gensio-3.0.0/0000775000175000017500000000000015061121735006542 5gensio-3.0.0/configure0000775000175000017500000313307615061121657010411 #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71 for gensio 3.0.0. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, # Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="as_nop=: if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else \$as_nop case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ) then : else \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) test x\"\$blah\" = xblah || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null then : as_have_required=yes else $as_nop as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$as_shell as_have_required=yes if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null then : break 2 fi fi done;; esac as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes fi fi if test "x$CONFIG_SHELL" != x then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno then : printf "%s\n" "$0: This script requires a shell more modern than all" printf "%s\n" "$0: the shells that I found on your system." if test ${ZSH_VERSION+y} ; then printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and minyard@acm.org $0: about your system, including any error possibly output $0: before this message. Then install a modern shell, or $0: manually run the script under such a shell if you do $0: have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='gensio' PACKAGE_TARNAME='gensio' PACKAGE_VERSION='3.0.0' PACKAGE_STRING='gensio 3.0.0' PACKAGE_BUGREPORT='minyard@acm.org' PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_STDIO_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_c_list= ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS BASE_LIBS OSH_LIBS EXTRA_CFLAGS AM_CFLAGS AM_CXXFLAGS HAVE_WINDOWS_OS_FALSE HAVE_WINDOWS_OS_TRUE HAVE_UNIX_OS_FALSE HAVE_UNIX_OS_TRUE GENSIO_PTY_HELPER HAVE_PTY HAVE_UNIX ENABLE_INTERNAL_TRACE_FALSE ENABLE_INTERNAL_TRACE_TRUE GTLSSH_KEYGENMAN GTLSSYNCMAN GTLSSHMAN GTLSSHDMAN GTLSSH_KEYGEN GTLSSYNC GTLSSH GTLSSHD HAVE_WORKING_PORT0 HAVE_PTSNAME_R PAMLIB GO_DIR GOPROG PYTHON_EXECUTABLE PYTHON_UNDEF_LIBS PYTHON_UNDEF_FLAG PYTHON_SWIG_FLAGS PYTHON_HAS_THREADS PYTHON_INSTALL_LIB_DIR PYTHON_INSTALL_DIR PYGENSIO_DIR PYTHON_DIR PYTHON_EXTRA_LDFLAGS PYTHON_EXTRA_LIBS PYTHON_PLATFORM_SITE_PKG PYTHON_SITE_PKG PYTHON_LIBS PYTHON_CPPFLAGS PYTHON_VERSION PYTHON SWIG_CPP_DIR SWIG_DIR SWIG_LIB SWIG DYNAMIC_AFSKMDM BUILTIN_AFSKMDM_FALSE BUILTIN_AFSKMDM_TRUE DYNAMIC_RATELIMIT BUILTIN_RATELIMIT_FALSE BUILTIN_RATELIMIT_TRUE DYNAMIC_SCRIPT BUILTIN_SCRIPT_FALSE BUILTIN_SCRIPT_TRUE DYNAMIC_KEEPOPEN BUILTIN_KEEPOPEN_FALSE BUILTIN_KEEPOPEN_TRUE DYNAMIC_XLT BUILTIN_XLT_FALSE BUILTIN_XLT_TRUE DYNAMIC_AX25 BUILTIN_AX25_FALSE BUILTIN_AX25_TRUE DYNAMIC_KISS BUILTIN_KISS_FALSE BUILTIN_KISS_TRUE DYNAMIC_PERF BUILTIN_PERF_FALSE BUILTIN_PERF_TRUE DYNAMIC_TRACE BUILTIN_TRACE_FALSE BUILTIN_TRACE_TRUE DYNAMIC_RELPKT BUILTIN_RELPKT_FALSE BUILTIN_RELPKT_TRUE DYNAMIC_MSGDELIM BUILTIN_MSGDELIM_FALSE BUILTIN_MSGDELIM_TRUE DYNAMIC_TELNET BUILTIN_TELNET_FALSE BUILTIN_TELNET_TRUE DYNAMIC_MUX BUILTIN_MUX_FALSE BUILTIN_MUX_TRUE DYNAMIC_CERTAUTH BUILTIN_CERTAUTH_FALSE BUILTIN_CERTAUTH_TRUE DYNAMIC_SSL BUILTIN_SSL_FALSE BUILTIN_SSL_TRUE HAVE_OPENSSL OPENSSL_LDFLAGS OPENSSL_LIBS OPENSSL_INCLUDES PKG_CONFIG DYNAMIC_CM108GPIO CM108GPIO_LIBS BUILTIN_CM108GPIO_FALSE BUILTIN_CM108GPIO_TRUE HAVE_UDEV DYNAMIC_SOUND BUILTIN_SOUND_FALSE BUILTIN_SOUND_TRUE SOUND_LIBS HAVE_PORTAUDIO HAVE_WIN32SOUND HAVE_ALSA BUILTIN_MDNS_LIBS DYNAMIC_MDNS BUILTIN_MDNS_FALSE BUILTIN_MDNS_TRUE HAVE_MDNS HAVE_MDNS_FALSE HAVE_MDNS_TRUE GMDNSMAN GMDNS MDNS_LIBS HAVE_WINMDNS HAVE_WINMDNS_FALSE HAVE_WINMDNS_TRUE HAVE_DNSSD HAVE_DNSSD_FALSE HAVE_DNSSD_TRUE HAVE_AVAHI HAVE_AVAHI_FALSE HAVE_AVAHI_TRUE DYNAMIC_IPMISOL BUILTIN_IPMISOL_FALSE BUILTIN_IPMISOL_TRUE OPENIPMI_LIBS OPENIPMI_CPPFLAGS HAVE_OPENIPMI HAVE_OPENIPMI_FALSE HAVE_OPENIPMI_TRUE DYNAMIC_FILE BUILTIN_FILE_FALSE BUILTIN_FILE_TRUE DYNAMIC_ECHO BUILTIN_ECHO_FALSE BUILTIN_ECHO_TRUE DYNAMIC_SERIALDEV BUILTIN_SERIALDEV_FALSE BUILTIN_SERIALDEV_TRUE DYNAMIC_CONACC BUILTIN_CONACC_FALSE BUILTIN_CONACC_TRUE DYNAMIC_DUMMY BUILTIN_DUMMY_FALSE BUILTIN_DUMMY_TRUE DYNAMIC_PTY BUILTIN_PTY_FALSE BUILTIN_PTY_TRUE DYNAMIC_STDIO BUILTIN_STDIO_FALSE BUILTIN_STDIO_TRUE DYNAMIC_SCTP BUILTIN_SCTP_FALSE BUILTIN_SCTP_TRUE HAVE_LIBSCTP DYNAMIC_DGRAM BUILTIN_DGRAM_FALSE BUILTIN_DGRAM_TRUE DYNAMIC_NET BUILTIN_NET_FALSE BUILTIN_NET_TRUE REGEX_LIB TCL_DIR TCL_LIB TCL_LIBS TCL_CFLAGS GLIB_DIR GLIB_LIB GLIB_LIBS GLIB_CFLAGS HAVE_GLIB_FALSE HAVE_GLIB_TRUE pkgprog CPLUSPLUS_DIR HAVE_CXX11 PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CXX PTHREAD_CC ax_pthread_config CPP INSTALL_DOC_FALSE INSTALL_DOC_TRUE moduleinstalldir LN_SF HAVE_UCRED HAVE_UCRED_FALSE HAVE_UCRED_TRUE USE_LOGIN_PROGRAM USE_LOGIN_PROGRAM_FALSE USE_LOGIN_PROGRAM_TRUE PYTHON_EXT_EXT_SET PYTHON_EXT_EXT USE_OPENPTY USE_OPENPTY_FALSE USE_OPENPTY_TRUE USE_GGL_INT USE_GGL_INT_FALSE USE_GGL_INT_TRUE CXXCPP LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB DLLTOOL OBJDUMP FILECMD LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED LIBTOOL ac_ct_AR AR GENSIO_LIB_VERSION am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V CSCOPE ETAGS CTAGS am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build gensio_VERSION_STRING gensio_VERSION_PATCH gensio_VERSION_MINOR gensio_VERSION_MAJOR target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_dependency_tracking enable_debug enable_shared enable_static with_pic enable_fast_install with_aix_soname with_gnu_ld with_sysroot enable_libtool_lock with_link_ssl_with_main with_moduleinstall with_uucp_locking with_flock_locking with_broken_pselect with_tcp_wrappers enable_doc enable_epoll_pwait with_pthreads with_cplusplus with_glib with_glibcflags with_gliblibs with_tcl with_tclcflags with_tcllibs with_all_gensios with_net with_dgram with_sctp with_stdio with_pty with_dummy with_conacc with_serialdev with_echo with_file with_openipmiflags with_openipmilibs with_openipmi with_ipmisol with_mdns with_avahi with_dnssd with_winmdns with_alsa with_winsound with_portaudio with_sound with_udev with_cm108gpio with_openssl with_ssl with_certauth with_mux with_telnet with_msgdelim with_relpkt with_trace with_perf with_kiss with_ax25 with_xlt with_keepopen with_script with_ratelimit with_afskmdm with_swig with_python with_pythoninstall with_pythoninstalllib with_pythoncflags with_pythonusepthreads with_go enable_internal_trace with_file_stdio ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CXX CXXFLAGS CCC LT_SYS_LIBRARY_PATH CXXCPP CPP PYTHON_VERSION' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures gensio 3.0.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/gensio] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of gensio 3.0.0:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-debug add -g option when building --disable-debug remove -g option when building --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --disable=doc disable building and installing docs --enable-epoll_pwait This platform supports epoll(7) with epoll_pwait(2) --enable-internal-trace[=yes|no] Enable internal tracing of states and data Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-link-ssl-with-main=yes|no Link libssl with the main program. See "Issues with openssl and signal masks" in the FAQ --with-moduleinstall=PATH Install gensio modules in the given location. --with-uucp-locking Enable UUCP-style locking with yes/no, or set the uucp lock directory otherwise --with-flock-locking Enable flock-style on serial port locking with yes/no --with-broken-pselect pselect is not atomic, work around it --with-tcp-wrappers Enable tcpwrappers support --with-pthreads=yes|no Use pthreads or not --with-cplusplus=yes|no Enable or disable C++ support. --with-glib=yes|no Look for glib. --with-glibcflags=flags Set the flags to compile with glib. --with-gliblibs=libs Set the libraries to link with glib. --with-tcl=yes|no Look for tcl. --with-tclcflags=flags Set the flags to compile with tcl. --with-tcllibs=libs Set the libraries to link with tcl. --with-all-gensios=yes|dynamic|no Default setting for all gensios --with-net=yes|dynamic|no Enable tcp/unix gensio --with-dgram=yes|dynamic|no Enable tcp/unix gensio --with-sctp=yes|no Look for sctp --with-sctp=yes|dynamic|no Enable sctp gensio --with-stdio=yes|dynamic|no Enable tcp/unix gensio --with-pty=yes|dynamic|no Enable tcp/unix gensio --with-dummy=yes|dynamic|no Enable tcp/unix gensio --with-conacc=yes|dynamic|no Enable tcp/unix gensio --with-serialdev=yes|dynamic|no Enable tcp/unix gensio --with-echo=yes|dynamic|no Enable tcp/unix gensio --with-file=yes|dynamic|no Enable tcp/unix gensio --with-openipmiflags=flags Set the flags to compile with OpenIPMI. --with-openipmilibs=libs Set the libraries to link with OpenIPMI. --with-openipmi=yes|dynamic|no Look for openipmi --with-ipmisol=yes|dynamic|no Enable ipmisol gensio --with-mdns[=yes|no] Look for mdns. --with-avahi[=yes|no] Look for avahi. --with-dnssd[=yes|no] Look for dnssd. --with-winmdns[=yes|no] Look for windows mdns. --with-mdns=yes|dynamic|no Enable mdns gensio --with-alsa=yes|no Look for alsa --with-winsound=yes|no Use windows sound --with-portaudio=yes|no Look for portaudio --with-sound=yes|dynamic|no Enable tcp/unix gensio --with-udev=yes|no Look for udev --with-cm108gpio=yes|dynamic|no Enable cm108 GPIO gensio --with-openssl[=yes|no|PATH] Look for OpenSSL, with optional root of the OpenSSL directory --with-ssl=yes|dynamic|no Enable ssl gensio --with-certauth=yes|dynamic|no Enable certauth gensio --with-mux=yes|dynamic|no Enable tcp/unix gensio --with-telnet=yes|dynamic|no Enable tcp/unix gensio --with-msgdelim=yes|dynamic|no Enable tcp/unix gensio --with-relpkt=yes|dynamic|no Enable tcp/unix gensio --with-trace=yes|dynamic|no Enable tcp/unix gensio --with-perf=yes|dynamic|no Enable tcp/unix gensio --with-kiss=yes|dynamic|no Enable tcp/unix gensio --with-ax25=yes|dynamic|no Enable tcp/unix gensio --with-xlt=yes|dynamic|no Enable tcp/unix gensio --with-keepopen=yes|dynamic|no Enable tcp/unix gensio --with-script=yes|dynamic|no Enable tcp/unix gensio --with-ratelimit=yes|dynamic|no Enable tcp/unix gensio --with-afskmdm=yes|dynamic|no Enable tcp/unix gensio --with-swig[=yes|no|PATH] Look for swig, with the optional path. --with-python[=yes|no|PATH] Look for python, with the optional path. --with-pythoninstall=PATH Install python modules in the given location. --with-pythoninstalllib=PATH Install python libraries in the given location. --with-pythoncflags=PATH Use the given flags when compiling python parts. --with-pythonusepthreads[=yes|no] Use threads with python. --with-go[=yes|no|PATH] Look for go, with the optional path. --with-file-stdio[=yes|no] Use stdio instead of unix files for the file gensio. Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CXX C++ compiler command CXXFLAGS C++ compiler flags LT_SYS_LIBRARY_PATH User-defined run-time library search path. CXXCPP C++ preprocessor CPP C preprocessor PYTHON_VERSION The installed Python version to use, for example '2.3'. This string will be appended to the Python interpreter canonical name. Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for configure.gnu first; this name is used for a wrapper for # Metaconfig's "Configure" on case-insensitive file systems. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF gensio configure 3.0.0 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. */ #include #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main (void) { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link # ac_fn_c_try_run LINENO # ---------------------- # Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that # executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: program exited with status $ac_status" >&5 printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_check_decl LINENO SYMBOL VAR INCLUDES EXTRA-OPTIONS FLAG-VAR # ------------------------------------------------------------------ # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR # accordingly. Pass EXTRA-OPTIONS to the compiler, using FLAG-VAR. ac_fn_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack as_decl_name=`echo $2|sed 's/ *(.*//'` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 printf %s "checking whether $as_decl_name is declared... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` eval ac_save_FLAGS=\$$6 as_fn_append $6 " $5" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { #ifndef $as_decl_name #ifdef __cplusplus (void) $as_decl_use; #else (void) $as_decl_name; #endif #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext eval $6=\$ac_save_FLAGS fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_check_decl # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- # Tries to find if the field MEMBER exists in type AGGR, after including # INCLUDES, setting cache variable VAR accordingly. ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 printf %s "checking for $2.$3... " >&6; } if eval test \${$4+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main (void) { static $2 ac_aggr; if (ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$4=yes" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main (void) { static $2 ac_aggr; if (sizeof ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$4=yes" else $as_nop eval "$4=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$4 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_member ac_configure_args_raw= for ac_arg do case $ac_arg in *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_configure_args_raw " '$ac_arg'" done case $ac_configure_args_raw in *$as_nl*) ac_safe_unquote= ;; *) ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. ac_unsafe_a="$ac_unsafe_z#~" ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; esac cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by gensio $as_me 3.0.0, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac printf "%s\n" "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Sanitize IFS. IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo printf "%s\n" "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && printf "%s\n" "$as_me: caught signal $ac_signal" printf "%s\n" "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi for ac_site_file in $ac_site_files do case $ac_site_file in #( */*) : ;; #( *) : ac_site_file=./$ac_site_file ;; esac if test -f "$ac_site_file" && test -r "$ac_site_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Test code for whether the C compiler supports C89 (global declarations) ac_c_conftest_c89_globals=' /* Does the compiler advertise C89 conformance? Do not test the value of __STDC__, because some compilers set it to 0 while being otherwise adequately conformant. */ #if !defined __STDC__ # error "Compiler does not advertise C89 conformance" #endif #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ struct buf { int x; }; struct buf * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not \xHH hex character constants. These do not provoke an error unfortunately, instead are silently treated as an "x". The following induces an error, until -std is added to get proper ANSI mode. Curiously \x00 != x always comes out true, for an array size at least. It is necessary to write \x00 == 0 to get something that is true only with -std. */ int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) '\''x'\'' int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), int, int);' # Test code for whether the C compiler supports C89 (body of main). ac_c_conftest_c89_main=' ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); ' # Test code for whether the C compiler supports C99 (global declarations) ac_c_conftest_c99_globals=' // Does the compiler advertise C99 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L # error "Compiler does not advertise C99 conformance" #endif #include extern int puts (const char *); extern int printf (const char *, ...); extern int dprintf (int, const char *, ...); extern void *malloc (size_t); // Check varargs macros. These examples are taken from C99 6.10.3.5. // dprintf is used instead of fprintf to avoid needing to declare // FILE and stderr. #define debug(...) dprintf (2, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK #error "your preprocessor is broken" #endif #if BIG_OK #else #error "your preprocessor is broken" #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) continue; return 0; } // Check varargs and va_copy. static bool test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str = ""; int number = 0; float fnumber = 0; while (*format) { switch (*format++) { case '\''s'\'': // string str = va_arg (args_copy, const char *); break; case '\''d'\'': // int number = va_arg (args_copy, int); break; case '\''f'\'': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); return *str && number && fnumber; } ' # Test code for whether the C compiler supports C99 (body of main). ac_c_conftest_c99_main=' // Check bool. _Bool success = false; success |= (argc != 0); // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[0] = argv[0][0]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' || dynamic_array[ni.number - 1] != 543); ' # Test code for whether the C compiler supports C11 (global declarations) ac_c_conftest_c11_globals=' // Does the compiler advertise C11 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L # error "Compiler does not advertise C11 conformance" #endif // Check _Alignas. char _Alignas (double) aligned_as_double; char _Alignas (0) no_special_alignment; extern char aligned_as_int; char _Alignas (0) _Alignas (int) aligned_as_int; // Check _Alignof. enum { int_alignment = _Alignof (int), int_array_alignment = _Alignof (int[100]), char_alignment = _Alignof (char) }; _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); // Check _Noreturn. int _Noreturn does_not_return (void) { for (;;) continue; } // Check _Static_assert. struct test_static_assert { int x; _Static_assert (sizeof (int) <= sizeof (long int), "_Static_assert does not work in struct"); long int y; }; // Check UTF-8 literals. #define u8 syntax error! char const utf8_literal[] = u8"happens to be ASCII" "another string"; // Check duplicate typedefs. typedef long *long_ptr; typedef long int *long_ptr; typedef long_ptr long_ptr; // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. struct anonymous { union { struct { int i; int j; }; struct { int k; long int l; } w; }; int m; } v1; ' # Test code for whether the C compiler supports C11 (body of main). ac_c_conftest_c11_main=' _Static_assert ((offsetof (struct anonymous, i) == offsetof (struct anonymous, w.k)), "Anonymous union alignment botch"); v1.i = 2; v1.w.k = 5; ok |= v1.i != 5; ' # Test code for whether the C compiler supports C11 (complete). ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} ${ac_c_conftest_c11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} ${ac_c_conftest_c11_main} return ok; } " # Test code for whether the C compiler supports C99 (complete). ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} return ok; } " # Test code for whether the C compiler supports C89 (complete). ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} return ok; } " # Test code for whether the C++ compiler supports C++98 (global declarations) ac_cxx_conftest_cxx98_globals=' // Does the compiler advertise C++98 conformance? #if !defined __cplusplus || __cplusplus < 199711L # error "Compiler does not advertise C++98 conformance" #endif // These inclusions are to reject old compilers that // lack the unsuffixed header files. #include #include // and are *not* freestanding headers in C++98. extern void assert (int); namespace std { extern int strcmp (const char *, const char *); } // Namespaces, exceptions, and templates were all added after "C++ 2.0". using std::exception; using std::strcmp; namespace { void test_exception_syntax() { try { throw "test"; } catch (const char *s) { // Extra parentheses suppress a warning when building autoconf itself, // due to lint rules shared with more typical C programs. assert (!(strcmp) (s, "test")); } } template struct test_template { T const val; explicit test_template(T t) : val(t) {} template T add(U u) { return static_cast(u) + val; } }; } // anonymous namespace ' # Test code for whether the C++ compiler supports C++98 (body of main) ac_cxx_conftest_cxx98_main=' assert (argc); assert (! argv[0]); { test_exception_syntax (); test_template tt (2.0); assert (tt.add (4) == 6.0); assert (true && !false); } ' # Test code for whether the C++ compiler supports C++11 (global declarations) ac_cxx_conftest_cxx11_globals=' // Does the compiler advertise C++ 2011 conformance? #if !defined __cplusplus || __cplusplus < 201103L # error "Compiler does not advertise C++11 conformance" #endif namespace cxx11test { constexpr int get_val() { return 20; } struct testinit { int i; double d; }; class delegate { public: delegate(int n) : n(n) {} delegate(): delegate(2354) {} virtual int getval() { return this->n; }; protected: int n; }; class overridden : public delegate { public: overridden(int n): delegate(n) {} virtual int getval() override final { return this->n * 2; } }; class nocopy { public: nocopy(int i): i(i) {} nocopy() = default; nocopy(const nocopy&) = delete; nocopy & operator=(const nocopy&) = delete; private: int i; }; // for testing lambda expressions template Ret eval(Fn f, Ret v) { return f(v); } // for testing variadic templates and trailing return types template auto sum(V first) -> V { return first; } template auto sum(V first, Args... rest) -> V { return first + sum(rest...); } } ' # Test code for whether the C++ compiler supports C++11 (body of main) ac_cxx_conftest_cxx11_main=' { // Test auto and decltype auto a1 = 6538; auto a2 = 48573953.4; auto a3 = "String literal"; int total = 0; for (auto i = a3; *i; ++i) { total += *i; } decltype(a2) a4 = 34895.034; } { // Test constexpr short sa[cxx11test::get_val()] = { 0 }; } { // Test initializer lists cxx11test::testinit il = { 4323, 435234.23544 }; } { // Test range-based for int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; for (auto &x : array) { x += 23; } } { // Test lambda expressions using cxx11test::eval; assert (eval ([](int x) { return x*2; }, 21) == 42); double d = 2.0; assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0); assert (d == 5.0); assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0); assert (d == 5.0); } { // Test use of variadic templates using cxx11test::sum; auto a = sum(1); auto b = sum(1, 2); auto c = sum(1.0, 2.0, 3.0); } { // Test constructor delegation cxx11test::delegate d1; cxx11test::delegate d2(); cxx11test::delegate d3(45); } { // Test override and final cxx11test::overridden o1(55464); } { // Test nullptr char *c = nullptr; } { // Test template brackets test_template<::test_template> v(test_template(12)); } { // Unicode literals char const *utf8 = u8"UTF-8 string \u2500"; char16_t const *utf16 = u"UTF-8 string \u2500"; char32_t const *utf32 = U"UTF-32 string \u2500"; } ' # Test code for whether the C compiler supports C++11 (complete). ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals} ${ac_cxx_conftest_cxx11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} ${ac_cxx_conftest_cxx11_main} return ok; } " # Test code for whether the C compiler supports C++98 (complete). ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} return ok; } " as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" # Auxiliary files required by this configure script. ac_aux_files="ltmain.sh ar-lib compile missing install-sh config.guess config.sub" # Locations in which to look for auxiliary files. ac_aux_dir_candidates="${srcdir}${PATH_SEPARATOR}${srcdir}/..${PATH_SEPARATOR}${srcdir}/../.." # Search for a directory containing all of the required auxiliary files, # $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. # If we don't find one directory that contains all the files we need, # we report the set of missing files from the *first* directory in # $ac_aux_dir_candidates and give up. ac_missing_aux_files="" ac_first_candidate=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in $ac_aux_dir_candidates do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 ac_aux_dir_found=yes ac_install_sh= for ac_aux in $ac_aux_files do # As a special case, if "install-sh" is required, that requirement # can be satisfied by any of "install-sh", "install.sh", or "shtool", # and $ac_install_sh is set appropriately for whichever one is found. if test x"$ac_aux" = x"install-sh" then if test -f "${as_dir}install-sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 ac_install_sh="${as_dir}install-sh -c" elif test -f "${as_dir}install.sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 ac_install_sh="${as_dir}install.sh -c" elif test -f "${as_dir}shtool"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 ac_install_sh="${as_dir}shtool install -c" else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} install-sh" else break fi fi else if test -f "${as_dir}${ac_aux}"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" else break fi fi fi done if test "$ac_aux_dir_found" = yes; then ac_aux_dir="$as_dir" break fi ac_first_candidate=false as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. if test -f "${ac_aux_dir}config.guess"; then ac_config_guess="$SHELL ${ac_aux_dir}config.guess" fi if test -f "${ac_aux_dir}config.sub"; then ac_config_sub="$SHELL ${ac_aux_dir}config.sub" fi if test -f "$ac_aux_dir/configure"; then ac_configure="$SHELL ${ac_aux_dir}configure" fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu gensio_VERSION_MAJOR=3 gensio_VERSION_MINOR=0 gensio_VERSION_PATCH=0 gensio_VERSION_STRING=${PACKAGE_VERSION} # Make sure we can run config.sub. $SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 printf %s "checking build system type... " >&6; } if test ${ac_cv_build+y} then : printf %s "(cached) " >&6 else $as_nop ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 printf "%s\n" "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 printf %s "checking host system type... " >&6; } if test ${ac_cv_host+y} then : printf %s "(cached) " >&6 else $as_nop if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 printf "%s\n" "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 printf %s "checking target system type... " >&6; } if test ${ac_cv_target+y} then : printf %s "(cached) " >&6 else $as_nop if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "${ac_aux_dir}config.sub" $target_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $target_alias failed" "$LINENO" 5 fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 printf "%s\n" "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- am__api_version='1.16' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 printf %s "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test ${ac_cv_path_install+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac # Account for fact that we put trailing slashes in our PATH walk. case $as_dir in #(( ./ | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test ${ac_cv_path_install+y}; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 printf "%s\n" "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 printf %s "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 printf "%s\n" "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 printf %s "checking for a race-free mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if test ${ac_cv_path_mkdir+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir ('*'coreutils) '* | \ 'BusyBox '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test ${ac_cv_path_mkdir+y}; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 printf "%s\n" "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AWK+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 printf "%s\n" "$AWK" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AWK" && break done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : printf %s "(cached) " >&6 else $as_nop cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } SET_MAKE= else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test ${enable_silent_rules+y} then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 printf %s "checking whether $am_make supports nested variables... " >&6; } if test ${am_cv_make_support_nested_variables+y} then : printf %s "(cached) " >&6 else $as_nop if printf "%s\n" 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='gensio' VERSION='3.0.0' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h printf "%s\n" "#define VERSION \"$VERSION\"" >>confdefs.h # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # Variables for tags utilities; see am/tags.am if test -z "$CTAGS"; then CTAGS=ctags fi if test -z "$ETAGS"; then ETAGS=etags fi if test -z "$CSCOPE"; then CSCOPE=cscope fi # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi ac_config_headers="$ac_config_headers config.h" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. set dummy ${ac_tool_prefix}clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "clang", so it can be a program name with args. set dummy clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 printf %s "checking whether the C compiler works... " >&6; } ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else $as_nop ac_file='' fi if test -z "$ac_file" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 printf %s "checking for C compiler default output file name... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 printf "%s\n" "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 printf %s "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 printf "%s\n" "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 printf %s "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 printf %s "checking whether $CC understands -c and -o together... " >&6; } if test ${am_cv_prog_cc_c_o+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 printf "%s\n" "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; } cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } case $?:`cat confinc.out 2>/dev/null` in #( '0:this is the am__doit target') : case $s in #( BSD) : am__include='.include' am__quote='"' ;; #( *) : am__include='include' am__quote='' ;; esac ;; #( *) : ;; esac if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 printf "%s\n" "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test ${enable_dependency_tracking+y} then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CC_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 printf "%s\n" "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CXX+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 printf "%s\n" "$CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CXX+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 printf "%s\n" "$ac_ct_CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5 printf %s "checking whether the compiler supports GNU C++... " >&6; } if test ${ac_cv_cxx_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+y} ac_save_CXXFLAGS=$CXXFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 printf %s "checking whether $CXX accepts -g... " >&6; } if test ${ac_cv_prog_cxx_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_g=yes else $as_nop CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : else $as_nop ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 printf "%s\n" "$ac_cv_prog_cxx_g" >&6; } if test $ac_test_CXXFLAGS; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_prog_cxx_stdcxx=no if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5 printf %s "checking for $CXX option to enable C++11 features... " >&6; } if test ${ac_cv_prog_cxx_cxx11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_cxx11=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx11_program _ACEOF for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx11" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx11" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 ac_prog_cxx_stdcxx=cxx11 fi fi if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5 printf %s "checking for $CXX option to enable C++98 features... " >&6; } if test ${ac_cv_prog_cxx_cxx98+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_cxx98=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx98_program _ACEOF for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx98=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx98" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx98" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx98" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx98" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98 ac_prog_cxx_stdcxx=cxx98 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CXX_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 printf "%s\n" "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi # Per discussions with the Debian maintainer, it's best for # maintainers to have all the soname libary versions be the same if # they come from a single source. So here it is. GENSIO_LIB_VERSION=14:0:0 # Check whether --enable-debug was given. if test ${enable_debug+y} then : enableval=$enable_debug; fi if test -z ${enable_debug}; then add_mg=yes else add_mg=${enable_debug} fi # Add or remove -g as necessary. This is message because we have to match # -g at the beginning, end, in the middle, or by itself in the CFLAGS string. # Maybe there is a better way to do this? # Space and tab ST='[ ]' if test "${add_mg}" = yes; then if ! echo "$CFLAGS" | grep -e "^-g${ST}" -e "${ST}-g$" -e "${ST}-g${ST}" -e "^-g$" ; then CFLAGS="$CFLAGS -g" fi else CFLAGS=`echo $CFLAGS | sed -e "s/^-g${ST}//" -e "s/${ST}-g$//" -e "s/${ST}-g${ST}/ /g" -e "s/^-g$//"` fi if test -n "$ac_tool_prefix"; then for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AR+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 printf "%s\n" "$AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_AR+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 printf "%s\n" "$ac_ct_AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 printf %s "checking the archiver ($AR) interface... " >&6; } if test ${am_cv_ar_interface+y} then : printf %s "(cached) " >&6 else $as_nop ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am_cv_ar_interface=ar cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int some_variable = 0; _ACEOF if ac_fn_c_try_compile "$LINENO" then : am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 printf "%s\n" "$am_cv_ar_interface" >&6; } case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) as_fn_error $? "could not determine $AR interface" "$LINENO" 5 ;; esac # Per discussion at: # https://lists.gnu.org/archive/html/libtool/2022-09/msg00000.html # This enabled RUNPATH over RPATH. libtool will not set # LD_LIBRARY_PATH if RPATH is used, but the code uses LD_LIBRARY_PATH # as a way to find module object files. So this is a hack until a # workaround is available. OLD_LDFLAGS="$LDFLAGS" if uname -a | grep '^Linux' >/dev/null 2>/dev/null; then LDFLAGS="$LDFLAGS -Wl,--enable-new-dtags" fi case `pwd` in *\ * | *\ *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.7' macro_revision='2.4.7' ltmain=$ac_aux_dir/ltmain.sh # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 printf %s "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case $ECHO in printf*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5 printf "%s\n" "printf" >&6; } ;; print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 printf "%s\n" "print -r" >&6; } ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5 printf "%s\n" "cat" >&6; } ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 printf %s "checking for a sed that does not truncate output... " >&6; } if test ${ac_cv_path_SED+y} then : printf %s "(cached) " >&6 else $as_nop ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in sed gsed do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 printf "%s\n" "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 printf %s "checking for grep that handles long lines and -e... " >&6; } if test ${ac_cv_path_GREP+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in grep ggrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 printf "%s\n" "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 printf %s "checking for egrep... " >&6; } if test ${ac_cv_path_EGREP+y} then : printf %s "(cached) " >&6 else $as_nop if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in egrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 printf "%s\n" "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 printf %s "checking for fgrep... " >&6; } if test ${ac_cv_path_FGREP+y} then : printf %s "(cached) " >&6 else $as_nop if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in fgrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 printf "%s\n" "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test ${with_gnu_ld+y} then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else $as_nop with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 printf %s "checking for GNU ld... " >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 printf %s "checking for non-GNU ld... " >&6; } fi if test ${lt_cv_path_LD+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 printf "%s\n" "$LD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 printf %s "checking if the linker ($LD) is GNU ld... " >&6; } if test ${lt_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 else $as_nop # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 printf %s "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if test ${lt_cv_path_NM+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 printf "%s\n" "$lt_cv_path_NM" >&6; } if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DUMPBIN+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 printf "%s\n" "$DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DUMPBIN+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 printf "%s\n" "$ac_ct_DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 printf %s "checking the name lister ($NM) interface... " >&6; } if test ${lt_cv_nm_interface+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 printf "%s\n" "$lt_cv_nm_interface" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 printf %s "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 printf "%s\n" "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 printf %s "checking the maximum length of command line arguments... " >&6; } if test ${lt_cv_sys_max_cmd_len+y} then : printf %s "(cached) " >&6 else $as_nop i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n "$lt_cv_sys_max_cmd_len"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 printf "%s\n" "$lt_cv_sys_max_cmd_len" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 printf "%s\n" "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 printf %s "checking how to convert $build file names to $host format... " >&6; } if test ${lt_cv_to_host_file_cmd+y} then : printf %s "(cached) " >&6 else $as_nop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 printf "%s\n" "$lt_cv_to_host_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 printf %s "checking how to convert $build file names to toolchain format... " >&6; } if test ${lt_cv_to_tool_file_cmd+y} then : printf %s "(cached) " >&6 else $as_nop #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 printf "%s\n" "$lt_cv_to_tool_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 printf %s "checking for $LD option to reload object files... " >&6; } if test ${lt_cv_ld_reload_flag+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_reload_flag='-r' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 printf "%s\n" "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) if test yes = "$GCC"; then reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}file", so it can be a program name with args. set dummy ${ac_tool_prefix}file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_FILECMD+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$FILECMD"; then ac_cv_prog_FILECMD="$FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_FILECMD="${ac_tool_prefix}file" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi FILECMD=$ac_cv_prog_FILECMD if test -n "$FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FILECMD" >&5 printf "%s\n" "$FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_FILECMD"; then ac_ct_FILECMD=$FILECMD # Extract the first word of "file", so it can be a program name with args. set dummy file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_FILECMD+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_FILECMD"; then ac_cv_prog_ac_ct_FILECMD="$ac_ct_FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_FILECMD="file" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_FILECMD=$ac_cv_prog_ac_ct_FILECMD if test -n "$ac_ct_FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FILECMD" >&5 printf "%s\n" "$ac_ct_FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_FILECMD" = x; then FILECMD=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac FILECMD=$ac_ct_FILECMD fi else FILECMD="$ac_cv_prog_FILECMD" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 printf "%s\n" "$OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 printf "%s\n" "$ac_ct_OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 printf %s "checking how to recognize dependent libraries... " >&6; } if test ${lt_cv_deplibs_check_method+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 printf "%s\n" "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 printf "%s\n" "$DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 printf "%s\n" "$ac_ct_DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 printf %s "checking how to associate runtime and link libraries... " >&6; } if test ${lt_cv_sharedlib_from_linklib_cmd+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 printf "%s\n" "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AR+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 printf "%s\n" "$AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_AR+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 printf "%s\n" "$ac_ct_AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have # higher priority because thats what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} lt_ar_flags=$AR_FLAGS # Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override # by AR_FLAGS because that was never working and AR_FLAGS is about to die. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 printf %s "checking for archiver @FILE support... " >&6; } if test ${lt_cv_ar_at_file+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 printf "%s\n" "$lt_cv_ar_at_file" >&6; } if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 printf "%s\n" "$RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 printf "%s\n" "$ac_ct_RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 printf %s "checking command to parse $NM output from $compiler object... " >&6; } if test ${lt_cv_sys_global_symbol_pipe+y} then : printf %s "(cached) " >&6 else $as_nop # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: failed" >&5 printf "%s\n" "failed" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ok" >&5 printf "%s\n" "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 printf %s "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test ${with_sysroot+y} then : withval=$with_sysroot; else $as_nop with_sysroot=no fi lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 printf "%s\n" "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 printf "%s\n" "${lt_sysroot:-no}" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 printf %s "checking for a working dd... " >&6; } if test ${ac_cv_path_lt_DD+y} then : printf %s "(cached) " >&6 else $as_nop printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then ac_path_lt_DD_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in dd do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_lt_DD="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_lt_DD" || continue if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi $ac_path_lt_DD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_lt_DD"; then : fi else ac_cv_path_lt_DD=$lt_DD fi rm -f conftest.i conftest2.i conftest.out fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 printf "%s\n" "$ac_cv_path_lt_DD" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 printf %s "checking how to truncate binary pipes... " >&6; } if test ${lt_cv_truncate_bin+y} then : printf %s "(cached) " >&6 else $as_nop printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 printf "%s\n" "$lt_cv_truncate_bin" >&6; } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # Check whether --enable-libtool-lock was given. if test ${enable_libtool_lock+y} then : enableval=$enable_libtool_lock; fi test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 printf %s "checking whether the C compiler needs -belf... " >&6; } if test ${lt_cv_cc_needs_belf+y} then : printf %s "(cached) " >&6 else $as_nop ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_cc_needs_belf=yes else $as_nop lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 printf "%s\n" "$lt_cv_cc_needs_belf" >&6; } if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 printf "%s\n" "$MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 printf "%s\n" "$ac_ct_MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if test ${lt_cv_path_mainfest_tool+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 printf "%s\n" "$lt_cv_path_mainfest_tool" >&6; } if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DSYMUTIL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 printf "%s\n" "$DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DSYMUTIL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 printf "%s\n" "$ac_ct_DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_NMEDIT+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 printf "%s\n" "$NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_NMEDIT+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 printf "%s\n" "$ac_ct_NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_LIPO+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 printf "%s\n" "$LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_LIPO+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 printf "%s\n" "$ac_ct_LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 printf "%s\n" "$OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 printf "%s\n" "$ac_ct_OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL64+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 printf "%s\n" "$OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL64+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 printf "%s\n" "$ac_ct_OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 printf %s "checking for -single_module linker flag... " >&6; } if test ${lt_cv_apple_cc_single_mod+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 printf %s "checking for -exported_symbols_list linker flag... " >&6; } if test ${lt_cv_ld_exported_symbols_list+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_ld_exported_symbols_list=yes else $as_nop lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 printf "%s\n" "$lt_cv_ld_exported_symbols_list" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 printf %s "checking for -force_load linker flag... " >&6; } if test ${lt_cv_ld_force_load+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR $AR_FLAGS libconftest.a conftest.o" >&5 $AR $AR_FLAGS libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 printf "%s\n" "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) case $MACOSX_DEPLOYMENT_TARGET,$host in 10.[012],*|,*powerpc*-darwin[5-8]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; *) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } ac_header= ac_cache= for ac_item in $ac_header_c_list do if test $ac_cache; then ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then printf "%s\n" "#define $ac_item 1" >> confdefs.h fi ac_header= ac_cache= elif test $ac_header; then ac_cache=$ac_item else ac_header=$ac_item fi done if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes then : printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes then : printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h fi func_stripname_cnf () { case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; esac } # func_stripname_cnf # Set options enable_dlopen=yes enable_win32_dll=no # Check whether --enable-shared was given. if test ${enable_shared+y} then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_shared=yes fi # Check whether --enable-static was given. if test ${enable_static+y} then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_static=yes fi # Check whether --with-pic was given. if test ${with_pic+y} then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop pic_mode=default fi # Check whether --enable-fast-install was given. if test ${enable_fast_install+y} then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_fast_install=yes fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 printf %s "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test ${with_aix_soname+y} then : withval=$with_aix_soname; case $withval in aix|svr4|both) ;; *) as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 ;; esac lt_cv_with_aix_soname=$with_aix_soname else $as_nop if test ${lt_cv_with_aix_soname+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_with_aix_soname=aix fi with_aix_soname=$lt_cv_with_aix_soname fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 printf "%s\n" "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 printf %s "checking for objdir... " >&6; } if test ${lt_cv_objdir+y} then : printf %s "(cached) " >&6 else $as_nop rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 printf "%s\n" "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir printf "%s\n" "#define LT_OBJDIR \"$lt_cv_objdir/\"" >>confdefs.h case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC and # ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o func_cc_basename $compiler cc_basename=$func_cc_basename_result # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 printf %s "checking for ${ac_tool_prefix}file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else $as_nop case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/${ac_tool_prefix}file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for file" >&5 printf %s "checking for file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else $as_nop case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 printf %s "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if test ${lt_cv_prog_compiler_rtti_exceptions+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 printf "%s\n" "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi lt_prog_compiler_pic='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # flang / f18. f95 an alias for gfortran or flang on Debian flang* | f18* | f95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 printf %s "checking for $compiler option to produce PIC... " >&6; } if test ${lt_cv_prog_compiler_pic+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if test ${lt_cv_prog_compiler_pic_works+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if test ${lt_cv_prog_compiler_static_works+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_static_works=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 printf %s "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 printf "%s\n" "$hard_links" >&6; } if test no = "$hard_links"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct=no hardcode_direct_absolute=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' $wl-bernotok' allow_undefined_flag=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl* | icl*) # Native MSVC or ICC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC and ICC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly* | midnightbsd*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test yes = "$GCC"; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 printf %s "checking if $CC understands -b... " >&6; } if test ${lt_cv_prog_compiler__b+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler__b=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 printf "%s\n" "$lt_cv_prog_compiler__b" >&6; } if test yes = "$lt_cv_prog_compiler__b"; then archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 printf %s "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if test ${lt_cv_irix_exported_symbol+y} then : printf %s "(cached) " >&6 else $as_nop save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_irix_exported_symbol=yes else $as_nop lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi link_all_deplibs=no else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' else archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; osf3*) if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then wlarc='$wl' archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='$wl-z,text' allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 printf "%s\n" "$ld_shlibs" >&6; } test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 printf %s "checking whether -lc should be explicitly linked in... " >&6; } if test ${lt_cv_archive_cmds_need_lc+y} then : printf %s "(cached) " >&6 else $as_nop $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 printf "%s\n" "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 printf %s "checking dynamic linker characteristics... " >&6; } if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if test ${lt_cv_shlibpath_overrides_runpath+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 printf "%s\n" "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 printf %s "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 printf "%s\n" "$hardcode_action" >&6; } if test relink = "$hardcode_action" || test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else $as_nop ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else $as_nop lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes then : lt_cv_dlopen=shl_load else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 printf %s "checking for shl_load in -ldld... " >&6; } if test ${ac_cv_lib_dld_shl_load+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char shl_load (); int main (void) { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_shl_load=yes else $as_nop ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes then : lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else $as_nop ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes then : lt_cv_dlopen=dlopen else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else $as_nop ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 printf %s "checking for dlopen in -lsvld... " >&6; } if test ${ac_cv_lib_svld_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_svld_dlopen=yes else $as_nop ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 printf "%s\n" "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 printf %s "checking for dld_link in -ldld... " >&6; } if test ${ac_cv_lib_dld_dld_link+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dld_link (); int main (void) { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_dld_link=yes else $as_nop ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 printf "%s\n" "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes then : lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi fi fi fi fi fi ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 printf %s "checking whether a program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self+y} then : printf %s "(cached) " >&6 else $as_nop if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 printf "%s\n" "$lt_cv_dlopen_self" >&6; } if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 printf %s "checking whether a statically linked program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self_static+y} then : printf %s "(cached) " >&6 else $as_nop if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 printf "%s\n" "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 printf %s "checking whether stripping libraries is possible... " >&6; } if test -z "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } else if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else case $host_os in darwin*) # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } ;; freebsd*) if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ;; esac fi fi # Report what library types will actually be built { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 printf %s "checking if libtool supports shared libraries... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 printf "%s\n" "$can_build_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 printf %s "checking whether to build shared libraries... " >&6; } test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 printf "%s\n" "$enable_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 printf %s "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 printf "%s\n" "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC=$lt_save_CC if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 printf %s "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if test ${ac_cv_prog_CXXCPP+y} then : printf %s "(cached) " >&6 else $as_nop # Double quotes because $CXX needs to be expanded for CXXCPP in "$CXX -E" cpp /lib/cpp do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 printf "%s\n" "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu else _lt_caught_CXX_error=yes fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu archive_cmds_need_lc_CXX=no allow_undefined_flag_CXX= always_export_symbols_CXX=no archive_expsym_cmds_CXX= compiler_needs_object_CXX=no export_dynamic_flag_spec_CXX= hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no hardcode_libdir_flag_spec_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no inherit_rpath_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= link_all_deplibs_CXX=unknown old_archive_cmds_CXX=$old_archive_cmds reload_flag_CXX=$reload_flag reload_cmds_CXX=$reload_cmds no_undefined_flag_CXX= whole_archive_flag_spec_CXX= enable_shared_with_static_runtimes_CXX=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o objext_CXX=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC compiler_CXX=$CC func_cc_basename $compiler cc_basename=$func_cc_basename_result if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration # Check whether --with-gnu-ld was given. if test ${with_gnu_ld+y} then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else $as_nop with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 printf %s "checking for GNU ld... " >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 printf %s "checking for non-GNU ld... " >&6; } fi if test ${lt_cv_path_LD+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 printf "%s\n" "$LD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 printf %s "checking if the linker ($LD) is GNU ld... " >&6; } if test ${lt_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 else $as_nop # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec_CXX= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ld_shlibs_CXX=yes case $host_os in aix3*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_CXX='' hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes file_list_spec_CXX='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct_CXX=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_CXX=yes hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_libdir_separator_CXX= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec_CXX='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. always_export_symbols_CXX=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. no_undefined_flag_CXX='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath__CXX+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath__CXX+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' $wl-bernotok' allow_undefined_flag_CXX=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' fi archive_cmds_need_lc_CXX=yes archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs_CXX=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl* | ,icl* | no,icl*) # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_CXX=' ' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=yes file_list_spec_CXX='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' enable_shared_with_static_runtimes_CXX=yes # Don't use ranlib old_postinstall_cmds_CXX='chmod 644 $oldlib' postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_CXX='-L$libdir' export_dynamic_flag_spec_CXX='$wl--export-all-symbols' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec_CXX='' fi link_all_deplibs_CXX=yes allow_undefined_flag_CXX=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds_CXX="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds_CXX="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" if test yes != "$lt_cv_apple_cc_single_mod"; then archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" archive_expsym_cmds_CXX="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi else ld_shlibs_CXX=no fi ;; os2*) hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_minus_L_CXX=yes allow_undefined_flag_CXX=unsupported shrext_cmds=.dll archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes_CXX=yes file_list_spec_CXX='@' ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF ld_shlibs_CXX=no ;; freebsd-elf*) archive_cmds_need_lc_CXX=no ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; haiku*) archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs_CXX=yes ;; hpux9*) hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='$wl-E' hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: case $host_cpu in hppa*64*|ia64*) ;; *) export_dynamic_flag_spec_CXX='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; *) hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; interix[3-9]*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_CXX='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi link_all_deplibs_CXX=yes ;; esac hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: inherit_rpath_CXX=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac archive_cmds_need_lc_CXX=no hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [1-5].* | *pgcpp\ [1-5].*) prelink_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' old_archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' hardcode_libdir_flag_spec_CXX='-R$libdir' whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object_CXX=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; m88k*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) ld_shlibs_CXX=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no hardcode_direct_absolute_CXX=yes archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' export_dynamic_flag_spec_CXX='$wl-E' whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else ld_shlibs_CXX=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) case $host in osf3*) allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' ;; *) allow_undefined_flag_CXX=' -expect_unresolved \*' archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' ;; esac hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' case $host in osf3*) archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' ;; esac link_all_deplibs_CXX=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then no_undefined_flag_CXX=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' fi hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag_CXX='$wl-z,text' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_CXX='$wl-z,text' allow_undefined_flag_CXX='$wl-z,nodefs' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes export_dynamic_flag_spec_CXX='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ '"$old_archive_cmds_CXX" reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ '"$reload_cmds_CXX" ;; *) archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 printf "%s\n" "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && can_build_shared=no GCC_CXX=$GXX LD_CXX=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... # Dependencies to place before and after the object being linked: predep_objects_CXX= postdep_objects_CXX= predeps_CXX= postdeps_CXX= compiler_lib_search_path_CXX= cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$compiler_lib_search_path_CXX"; then compiler_lib_search_path_CXX=$prev$p else compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$postdeps_CXX"; then postdeps_CXX=$prev$p else postdeps_CXX="${postdeps_CXX} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$predep_objects_CXX"; then predep_objects_CXX=$p else predep_objects_CXX="$predep_objects_CXX $p" fi else if test -z "$postdep_objects_CXX"; then postdep_objects_CXX=$p else postdep_objects_CXX="$postdep_objects_CXX $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling CXX test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken case $host_os in interix[3-9]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. predep_objects_CXX= postdep_objects_CXX= postdeps_CXX= ;; esac case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac compiler_lib_search_dirs_CXX= if test -n "${compiler_lib_search_path_CXX}"; then compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi lt_prog_compiler_wl_CXX= lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi lt_prog_compiler_pic_CXX='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic_CXX='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic_CXX='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static_CXX='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_CXX='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static_CXX= ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac else case $host_os in aix[4-9]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' else lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; dgux*) case $cc_basename in ec++*) lt_prog_compiler_pic_CXX='-KPIC' ;; ghcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_CXX='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler lt_prog_compiler_wl_CXX='--backend -Wl,' lt_prog_compiler_pic_CXX='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fPIC' lt_prog_compiler_static_CXX='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fpic' lt_prog_compiler_static_CXX='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) # IBM XL 8.0, 9.0 on PPC and BlueGene lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-qpic' lt_prog_compiler_static_CXX='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) lt_prog_compiler_pic_CXX='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) lt_prog_compiler_wl_CXX='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 lt_prog_compiler_pic_CXX='-pic' ;; cxx*) # Digital/Compaq C++ lt_prog_compiler_wl_CXX='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x lt_prog_compiler_pic_CXX='-pic' lt_prog_compiler_static_CXX='-Bstatic' ;; lcc*) # Lucid lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 lt_prog_compiler_pic_CXX='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) lt_prog_compiler_can_build_shared_CXX=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= ;; *) lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 printf %s "checking for $compiler option to produce PIC... " >&6; } if test ${lt_cv_prog_compiler_pic_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_CXX" >&6; } lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } if test ${lt_cv_prog_compiler_pic_works_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works_CXX=yes fi fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; esac else lt_prog_compiler_pic_CXX= lt_prog_compiler_can_build_shared_CXX=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if test ${lt_cv_prog_compiler_static_works_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_static_works_CXX=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works_CXX=yes fi else lt_cv_prog_compiler_static_works_CXX=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_static_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then : else lt_prog_compiler_static_CXX= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 printf %s "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 printf "%s\n" "$hard_links" >&6; } if test no = "$hard_links"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' case $host_os in aix[4-9]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl* | icl*) exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' ;; esac ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs_CXX=no ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 printf "%s\n" "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && can_build_shared=no with_gnu_ld_CXX=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_CXX" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_CXX=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds_CXX in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 printf %s "checking whether -lc should be explicitly linked in... " >&6; } if test ${lt_cv_archive_cmds_need_lc_CXX+y} then : printf %s "(cached) " >&6 else $as_nop $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_CXX allow_undefined_flag_CXX= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc_CXX=no else lt_cv_archive_cmds_need_lc_CXX=yes fi allow_undefined_flag_CXX=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 printf "%s\n" "$lt_cv_archive_cmds_need_lc_CXX" >&6; } archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX ;; esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 printf %s "checking dynamic linker characteristics... " >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec_CXX='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if test ${lt_cv_shlibpath_overrides_runpath+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 printf "%s\n" "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 printf %s "checking how to hardcode library paths into programs... " >&6; } hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || test -n "$runpath_var_CXX" || test yes = "$hardcode_automatic_CXX"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct_CXX" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && test no != "$hardcode_minus_L_CXX"; then # Linking always hardcodes the temporary library directory. hardcode_action_CXX=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_CXX=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_CXX=unsupported fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 printf "%s\n" "$hardcode_action_CXX" >&6; } if test relink = "$hardcode_action_CXX" || test yes = "$inherit_rpath_CXX"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_commands="$ac_config_commands libtool" # Only expand once: LDFLAGS="$OLD_LDFLAGS" # defaults OSH_LIBS= BASE_LIBS= AM_CFLAGS= AM_CXXFLAGS= EXTRA_CFLAGS= uucp_locking_flag=yes UUCP_LOCK_DIR=/var/spool/lock flock_locking_flag=yes USE_FILE_STDIO=0 broken_pselect=no system_type=unix # macos defines git_t, but getgrouplist() takes int* USE_GGL_INT=0 # posix_openpt doesn't work like what we want on macos. You have to # open the client before you can set the file descriptor non-blocking, # which is a fairly annoying thing. See # https://developer.apple.com/forums/thread/734230 for details. USE_OPENPTY=0 # openssl calls sigprocmask() in it's startup code for ARM and some # other processors. On at least macos, this affects all threads, not # just the calling thread. So if you load it while threads are # running, it will modify the thread masks of all running threads, and # screw things up for waking using signals. Check for this on # platforms that need it, and link -lssl to the main program to avoid # the issue. See # https://github.com/openssl/openssl/issues/21541 link_ssl_with_main=no # Python extension modules end in .pyd on Windows, so we need to override # the extension from .dll to that. We can ignore it on everything else. PYTHON_EXT_EXT=.so PYTHON_EXT_EXT_SET= # Windows requires that -no-undefined be set, but homebrew on MacOS requires # that -undefined be set. Sigh. PYTHON_UNDEF_FLAG=-undefined # Do we use the login program to login with gtlsshd, or do we directly # run the shell? On MacOS you need to use login for things to work right. USE_LOGIN_PROGRAM=0 # Do we have unix credentials on unix sockets? HAVE_UCRED=0 HAVE_WIN32SOUND=0 DISABLE_GO=no DISABLE_GTLSSHD=no case $target_os in msys) # MSYS presents some challenges. We hack things to # get them to compile, but not much works well. See # the README file for details. OSH_LIBS="$OSH_LIBS -ldl" uucp_locking_flag=no flock_locking_flag=no PYTHON_UNDEF_FLAG=-no-undefined HAVE_WIN32SOUND=1 DISABLE_GO=yes DISABLE_GTLSSHD=yes ;; mingw*) OSH_LIBS="$OSH_LIBS -lws2_32 -liphlpapi -lgdi32 -lbcrypt" OSH_LIBS="$OSH_LIBS -lsecur32 -luserenv -lwtsapi32" OSH_LIBS="$OSH_LIBS -lole32" uucp_locking_flag=no flock_locking_flag=no system_type=windows USE_FILE_STDIO=1 PYTHON_EXT_EXT=".pyd" PYTHON_EXT_EXT_SET="-shrext .pyd" PYTHON_UNDEF_FLAG=-no-undefined HAVE_WIN32SOUND=1 ;; cygwin*) OSH_LIBS="$OSH_LIBS -ldl" uucp_locking_flag=no flock_locking_flag=no ;; linux*) OSH_LIBS="$OSH_LIBS -ldl" UUCP_LOCK_DIR=/var/lock HAVE_UCRED=1 ;; darwin*) # macos OSH_LIBS="$OSH_LIBS -ldl" link_ssl_with_main=check uucp_locking_flag=no USE_GGL_INT=1 USE_OPENPTY=1 USE_LOGIN_PROGRAM=1 HAVE_UCRED=1 broken_pselect=yes ;; freebsd*) OSH_LIBS="$OSH_LIBS -ldl" broken_pselect=yes HAVE_UCRED=1 ;; *bsd* | *BSD*) OSH_LIBS="$OSH_LIBS -ldl" broken_pselect=yes ;; *) # Defaults, maybe it will work OSH_LIBS="$OSH_LIBS -ldl" ;; esac printf "%s\n" "#define USE_GGL_INT $USE_GGL_INT" >>confdefs.h if test ${USE_GGL_INT} = 1; then USE_GGL_INT_TRUE= USE_GGL_INT_FALSE='#' else USE_GGL_INT_TRUE='#' USE_GGL_INT_FALSE= fi printf "%s\n" "#define USE_OPENPTY $USE_OPENPTY" >>confdefs.h if test ${USE_OPENPTY} = 1; then USE_OPENPTY_TRUE= USE_OPENPTY_FALSE='#' else USE_OPENPTY_TRUE='#' USE_OPENPTY_FALSE= fi printf "%s\n" "#define USE_LOGIN_PROGRAM $USE_LOGIN_PROGRAM" >>confdefs.h if test ${USE_LOGIN_PROGRAM} = 1; then USE_LOGIN_PROGRAM_TRUE= USE_LOGIN_PROGRAM_FALSE='#' else USE_LOGIN_PROGRAM_TRUE='#' USE_LOGIN_PROGRAM_FALSE= fi printf "%s\n" "#define HAVE_UCRED $HAVE_UCRED" >>confdefs.h if test ${HAVE_UCRED} = 1; then HAVE_UCRED_TRUE= HAVE_UCRED_FALSE='#' else HAVE_UCRED_TRUE='#' HAVE_UCRED_FALSE= fi # Check whether --with-link-ssl-with-main was given. if test ${with_link_ssl_with_main+y} then : withval=$with_link_ssl_with_main; link_ssl_with_main="$withval" fi pkgconfig_update_info() { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking \"CPPFLAGS for $1\"" >&5 printf %s "checking \"CPPFLAGS for $1\"... " >&6; } new_cppflags=`pkg-config --cflags $1` if test -z $new_cppflags; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: \"Not available\"" >&5 printf "%s\n" "\"Not available\"" >&6; } else CPPFLAGS="$new_cppflags $CPPFLAGS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: \"$new_cppflags\"" >&5 printf "%s\n" "\"$new_cppflags\"" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking \"LDFLAGS for $1\"" >&5 printf %s "checking \"LDFLAGS for $1\"... " >&6; } new_ldflags=`pkg-config --libs-only-L $1` if test -z $new_ldflags; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: \"Not available\"" >&5 printf "%s\n" "\"Not available\"" >&6; } else LDFLAGS="$new_ldflags $LDFLAGS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: \"$new_ldflags\"" >&5 printf "%s\n" "\"$new_ldflags\"" >&6; } fi } case $target_os in darwin*) pkgconfig_update_info openssl pkgconfig_update_info portaudio-2.0 ;; *) ;; esac if test "$link_ssl_with_main" = "check"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if ssl needs to be linked with the main library" >&5 printf %s "checking if ssl needs to be linked with the main library... " >&6; } OPENSSLLIBDIR=`pkg-config --libs-only-L openssl | sed 's/-L//'` ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test "$cross_compiling" = yes then : link_ssl_with_main=yes else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include #include #include #include #include #include struct cross_thread_info { int waitfd; int err; }; static void * cross_thread(void *data) { struct cross_thread_info *info = data; sigset_t sigmask, omask; int rv = 0; fd_set rfds; rv = pthread_sigmask(SIG_SETMASK, NULL, &sigmask); assert(rv == 0); if (!sigismember(&sigmask, SIGUSR1)) { fprintf(stderr, "SIGUSR1 not in sigmask 1\n"); info->err = 1; goto out_err; } FD_ZERO(&rfds); FD_SET(info->waitfd, &rfds); sigdelset(&sigmask, SIGUSR1); rv = pthread_sigmask(SIG_SETMASK, &sigmask, &omask); assert(rv == 0); rv = pselect(info->waitfd + 1, &rfds, NULL, NULL, NULL, NULL); assert(rv == 1); rv = pthread_sigmask(SIG_SETMASK, &omask, &sigmask); assert(rv == 0); if (sigismember(&sigmask, SIGUSR1)) { fprintf(stderr, "SIGUSR1 in sigmask 1\n"); info->err = 4; goto out_err; } out_err: return NULL; } static int check_pselect_cross_thread(sigset_t mask) { int rv = 1; int pipefds[2] = { -1, -1 }; struct cross_thread_info info; pthread_t th; char dummy = 0; rv = pipe(pipefds); if (rv == -1) { perror("pipe"); return 1; } info.err = 0; info.waitfd = pipefds[0]; rv = pthread_create(&th, NULL, cross_thread, &info); sleep(2); /* Give the thread time to enter pselect() */ if (dlopen("$OPENSSLLIBDIR/libssl.dylib", RTLD_LAZY | RTLD_GLOBAL) == NULL) { fprintf(stderr, "dlopen failed: %s\n", dlerror()); rv = 1; } write(pipefds[1], &dummy, 1); pthread_join(th, NULL); if (!rv) rv = info.err; if (!rv) printf("dlopen does not affect other threads' sigmasks\n"); close(pipefds[0]); close(pipefds[1]); return rv; } int main(int argc, char *argv[]) { sigset_t mask; int rv; /* Start with SIGUSR1 blocked. */ rv = sigprocmask(SIG_SETMASK, NULL, &mask); assert(rv == 0); sigaddset(&mask, SIGUSR1); rv = sigprocmask(SIG_SETMASK, &mask, NULL); assert(rv == 0); rv = check_pselect_cross_thread(mask); return rv; } _ACEOF if ac_fn_c_try_run "$LINENO" then : link_ssl_with_main=no else $as_nop if test $? = 4; then link_ssl_with_main=yes else link_ssl_with_main=failed fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $link_ssl_with_main" >&5 printf "%s\n" "$link_ssl_with_main" >&6; } if test $link_ssl_with_main == failed; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Error running ssl link test program. See \`config.log' for more details" "$LINENO" 5; } fi fi if test "$version_type" = "windows"; then # LN_S gets set to "cp -pR", which just doesn't work. MinGW has # a working "ln", so force it. LN_SF="ln -sf" else LN_SF="\$(LN_S) -f" fi # If compiling static, turn off DLL visibility, primarily so Windows # will link properly. Don't allow both static and shared libraries # to be built at the same time for now. if test "$version_type" = "windows"; then if test "${enable_shared}" = yes; then enable_static=no fi if test "$enable_static" = "yes"; then EXTRA_CFLAGS="$EXTRA_CFLAGS -DGENSIO_LINK_STATIC" fi # Need to pull in some special things for osops. EXTRA_CFLAGS="$EXTRA_CFLAGS -DNTDDI_VERSION=0x0a000006 -DWINVER=0x0602" fi moduleinstalldir="\$(pkglibexecdir)" # Check whether --with-moduleinstall was given. if test ${with_moduleinstall+y} then : withval=$with_moduleinstall; moduleinstalldir="$withval" fi # Check whether --with-uucp-locking was given. if test ${with_uucp_locking+y} then : withval=$with_uucp_locking; uucp_locking_flag="$withval" fi case "$uucp_locking_flag" in yes) USE_UUCP_LOCKING=1 ;; no) USE_UUCP_LOCKING=0 ;; *) USE_UUCP_LOCKING=1 UUCP_LOCK_DIR="$uucp_locking_flag" ;; esac printf "%s\n" "#define USE_UUCP_LOCKING $USE_UUCP_LOCKING" >>confdefs.h printf "%s\n" "#define UUCP_LOCK_DIR \"$UUCP_LOCK_DIR\"" >>confdefs.h # Check whether --with-flock-locking was given. if test ${with_flock_locking+y} then : withval=$with_flock_locking; flock_locking_flag="$withval" fi case "$flock_locking_flag" in yes) USE_FLOCK_LOCKING=1 ;; no) USE_FLOCK_LOCKING=0 ;; *) USE_FLOCK_LOCKING=1 ;; esac printf "%s\n" "#define USE_FLOCK_LOCKING $USE_FLOCK_LOCKING" >>confdefs.h # Check whether --with-broken-pselect was given. if test ${with_broken_pselect+y} then : withval=$with_broken_pselect; broken_pselect="$withval" fi case "$broken_pselect" in yes) printf "%s\n" "#define BROKEN_PSELECT /**/" >>confdefs.h ;; *) ;; esac # Check whether --with-tcp-wrappers was given. if test ${with_tcp_wrappers+y} then : withval=$with_tcp_wrappers; tcp_wrappers="$withval" else $as_nop tcp_wrappers="no" fi if test "$tcp_wrappers" != "no" then ac_fn_c_check_header_compile "$LINENO" "tcpd.h" "ac_cv_header_tcpd_h" "$ac_includes_default" if test "x$ac_cv_header_tcpd_h" = xyes then : printf "%s\n" "#define HAVE_TCPD_H 1" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for request_init in -lwrap" >&5 printf %s "checking for request_init in -lwrap... " >&6; } if test ${ac_cv_lib_wrap_request_init+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lwrap $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char request_init (); int main (void) { return request_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_wrap_request_init=yes else $as_nop ac_cv_lib_wrap_request_init=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_wrap_request_init" >&5 printf "%s\n" "$ac_cv_lib_wrap_request_init" >&6; } if test "x$ac_cv_lib_wrap_request_init" = xyes then : HAVE_LIBWRAP=1; OSH_LIBS="-lwrap $OSH_LIBS" fi fi # Check whether --enable-doc was given. if test ${enable_doc+y} then : enableval=$enable_doc; else $as_nop enable_doc="yes" fi if test "x$enable_doc" != "xno"; then INSTALL_DOC_TRUE= INSTALL_DOC_FALSE='#' else INSTALL_DOC_TRUE='#' INSTALL_DOC_FALSE= fi ax_have_epoll_cppflags="${CPPFLAGS}" ac_fn_c_check_header_compile "$LINENO" "linux/version.h" "ac_cv_header_linux_version_h" "$ac_includes_default" if test "x$ac_cv_header_linux_version_h" = xyes then : CPPFLAGS="${CPPFLAGS} -DHAVE_LINUX_VERSION_H" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Linux epoll(7) interface with signals extension" >&5 printf %s "checking for Linux epoll(7) interface with signals extension... " >&6; } if test ${ax_cv_have_epoll_pwait+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_LINUX_VERSION_H # include # if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) # error linux kernel version is too old to have epoll_pwait # endif #endif #include #include int main (void) { int fd, rc; struct epoll_event ev; fd = epoll_create(128); rc = epoll_wait(fd, &ev, 1, 0); rc = epoll_pwait(fd, &ev, 1, 0, (sigset_t const *)(0)); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ax_cv_have_epoll_pwait=yes else $as_nop ax_cv_have_epoll_pwait=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi CPPFLAGS="${ax_have_epoll_cppflags}" if test "${ax_cv_have_epoll_pwait}" = "yes" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } ax_config_feature_epoll_pwait=yes else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ax_config_feature_epoll_pwait=no fi # Check whether --enable-epoll_pwait was given. if test ${enable_epoll_pwait+y} then : enableval=$enable_epoll_pwait; case "${enableval}" in yes) ax_config_feature_epoll_pwait="yes" ;; no) ax_config_feature_epoll_pwait="no" ;; *) as_fn_error $? "bad value ${enableval} for feature --epoll_pwait" "$LINENO" 5 ;; esac fi if test "$ax_config_feature_epoll_pwait" = yes then : printf "%s\n" "#define HAVE_EPOLL_PWAIT 1" >>confdefs.h if test "$ax_config_feature_verbose" = yes then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Feature epoll_pwait is enabled" >&5 printf "%s\n" "$as_me: Feature epoll_pwait is enabled" >&6;} fi else $as_nop if test "$ax_config_feature_verbose" = yes then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Feature epoll_pwait is disabled" >&5 printf "%s\n" "$as_me: Feature epoll_pwait is disabled" >&6;} fi fi ac_fn_c_check_func "$LINENO" "kevent" "ac_cv_func_kevent" if test "x$ac_cv_func_kevent" = xyes then : printf "%s\n" "#define HAVE_KEVENT 1" >>confdefs.h fi if test "x$system_type" = "xunix"; then use_pthreads=yes else use_pthreads=no fi use_pthreads_set=false # Check whether --with-pthreads was given. if test ${with_pthreads+y} then : withval=$with_pthreads; use_pthreads_set=true if test "x$withval" = "xyes"; then use_pthreads=yes elif test "x$withval" = "xno"; then use_pthreads=no else { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Unknown value for --with-pthreads. Use yes or no See \`config.log' for more details" "$LINENO" 5; } fi fi if test "x$use_pthreads" != "xno"; then ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 printf %s "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test ${ac_cv_prog_CPP+y} then : printf %s "(cached) " >&6 else $as_nop # Double quotes because $CC needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 printf "%s\n" "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on Tru64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then ax_pthread_save_CC="$CC" ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" if test "x$PTHREAD_CC" != "x" then : CC="$PTHREAD_CC" fi if test "x$PTHREAD_CXX" != "x" then : CXX="$PTHREAD_CXX" fi CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS" >&5 printf %s "checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char pthread_join (); int main (void) { return pthread_join (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ax_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 printf "%s\n" "$ax_pthread_ok" >&6; } if test "x$ax_pthread_ok" = "xno"; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi CC="$ax_pthread_save_CC" CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items with a "," contain both # C compiler flags (before ",") and linker flags (after ","). Other items # starting with a "-" are C compiler flags, and remaining items are # library names, except for "none" which indicates that we try without # any flags at all, and "pthread-config" which is a program returning # the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 # (Note: HP C rejects this with "bad form for `-t' option") # -pthreads: Solaris/gcc (Note: HP C also rejects) # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads and # -D_REENTRANT too), HP C (must be checked before -lpthread, which # is present but should not be used directly; and before -mthreads, # because the compiler interprets this as "-mt" + "-hreads") # -mthreads: Mingw32/gcc, Lynx/gcc # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case $host_os in freebsd*) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) ax_pthread_flags="-kthread lthread $ax_pthread_flags" ;; hpux*) # From the cc(1) man page: "[-mt] Sets various -D flags to enable # multi-threading and also sets -lpthread." ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" ;; openedition*) # IBM z/OS requires a feature-test macro to be defined in order to # enable POSIX threads at all, so give the user a hint if this is # not set. (We don't define these ourselves, as they can affect # other portions of the system API in unpredictable ways.) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) AX_PTHREAD_ZOS_MISSING # endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "AX_PTHREAD_ZOS_MISSING" >/dev/null 2>&1 then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&5 printf "%s\n" "$as_me: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&2;} fi rm -rf conftest* ;; solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (N.B.: The stubs are missing # pthread_cleanup_push, or rather a function called by this macro, # so we could check for that, but who knows whether they'll stub # that too in a future libc.) So we'll check first for the # standard Solaris way of linking pthreads (-mt -lpthread). ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" ;; esac # Are we compiling with Clang? { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC is Clang" >&5 printf %s "checking whether $CC is Clang... " >&6; } if test ${ax_cv_PTHREAD_CLANG+y} then : printf %s "(cached) " >&6 else $as_nop ax_cv_PTHREAD_CLANG=no # Note that Autoconf sets GCC=yes for Clang as well as GCC if test "x$GCC" = "xyes"; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Note: Clang 2.7 lacks __clang_[a-z]+__ */ # if defined(__clang__) && defined(__llvm__) AX_PTHREAD_CC_IS_CLANG # endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "AX_PTHREAD_CC_IS_CLANG" >/dev/null 2>&1 then : ax_cv_PTHREAD_CLANG=yes fi rm -rf conftest* fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG" >&5 printf "%s\n" "$ax_cv_PTHREAD_CLANG" >&6; } ax_pthread_clang="$ax_cv_PTHREAD_CLANG" # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) # Note that for GCC and Clang -pthread generally implies -lpthread, # except when -nostdlib is passed. # This is problematic using libtool to build C++ shared libraries with pthread: # [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 # [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 # [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 # To solve this, first try -pthread together with -lpthread for GCC if test "x$GCC" = "xyes" then : ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags" fi # Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first if test "x$ax_pthread_clang" = "xyes" then : ax_pthread_flags="-pthread,-lpthread -pthread" fi # The presence of a feature test macro requesting re-entrant function # definitions is, on some systems, a strong hint that pthreads support is # correctly enabled case $host_os in darwin* | hpux* | linux* | osf* | solaris*) ax_pthread_check_macro="_REENTRANT" ;; aix*) ax_pthread_check_macro="_THREAD_SAFE" ;; *) ax_pthread_check_macro="--" ;; esac if test "x$ax_pthread_check_macro" = "x--" then : ax_pthread_check_cond=0 else $as_nop ax_pthread_check_cond="!defined($ax_pthread_check_macro)" fi if test "x$ax_pthread_ok" = "xno"; then for ax_pthread_try_flag in $ax_pthread_flags; do case $ax_pthread_try_flag in none) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 printf %s "checking whether pthreads work without any flags... " >&6; } ;; *,*) PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with \"$PTHREAD_CFLAGS\" and \"$PTHREAD_LIBS\"" >&5 printf %s "checking whether pthreads work with \"$PTHREAD_CFLAGS\" and \"$PTHREAD_LIBS\"... " >&6; } ;; -*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $ax_pthread_try_flag" >&5 printf %s "checking whether pthreads work with $ax_pthread_try_flag... " >&6; } PTHREAD_CFLAGS="$ax_pthread_try_flag" ;; pthread-config) # Extract the first word of "pthread-config", so it can be a program name with args. set dummy pthread-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ax_pthread_config+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ax_pthread_config"; then ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ax_pthread_config="yes" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no" fi fi ax_pthread_config=$ac_cv_prog_ax_pthread_config if test -n "$ax_pthread_config"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5 printf "%s\n" "$ax_pthread_config" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ax_pthread_config" = "xno" then : continue fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$ax_pthread_try_flag" >&5 printf %s "checking for the pthreads library -l$ax_pthread_try_flag... " >&6; } PTHREAD_LIBS="-l$ax_pthread_try_flag" ;; esac ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include # if $ax_pthread_check_cond # error "$ax_pthread_check_macro must be defined" # endif static void *some_global = NULL; static void routine(void *a) { /* To avoid any unused-parameter or unused-but-set-parameter warning. */ some_global = a; } static void *start_routine(void *a) { return a; } int main (void) { pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */ ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ax_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 printf "%s\n" "$ax_pthread_ok" >&6; } if test "x$ax_pthread_ok" = "xyes" then : break fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Clang needs special handling, because older versions handle the -pthread # option in a rather... idiosyncratic way if test "x$ax_pthread_clang" = "xyes"; then # Clang takes -pthread; it has never supported any other flag # (Note 1: This will need to be revisited if a system that Clang # supports has POSIX threads in a separate library. This tends not # to be the way of modern systems, but it's conceivable.) # (Note 2: On some systems, notably Darwin, -pthread is not needed # to get POSIX threads support; the API is always present and # active. We could reasonably leave PTHREAD_CFLAGS empty. But # -pthread does define _REENTRANT, and while the Darwin headers # ignore this macro, third-party headers might not.) # However, older versions of Clang make a point of warning the user # that, in an invocation where only linking and no compilation is # taking place, the -pthread option has no effect ("argument unused # during compilation"). They expect -pthread to be passed in only # when source code is being compiled. # # Problem is, this is at odds with the way Automake and most other # C build frameworks function, which is that the same flags used in # compilation (CFLAGS) are also used in linking. Many systems # supported by AX_PTHREAD require exactly this for POSIX threads # support, and in fact it is often not straightforward to specify a # flag that is used only in the compilation phase and not in # linking. Such a scenario is extremely rare in practice. # # Even though use of the -pthread flag in linking would only print # a warning, this can be a nuisance for well-run software projects # that build with -Werror. So if the active version of Clang has # this misfeature, we search for an option to squash it. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread" >&5 printf %s "checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread... " >&6; } if test ${ax_cv_PTHREAD_CLANG_NO_WARN_FLAG+y} then : printf %s "(cached) " >&6 else $as_nop ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown # Create an alternate version of $ac_link that compiles and # links in two steps (.c -> .o, .o -> exe) instead of one # (.c -> exe), because the warning occurs only in the second # step ax_pthread_save_ac_link="$ac_link" ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' ax_pthread_link_step=`printf "%s\n" "$ac_link" | sed "$ax_pthread_sed"` ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" ax_pthread_save_CFLAGS="$CFLAGS" for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do if test "x$ax_pthread_try" = "xunknown" then : break fi CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" ac_link="$ax_pthread_save_ac_link" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void){return 0;} _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_link="$ax_pthread_2step_ac_link" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void){return 0;} _ACEOF if ac_fn_c_try_link "$LINENO" then : break fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext done ac_link="$ax_pthread_save_ac_link" CFLAGS="$ax_pthread_save_CFLAGS" if test "x$ax_pthread_try" = "x" then : ax_pthread_try=no fi ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&5 printf "%s\n" "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&6; } case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in no | unknown) ;; *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; esac fi # $ax_pthread_clang = yes # Various other checks: if test "x$ax_pthread_ok" = "xyes"; then ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 printf %s "checking for joinable pthread attribute... " >&6; } if test ${ax_cv_PTHREAD_JOINABLE_ATTR+y} then : printf %s "(cached) " >&6 else $as_nop ax_cv_PTHREAD_JOINABLE_ATTR=unknown for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { int attr = $ax_pthread_attr; return attr /* ; */ ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext done fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_JOINABLE_ATTR" >&5 printf "%s\n" "$ax_cv_PTHREAD_JOINABLE_ATTR" >&6; } if test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ test "x$ax_pthread_joinable_attr_defined" != "xyes" then : printf "%s\n" "#define PTHREAD_CREATE_JOINABLE $ax_cv_PTHREAD_JOINABLE_ATTR" >>confdefs.h ax_pthread_joinable_attr_defined=yes fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether more special flags are required for pthreads" >&5 printf %s "checking whether more special flags are required for pthreads... " >&6; } if test ${ax_cv_PTHREAD_SPECIAL_FLAGS+y} then : printf %s "(cached) " >&6 else $as_nop ax_cv_PTHREAD_SPECIAL_FLAGS=no case $host_os in solaris*) ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_SPECIAL_FLAGS" >&5 printf "%s\n" "$ax_cv_PTHREAD_SPECIAL_FLAGS" >&6; } if test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ test "x$ax_pthread_special_flags_added" != "xyes" then : PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" ax_pthread_special_flags_added=yes fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5 printf %s "checking for PTHREAD_PRIO_INHERIT... " >&6; } if test ${ax_cv_PTHREAD_PRIO_INHERIT+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { int i = PTHREAD_PRIO_INHERIT; return i; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ax_cv_PTHREAD_PRIO_INHERIT=yes else $as_nop ax_cv_PTHREAD_PRIO_INHERIT=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5 printf "%s\n" "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; } if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ test "x$ax_pthread_prio_inherit_defined" != "xyes" then : printf "%s\n" "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h ax_pthread_prio_inherit_defined=yes fi CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" # More AIX lossage: compile with *_r variant if test "x$GCC" != "xyes"; then case $host_os in aix*) case "x/$CC" in #( x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6) : #handle absolute path differently from PATH based program lookup case "x$CC" in #( x/*) : if as_fn_executable_p ${CC}_r then : PTHREAD_CC="${CC}_r" fi if test "x${CXX}" != "x" then : if as_fn_executable_p ${CXX}_r then : PTHREAD_CXX="${CXX}_r" fi fi ;; #( *) : for ac_prog in ${CC}_r do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_PTHREAD_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$PTHREAD_CC"; then ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_PTHREAD_CC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PTHREAD_CC=$ac_cv_prog_PTHREAD_CC if test -n "$PTHREAD_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 printf "%s\n" "$PTHREAD_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$PTHREAD_CC" && break done test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" if test "x${CXX}" != "x" then : for ac_prog in ${CXX}_r do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_PTHREAD_CXX+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$PTHREAD_CXX"; then ac_cv_prog_PTHREAD_CXX="$PTHREAD_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_PTHREAD_CXX="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PTHREAD_CXX=$ac_cv_prog_PTHREAD_CXX if test -n "$PTHREAD_CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CXX" >&5 printf "%s\n" "$PTHREAD_CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$PTHREAD_CXX" && break done test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX" fi ;; esac ;; #( *) : ;; esac ;; esac fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX" # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test "x$ax_pthread_ok" = "xyes"; then OSH_LIBS="$OSH_LIBS $PTHREAD_LIBS" EXTRA_CFLAGS="$EXTRA_CFLAGS $PTHREAD_CFLAGS" CC="$PTHREAD_CC" printf "%s\n" "#define USE_PTHREADS /**/" >>confdefs.h : else ax_pthread_ok=no if $use_pthreads_set; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "--with-pthreads was given, but no working pthread library was found See \`config.log' for more details" "$LINENO" 5; } fi use_pthreads=no fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi if test "x$system_type" = "xunix"; then tryglib=yes trytcl=yes else tryglib=no trytcl=no fi # Check whether --with-cplusplus was given. if test ${with_cplusplus+y} then : withval=$with_cplusplus; cplusplus="$withval" else $as_nop if test -z "$CXX"; then cplusplus=no else cplusplus=yes fi fi HAVE_CXX11=0 CPLUSPLUS_DIR= if test "$cplusplus" = "yes"; then ax_cxx_compile_alternatives="11 0x" ax_cxx_compile_cxx11_required=false ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_success=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5 printf %s "checking whether $CXX supports C++11 features by default... " >&6; } if test ${ax_cv_cxx_compile_cxx11+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" // MSVC always sets __cplusplus to 199711L in older versions; newer versions // only set it correctly if /Zc:__cplusplus is specified as well as a // /std:c++NN switch: // https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ #elif __cplusplus < 201103L && !defined _MSC_VER #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { virtual ~Derived() override {} virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ax_cv_cxx_compile_cxx11=yes else $as_nop ax_cv_cxx_compile_cxx11=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5 printf "%s\n" "$ax_cv_cxx_compile_cxx11" >&6; } if test x$ax_cv_cxx_compile_cxx11 = xyes; then ac_success=yes fi if test x$ac_success = xno; then for alternative in ${ax_cxx_compile_alternatives}; do switch="-std=gnu++${alternative}" cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 printf %s "checking whether $CXX supports C++11 features with $switch... " >&6; } if eval test \${$cachevar+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_CXX="$CXX" CXX="$CXX $switch" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" // MSVC always sets __cplusplus to 199711L in older versions; newer versions // only set it correctly if /Zc:__cplusplus is specified as well as a // /std:c++NN switch: // https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ #elif __cplusplus < 201103L && !defined _MSC_VER #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { virtual ~Derived() override {} virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval $cachevar=yes else $as_nop eval $cachevar=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CXX="$ac_save_CXX" fi eval ac_res=\$$cachevar { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done fi if test x$ac_success = xno; then for alternative in ${ax_cxx_compile_alternatives}; do for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}" MSVC; do if test x"$switch" = xMSVC; then switch=-std:c++${alternative} cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx11_${switch}_MSVC" | $as_tr_sh` else cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 printf %s "checking whether $CXX supports C++11 features with $switch... " >&6; } if eval test \${$cachevar+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_CXX="$CXX" CXX="$CXX $switch" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" // MSVC always sets __cplusplus to 199711L in older versions; newer versions // only set it correctly if /Zc:__cplusplus is specified as well as a // /std:c++NN switch: // https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ #elif __cplusplus < 201103L && !defined _MSC_VER #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { virtual ~Derived() override {} virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval $cachevar=yes else $as_nop eval $cachevar=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CXX="$ac_save_CXX" fi eval ac_res=\$$cachevar { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done if test x$ac_success = xyes; then break fi done fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test x$ax_cxx_compile_cxx11_required = xtrue; then if test x$ac_success = xno; then as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5 fi fi if test x$ac_success = xno; then HAVE_CXX11=0 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5 printf "%s\n" "$as_me: No compiler with C++11 support was found" >&6;} else HAVE_CXX11=1 printf "%s\n" "#define HAVE_CXX11 1" >>confdefs.h fi if test "$HAVE_CXX11" = 1; then CPLUSPLUS_DIR="c++" else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: C++ version $cplusplusver is too old, need at least 201102, disabling c++" >&5 printf "%s\n" "C++ version $cplusplusver is too old, need at least 201102, disabling c++" >&6; } fi fi # Find pkg-config pkgprog= # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_pkgprog+y} then : printf %s "(cached) " >&6 else $as_nop case $pkgprog in [\\/]* | ?:[\\/]*) ac_cv_path_pkgprog="$pkgprog" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_pkgprog="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi pkgprog=$ac_cv_path_pkgprog if test -n "$pkgprog"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $pkgprog" >&5 printf "%s\n" "$pkgprog" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi # Check whether --with-glib was given. if test ${with_glib+y} then : withval=$with_glib; if test "x$withval" = "xyes"; then if test "x$tryglib" = "xno"; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "glib only support on Unix systems for now See \`config.log' for more details" "$LINENO" 5; } fi elif test "x$withval" = "xno"; then tryglib=no fi fi glibcflags= # Check whether --with-glibcflags was given. if test ${with_glibcflags+y} then : withval=$with_glibcflags; glibcflags="$withval" fi gliblibs= # Check whether --with-gliblibs was given. if test ${with_gliblibs+y} then : withval=$with_gliblibs; gliblibs="$withval" fi # Handle GLIB support haveglib=no if test "x$glibcflags" = "x" -o "x$gliblibs" = "x"; then glibprog= if test "x$tryglib" != "xno"; then if test "x$pkgprog" != "x"; then glibprog=$pkgprog fi fi GLIB_CFLAGS= GLIB_LIBS= if test "x$glibprog" != "x"; then GLIB_CFLAGS=`$glibprog --cflags gthread-2.0 2>/dev/null` if test $? = 0; then haveglib=yes GLIB_LIBS=`$glibprog --libs gthread-2.0 2>/dev/null` fi fi else haveglib=yes GLIB_CFLAGS="$glibcflags" GLIB_LIBS="$gliblibs" fi echo "checking for glib... $haveglib" if test "x$haveglib" = "xyes"; then HAVE_GLIB_TRUE= HAVE_GLIB_FALSE='#' else HAVE_GLIB_TRUE='#' HAVE_GLIB_FALSE= fi if test "x$haveglib" = "xyes"; then printf "%s\n" "#define HAVE_GLIB /**/" >>confdefs.h GLIB_LIB='$(top_builddir)/glib/libgensioglib.la' GLIB_DIR=glib else GLIB_LIB= GLIB_DIR= fi # Check whether --with-tcl was given. if test ${with_tcl+y} then : withval=$with_tcl; if test "x$withval" = "xyes"; then trytcl=yes elif test "x$withval" = "xno"; then trytcl=no fi fi tclcflags= # Check whether --with-tclcflags was given. if test ${with_tclcflags+y} then : withval=$with_tclcflags; tclcflags="$withval" fi tcllibs= # Check whether --with-tcllibs was given. if test ${with_tcllibs+y} then : withval=$with_tcllibs; tcllibs="$withval" fi # Handle TCL support TCL_LIBS= TCL_CFLAGS= havetcl=no if test "x$trytcl" != "xno"; then FOUND_TCL_HEADER=no ver=`echo 'puts \$tcl_version' | tclsh` if test "x$tclcflags" = "x"; then ac_fn_c_check_header_compile "$LINENO" "tcl/tcl.h" "ac_cv_header_tcl_tcl_h" "$ac_includes_default" if test "x$ac_cv_header_tcl_tcl_h" = xyes then : FOUND_TCL_HEADER=yes; fi if test "x$FOUND_TCL_HEADER" != "xyes"; then ac_fn_c_check_header_compile "$LINENO" "tcl.h" "ac_cv_header_tcl_h" "$ac_includes_default" if test "x$ac_cv_header_tcl_h" = xyes then : FOUND_TCL_HEADER=yes; fi if test "x$FOUND_TCL_HEADER" = "xyes"; then TCL_CFLAGS="" fi else tclcflags="-I /usr/include/tcl" TCL_CFLAGS="$tclcflags" fi else TCL_CFLAGS="$tclcflags" FOUND_TCL_HEADER=yes fi if test "x$tcllibs" = "x"; then if test "x$FOUND_TCL_HEADER" = "xyes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Tcl_CancelIdleCall in -ltcl" >&5 printf %s "checking for Tcl_CancelIdleCall in -ltcl... " >&6; } if test ${ac_cv_lib_tcl_Tcl_CancelIdleCall+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ltcl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char Tcl_CancelIdleCall (); int main (void) { return Tcl_CancelIdleCall (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_tcl_Tcl_CancelIdleCall=yes else $as_nop ac_cv_lib_tcl_Tcl_CancelIdleCall=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tcl_Tcl_CancelIdleCall" >&5 printf "%s\n" "$ac_cv_lib_tcl_Tcl_CancelIdleCall" >&6; } if test "x$ac_cv_lib_tcl_Tcl_CancelIdleCall" = xyes then : TCL_LIBS=-ltcl fi if test "x$TCL_LIBS" = "x"; then as_ac_Lib=`printf "%s\n" "ac_cv_lib_tcl$ver""_Tcl_DoOneEvent" | $as_tr_sh` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Tcl_DoOneEvent in -ltcl$ver" >&5 printf %s "checking for Tcl_DoOneEvent in -ltcl$ver... " >&6; } if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ltcl$ver $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char Tcl_DoOneEvent (); int main (void) { return Tcl_DoOneEvent (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$as_ac_Lib=yes" else $as_nop eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes" then : TCL_LIBS=-ltcl$ver fi fi fi else TCL_LIBS="$tcllibs" fi if test "x$FOUND_TCL_HEADER" = "xyes" -a "x$TCL_LIBS" != "x"; then havetcl=yes fi fi if test "x$havetcl" = "xyes"; then printf "%s\n" "#define HAVE_TCL /**/" >>confdefs.h TCL_LIB='$(top_builddir)/tcl/libgensiotcl.la' TCL_DIR=tcl else TCL_LIB= TCL_DIR= fi ac_fn_c_check_func "$LINENO" "regexec" "ac_cv_func_regexec" if test "x$ac_cv_func_regexec" = xyes then : printf "%s\n" "#define HAVE_REGEXEC 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "fnmatch" "ac_cv_func_fnmatch" if test "x$ac_cv_func_fnmatch" = xyes then : printf "%s\n" "#define HAVE_FNMATCH 1" >>confdefs.h fi have_pcre_posix=no REGEX_LIB= if test "x$ac_cv_func_regexec" != xyes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for regexec in -lpcreposix" >&5 printf %s "checking for regexec in -lpcreposix... " >&6; } if test ${ac_cv_lib_pcreposix_regexec+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lpcreposix $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char regexec (); int main (void) { return regexec (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_pcreposix_regexec=yes else $as_nop ac_cv_lib_pcreposix_regexec=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcreposix_regexec" >&5 printf "%s\n" "$ac_cv_lib_pcreposix_regexec" >&6; } if test "x$ac_cv_lib_pcreposix_regexec" = xyes then : have_pcre_posix=yes fi if test $have_pcre_posix = yes; then REGEX_LIB=-lpcreposix printf "%s\n" "#define HAVE_PCRE_POSIX /**/" >>confdefs.h ac_cv_func_regexec=pcre fi fi ac_fn_c_check_func "$LINENO" "fnmatch" "ac_cv_func_fnmatch" if test "x$ac_cv_func_fnmatch" = xyes then : printf "%s\n" "#define HAVE_FNMATCH 1" >>confdefs.h fi # If not creating shared libraries, build everything in. if test "$enable_shared" = "no"; then default_all=yes else default_all=dynamic fi # Check whether --with-all-gensios was given. if test ${with_all_gensios+y} then : withval=$with_all_gensios; if test "x$withval" = "xyes"; then default_all=yes elif test "x$withval" = "xdynamic"; then default_all=dynamic elif test "x$withval" = "xno"; then default_all=no fi fi BUILTIN_GENSIOS="" DYNAMIC_GENSIOS="" net=$default_all # Check whether --with-net was given. if test ${with_net+y} then : withval=$with_net; if test "x$withval" = "xyes"; then net=yes elif test "x$withval" = "xdynamic"; then net=dynamic elif test "x$withval" = "xno"; then net=no fi fi BUILTIN_NET=0 DYNAMIC_NET= case $net in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS net" BUILTIN_NET=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS net" DYNAMIC_NET=libgensio_net.la ;; no) ;; esac if test ${BUILTIN_NET} = 1; then BUILTIN_NET_TRUE= BUILTIN_NET_FALSE='#' else BUILTIN_NET_TRUE='#' BUILTIN_NET_FALSE= fi dgram=$default_all # Check whether --with-dgram was given. if test ${with_dgram+y} then : withval=$with_dgram; if test "x$withval" = "xyes"; then dgram=yes elif test "x$withval" = "xdynamic"; then dgram=dynamic elif test "x$withval" = "xno"; then dgram=no fi fi BUILTIN_DGRAM=0 DYNAMIC_DGRAM= case $dgram in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS dgram" BUILTIN_DGRAM=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS dgram" DYNAMIC_DGRAM=libgensio_dgram.la ;; no) ;; esac if test ${BUILTIN_DGRAM} = 1; then BUILTIN_DGRAM_TRUE= BUILTIN_DGRAM_FALSE='#' else BUILTIN_DGRAM_TRUE='#' BUILTIN_DGRAM_FALSE= fi trysctp=yes # Check whether --with-sctp was given. if test ${with_sctp+y} then : withval=$with_sctp; if test "x$withval" = "xyes"; then trysctp=yes elif test "x$withval" = "xno"; then trysctp=no fi fi HAVE_LIBSCTP=0 if test "x$trysctp" != "xno"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sctp_bindx in -lsctp" >&5 printf %s "checking for sctp_bindx in -lsctp... " >&6; } if test ${ac_cv_lib_sctp_sctp_bindx+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsctp $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char sctp_bindx (); int main (void) { return sctp_bindx (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_sctp_sctp_bindx=yes else $as_nop ac_cv_lib_sctp_sctp_bindx=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sctp_sctp_bindx" >&5 printf "%s\n" "$ac_cv_lib_sctp_sctp_bindx" >&6; } if test "x$ac_cv_lib_sctp_sctp_bindx" = xyes then : HAVE_LIBSCTP=1 fi fi printf "%s\n" "#define HAVE_LIBSCTP $HAVE_LIBSCTP" >>confdefs.h HAVE_SCTP_SENDV=0 if test "$HAVE_LIBSCTP" = "1"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sctp_sendv in -lsctp" >&5 printf %s "checking for sctp_sendv in -lsctp... " >&6; } if test ${ac_cv_lib_sctp_sctp_sendv+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsctp $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char sctp_sendv (); int main (void) { return sctp_sendv (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_sctp_sctp_sendv=yes else $as_nop ac_cv_lib_sctp_sctp_sendv=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sctp_sctp_sendv" >&5 printf "%s\n" "$ac_cv_lib_sctp_sctp_sendv" >&6; } if test "x$ac_cv_lib_sctp_sctp_sendv" = xyes then : HAVE_SCTP_SENDV=1 fi fi printf "%s\n" "#define HAVE_SCTP_SENDV $HAVE_SCTP_SENDV" >>confdefs.h if test "$HAVE_LIBSCTP" = "1"; then sctp=$default_all OSH_LIBS="-lsctp $OSH_LIBS" else sctp=no fi # Check whether --with-sctp was given. if test ${with_sctp+y} then : withval=$with_sctp; if test "x$withval" = "xyes"; then sctp=yes elif test "x$withval" = "xdynamic"; then sctp=dynamic elif test "x$withval" = "xno"; then sctp=no fi fi BUILTIN_SCTP=0 DYNAMIC_SCTP= case $sctp in yes) if test $HAVE_LIBSCTP = 0; then as_fn_error $? "\"sctp enabled but libsctp not found\"" "$LINENO" 5 fi BUILTIN_GENSIOS="$BUILTIN_GENSIOS sctp" BUILTIN_SCTP=1 ;; dynamic) if test $HAVE_LIBSCTP = 0; then as_fn_error $? "\"sctp enabled but libsctp not found\"" "$LINENO" 5 fi DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS sctp" DYNAMIC_SCTP=libgensio_sctp.la ;; no) ;; esac if test ${BUILTIN_SCTP} = 1; then BUILTIN_SCTP_TRUE= BUILTIN_SCTP_FALSE='#' else BUILTIN_SCTP_TRUE='#' BUILTIN_SCTP_FALSE= fi stdio=$default_all # Check whether --with-stdio was given. if test ${with_stdio+y} then : withval=$with_stdio; if test "x$withval" = "xyes"; then stdio=yes elif test "x$withval" = "xdynamic"; then stdio=dynamic elif test "x$withval" = "xno"; then stdio=no fi fi BUILTIN_STDIO=0 DYNAMIC_STDIO= case $stdio in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS stdio" BUILTIN_STDIO=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS stdio" DYNAMIC_STDIO=libgensio_stdio.la ;; no) ;; esac if test ${BUILTIN_STDIO} = 1; then BUILTIN_STDIO_TRUE= BUILTIN_STDIO_FALSE='#' else BUILTIN_STDIO_TRUE='#' BUILTIN_STDIO_FALSE= fi pty=$default_all # Check whether --with-pty was given. if test ${with_pty+y} then : withval=$with_pty; if test "x$withval" = "xyes"; then pty=yes elif test "x$withval" = "xdynamic"; then pty=dynamic elif test "x$withval" = "xno"; then pty=no fi fi BUILTIN_PTY=0 DYNAMIC_PTY= case $pty in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS pty" BUILTIN_PTY=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS pty" DYNAMIC_PTY=libgensio_pty.la ;; no) ;; esac if test ${BUILTIN_PTY} = 1; then BUILTIN_PTY_TRUE= BUILTIN_PTY_FALSE='#' else BUILTIN_PTY_TRUE='#' BUILTIN_PTY_FALSE= fi dummy=$default_all # Check whether --with-dummy was given. if test ${with_dummy+y} then : withval=$with_dummy; if test "x$withval" = "xyes"; then dummy=yes elif test "x$withval" = "xdynamic"; then dummy=dynamic elif test "x$withval" = "xno"; then dummy=no fi fi BUILTIN_DUMMY=0 DYNAMIC_DUMMY= case $dummy in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS dummy" BUILTIN_DUMMY=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS dummy" DYNAMIC_DUMMY=libgensio_dummy.la ;; no) ;; esac if test ${BUILTIN_DUMMY} = 1; then BUILTIN_DUMMY_TRUE= BUILTIN_DUMMY_FALSE='#' else BUILTIN_DUMMY_TRUE='#' BUILTIN_DUMMY_FALSE= fi conacc=$default_all # Check whether --with-conacc was given. if test ${with_conacc+y} then : withval=$with_conacc; if test "x$withval" = "xyes"; then conacc=yes elif test "x$withval" = "xdynamic"; then conacc=dynamic elif test "x$withval" = "xno"; then conacc=no fi fi BUILTIN_CONACC=0 DYNAMIC_CONACC= case $conacc in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS conacc" BUILTIN_CONACC=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS conacc" DYNAMIC_CONACC=libgensio_conacc.la ;; no) ;; esac if test ${BUILTIN_CONACC} = 1; then BUILTIN_CONACC_TRUE= BUILTIN_CONACC_FALSE='#' else BUILTIN_CONACC_TRUE='#' BUILTIN_CONACC_FALSE= fi serialdev=$default_all # Check whether --with-serialdev was given. if test ${with_serialdev+y} then : withval=$with_serialdev; if test "x$withval" = "xyes"; then serialdev=yes elif test "x$withval" = "xdynamic"; then serialdev=dynamic elif test "x$withval" = "xno"; then serialdev=no fi fi BUILTIN_SERIALDEV=0 DYNAMIC_SERIALDEV= case $serialdev in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS serialdev" BUILTIN_SERIALDEV=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS serialdev" DYNAMIC_SERIALDEV=libgensio_serialdev.la ;; no) ;; esac if test ${BUILTIN_SERIALDEV} = 1; then BUILTIN_SERIALDEV_TRUE= BUILTIN_SERIALDEV_FALSE='#' else BUILTIN_SERIALDEV_TRUE='#' BUILTIN_SERIALDEV_FALSE= fi echo=$default_all # Check whether --with-echo was given. if test ${with_echo+y} then : withval=$with_echo; if test "x$withval" = "xyes"; then echo=yes elif test "x$withval" = "xdynamic"; then echo=dynamic elif test "x$withval" = "xno"; then echo=no fi fi BUILTIN_ECHO=0 DYNAMIC_ECHO= case $echo in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS echo" BUILTIN_ECHO=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS echo" DYNAMIC_ECHO=libgensio_echo.la ;; no) ;; esac if test ${BUILTIN_ECHO} = 1; then BUILTIN_ECHO_TRUE= BUILTIN_ECHO_FALSE='#' else BUILTIN_ECHO_TRUE='#' BUILTIN_ECHO_FALSE= fi file=$default_all # Check whether --with-file was given. if test ${with_file+y} then : withval=$with_file; if test "x$withval" = "xyes"; then file=yes elif test "x$withval" = "xdynamic"; then file=dynamic elif test "x$withval" = "xno"; then file=no fi fi BUILTIN_FILE=0 DYNAMIC_FILE= case $file in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS file" BUILTIN_FILE=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS file" DYNAMIC_FILE=libgensio_file.la ;; no) ;; esac if test ${BUILTIN_FILE} = 1; then BUILTIN_FILE_TRUE= BUILTIN_FILE_FALSE='#' else BUILTIN_FILE_TRUE='#' BUILTIN_FILE_FALSE= fi # Handle OpenIPMI support OPENIPMI_CPPFLAGS= # Check whether --with-openipmiflags was given. if test ${with_openipmiflags+y} then : withval=$with_openipmiflags; OPENIPMI_CPPFLAGS="$withval" fi OPENIPMI_LIBS= # Check whether --with-openipmilibs was given. if test ${with_openipmilibs+y} then : withval=$with_openipmilibs; OPENIPMI_LIBS="$withval" fi # Check whether --with-openipmi was given. if test ${with_openipmi+y} then : withval=$with_openipmi; if test "x$withval" = "xyes"; then tryopenipmi=yes elif test "x$withval" = "xno"; then tryopenipmi=no fi fi HAVE_OPENIPMI=0 if test "x$tryopenipmi" != "xno"; then found_ipmiif=no ac_fn_c_check_header_compile "$LINENO" "OpenIPMI/ipmiif.h" "ac_cv_header_OpenIPMI_ipmiif_h" "$ac_includes_default" if test "x$ac_cv_header_OpenIPMI_ipmiif_h" = xyes then : found_ipmiif=yes; fi if test "x$found_ipmiif" = "xyes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ipmi_alloc_os_handler in -lOpenIPMI" >&5 printf %s "checking for ipmi_alloc_os_handler in -lOpenIPMI... " >&6; } if test ${ac_cv_lib_OpenIPMI_ipmi_alloc_os_handler+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lOpenIPMI $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char ipmi_alloc_os_handler (); int main (void) { return ipmi_alloc_os_handler (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_OpenIPMI_ipmi_alloc_os_handler=yes else $as_nop ac_cv_lib_OpenIPMI_ipmi_alloc_os_handler=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_OpenIPMI_ipmi_alloc_os_handler" >&5 printf "%s\n" "$ac_cv_lib_OpenIPMI_ipmi_alloc_os_handler" >&6; } if test "x$ac_cv_lib_OpenIPMI_ipmi_alloc_os_handler" = xyes then : HAVE_OPENIPMI=1 fi fi fi if test "$HAVE_OPENIPMI" = "1"; then ipmisol=$default_all if test "x$OPENIPMI_LIBS" = "x"; then if test "x$ax_pthread_ok" = "xyes"; then OPENIPMI_LIBS="-lOpenIPMI -lOpenIPMIpthread -lOpenIPMIutils" else OPENIPMI_LIBS="-lOpenIPMI -lOpenIPMIposix -lOpenIPMIutils" fi fi else ipmisol=no fi printf "%s\n" "#define HAVE_OPENIPMI $HAVE_OPENIPMI" >>confdefs.h if test ${HAVE_OPENIPMI} = 1; then HAVE_OPENIPMI_TRUE= HAVE_OPENIPMI_FALSE='#' else HAVE_OPENIPMI_TRUE='#' HAVE_OPENIPMI_FALSE= fi # Check whether --with-ipmisol was given. if test ${with_ipmisol+y} then : withval=$with_ipmisol; if test "x$withval" = "xyes"; then ipmisol=yes elif test "x$withval" = "xdynamic"; then ipmisol=dynamic elif test "x$withval" = "xno"; then ipmisol=no fi fi BUILTIN_IPMISOL=0 DYNAMIC_IPMISOL= case $ipmisol in yes) if test $HAVE_OPENIPMI = 0; then as_fn_error $? "\"ipmisol enabled but openipmi not found\"" "$LINENO" 5 fi BASE_LIBS="$BASE_LIBS $OPENIPMI_LIBS" BUILTIN_GENSIOS="$BUILTIN_GENSIOS ipmisol" BUILTIN_IPMISOL=1 ;; dynamic) if test $HAVE_OPENIPMI = 0; then as_fn_error $? "\"ipmisol enabled but openipmi not found\"" "$LINENO" 5 fi DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS ipmisol" DYNAMIC_IPMISOL=libgensio_ipmisol.la ;; no) ;; esac if test ${BUILTIN_IPMISOL} = 1; then BUILTIN_IPMISOL_TRUE= BUILTIN_IPMISOL_FALSE='#' else BUILTIN_IPMISOL_TRUE='#' BUILTIN_IPMISOL_FALSE= fi trymdns=yes # Check whether --with-mdns was given. if test ${with_mdns+y} then : withval=$with_mdns; if test "x$withval" = "x"; then trymdns=yes elif test "x$withval" = "xyes"; then trymdns=yes elif test "x$withval" = "xno"; then trymdns=no fi fi HAVE_MDNS=0 HAVE_AVAHI=0 tryavahi=yes # Check whether --with-avahi was given. if test ${with_avahi+y} then : withval=$with_avahi; if test "x$withval" = "x"; then tryavahi=yes elif test "x$withval" = "xyes"; then tryavahi=yes elif test "x$withval" = "xno"; then tryavahi=no fi fi if test $trymdns = yes -a $tryavahi = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for avahi_client_new in -lavahi-client" >&5 printf %s "checking for avahi_client_new in -lavahi-client... " >&6; } if test ${ac_cv_lib_avahi_client_avahi_client_new+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lavahi-client $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char avahi_client_new (); int main (void) { return avahi_client_new (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_avahi_client_avahi_client_new=yes else $as_nop ac_cv_lib_avahi_client_avahi_client_new=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_avahi_client_avahi_client_new" >&5 printf "%s\n" "$ac_cv_lib_avahi_client_avahi_client_new" >&6; } if test "x$ac_cv_lib_avahi_client_avahi_client_new" = xyes then : HAVE_AVAHI=1 fi fi if test "$HAVE_AVAHI" = "1"; then mdns=$default_all MDNS_LIBS="-lavahi-client -lavahi-common" HAVE_MDNS=1 fi printf "%s\n" "#define HAVE_AVAHI $HAVE_AVAHI" >>confdefs.h if test ${HAVE_AVAHI} = 1; then HAVE_AVAHI_TRUE= HAVE_AVAHI_FALSE='#' else HAVE_AVAHI_TRUE='#' HAVE_AVAHI_FALSE= fi HAVE_DNSSD=0 trydnssd=yes # Check whether --with-dnssd was given. if test ${with_dnssd+y} then : withval=$with_dnssd; if test "x$withval" = "x"; then trydnssd=yes elif test "x$withval" = "xyes"; then trydnssd=yes elif test "x$withval" = "xno"; then trydnssd=no fi fi if test $trymdns = yes -a ${HAVE_AVAHI} = 0 -a $trydnssd = yes; then found_dns_sh=no ac_fn_c_check_header_compile "$LINENO" "dns_sd.h" "ac_cv_header_dns_sd_h" "$ac_includes_default" if test "x$ac_cv_header_dns_sd_h" = xyes then : found_dns_sd=yes fi if test "x$found_dns_sd" = "xyes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for DNSServiceRegister in -ldns_sd" >&5 printf %s "checking for DNSServiceRegister in -ldns_sd... " >&6; } if test ${ac_cv_lib_dns_sd_DNSServiceRegister+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldns_sd $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char DNSServiceRegister (); int main (void) { return DNSServiceRegister (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dns_sd_DNSServiceRegister=yes else $as_nop ac_cv_lib_dns_sd_DNSServiceRegister=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dns_sd_DNSServiceRegister" >&5 printf "%s\n" "$ac_cv_lib_dns_sd_DNSServiceRegister" >&6; } if test "x$ac_cv_lib_dns_sd_DNSServiceRegister" = xyes then : HAVE_DNSSD=1 fi if test "$HAVE_DNSSD" = "1"; then MDNS_LIBS="-ldns_sd" else ac_fn_c_check_func "$LINENO" "DNSServiceRegister" "ac_cv_func_DNSServiceRegister" if test "x$ac_cv_func_DNSServiceRegister" = xyes then : HAVE_DNSSD=1 fi fi if test "$HAVE_DNSSD" = "1"; then mdns=$default_all HAVE_MDNS=1 fi fi fi printf "%s\n" "#define HAVE_DNSSD $HAVE_DNSSD" >>confdefs.h if test ${HAVE_DNSSD} = 1; then HAVE_DNSSD_TRUE= HAVE_DNSSD_FALSE='#' else HAVE_DNSSD_TRUE='#' HAVE_DNSSD_FALSE= fi HAVE_WINMDNS=0 if test "$version_type" = "windows"; then trywinmdns=yes else trywinmdns=no fi # Check whether --with-winmdns was given. if test ${with_winmdns+y} then : withval=$with_winmdns; if test "x$withval" = "x"; then trywinmdns=yes elif test "x$withval" = "xyes"; then trywinmdns=yes elif test "x$withval" = "xno"; then trywinmdns=no fi fi if test $trymdns = yes -a ${HAVE_AVAHI} = 0 -a ${HAVE_DNSSD} = 0 \ -a $trywinmdns = yes; then found_windns=no ac_fn_c_check_header_compile "$LINENO" "windns.h" "ac_cv_header_windns_h" "#include " if test "x$ac_cv_header_windns_h" = xyes then : found_windns=yes fi if test "x$found_windns" = "xyes"; then # AC_CHECK_LIB() doesn't work on DnsServiceBrowse() on mingw32, # for some reason it won't compile without includeing windns.h. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for MDNS support in Windows" >&5 printf %s "checking for MDNS support in Windows... " >&6; } ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main (void) { DnsServiceBrowse(NULL, NULL); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : HAVE_WINMDNS=1; { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi if test "$HAVE_WINMDNS" = "1"; then mdns=$default_all MDNS_LIBS="-ldnsapi" if test $target_os = msys; then # We are using Windows MDNS on MSYS2 MDNS_LIBS="-liphlpapi $MDNS_LIBS" fi HAVE_MDNS=1 fi fi printf "%s\n" "#define HAVE_WINMDNS $HAVE_WINMDNS" >>confdefs.h if test ${HAVE_WINMDNS} = 1; then HAVE_WINMDNS_TRUE= HAVE_WINMDNS_FALSE='#' else HAVE_WINMDNS_TRUE='#' HAVE_WINMDNS_FALSE= fi GMDNS= GMDNSMAN= if test ${HAVE_MDNS} = 1; then GMDNS="gmdns\$(EXEEXT)" GMDNSMAN=gmdns.1 else mdns=no fi printf "%s\n" "#define HAVE_MDNS $HAVE_MDNS" >>confdefs.h if test ${HAVE_MDNS} = 1; then HAVE_MDNS_TRUE= HAVE_MDNS_FALSE='#' else HAVE_MDNS_TRUE='#' HAVE_MDNS_FALSE= fi # Check whether --with-mdns was given. if test ${with_mdns+y} then : withval=$with_mdns; if test "x$withval" = "xyes"; then mdns=yes elif test "x$withval" = "xdynamic"; then mdns=dynamic elif test "x$withval" = "xno"; then mdns=no fi fi BUILTIN_MDNS=0 DYNAMIC_MDNS= BUILTIN_MDNS_LIBS= case $mdns in yes) if test $HAVE_MDNS = 0; then as_fn_error $? "\"mdns enabled but no support not found\"" "$LINENO" 5 fi BUILTIN_GENSIOS="$BUILTIN_GENSIOS mdns" BUILTIN_MDNS_LIBS="$MDNS_LIBS" BUILTIN_MDNS=1 ;; dynamic) if test $HAVE_MDNS = 0; then as_fn_error $? "\"mdns enabled but no support not found\"" "$LINENO" 5 fi DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS mdns" DYNAMIC_MDNS=libgensio_mdns.la ;; no) ;; esac if test ${BUILTIN_MDNS} = 1; then BUILTIN_MDNS_TRUE= BUILTIN_MDNS_FALSE='#' else BUILTIN_MDNS_TRUE='#' BUILTIN_MDNS_FALSE= fi SOUND_LIBS= # Handle alsa support tryalsa=yes # Check whether --with-alsa was given. if test ${with_alsa+y} then : withval=$with_alsa; if test "x$withval" = "xyes"; then tryalsa=yes elif test "x$withval" = "xno"; then tryalsa=no fi fi HAVE_ALSA=no if test "x$tryalsa" != "xno"; then found_alsa=no ac_fn_c_check_header_compile "$LINENO" "alsa/asoundlib.h" "ac_cv_header_alsa_asoundlib_h" "$ac_includes_default" if test "x$ac_cv_header_alsa_asoundlib_h" = xyes then : found_alsa=yes; fi if test "x$found_alsa" = "xyes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for snd_pcm_open in -lasound" >&5 printf %s "checking for snd_pcm_open in -lasound... " >&6; } if test ${ac_cv_lib_asound_snd_pcm_open+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lasound $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char snd_pcm_open (); int main (void) { return snd_pcm_open (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_asound_snd_pcm_open=yes else $as_nop ac_cv_lib_asound_snd_pcm_open=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_asound_snd_pcm_open" >&5 printf "%s\n" "$ac_cv_lib_asound_snd_pcm_open" >&6; } if test "x$ac_cv_lib_asound_snd_pcm_open" = xyes then : HAVE_ALSA=yes fi fi fi if test "x$HAVE_ALSA" != "xno"; then SOUND_LIBS="$SOUND_LIBS -lasound" HAVE_ALSA=1 else HAVE_ALSA=0 fi printf "%s\n" "#define HAVE_ALSA $HAVE_ALSA" >>confdefs.h # Allow windows sound to be disabled # Check whether --with-winsound was given. if test ${with_winsound+y} then : withval=$with_winsound; if test "x$withval" = "xyes"; then HAVE_WIN32SOUND=1 elif test "x$withval" = "xno"; then HAVE_WIN32SOUND=0 fi fi printf "%s\n" "#define HAVE_WIN32SOUND $HAVE_WIN32SOUND" >>confdefs.h if test $HAVE_WIN32SOUND = 1; then SOUND_LIBS="$SOUND_LIBS -lwinmm" fi # Handle portaudio support, only try if we don't have something else if test $HAVE_ALSA = 1 -o $HAVE_WIN32SOUND == 1; then tryportaudio=no else tryportaudio=yes fi HAVE_PORTAUDIO=no # Check whether --with-portaudio was given. if test ${with_portaudio+y} then : withval=$with_portaudio; if test "x$withval" = "xyes"; then tryportaudio=yes elif test "x$withval" = "xno"; then tryportaudio=no fi fi if test "x$tryportaudio" != "xno"; then found_portaudio=no ac_fn_c_check_header_compile "$LINENO" "portaudio.h" "ac_cv_header_portaudio_h" "$ac_includes_default" if test "x$ac_cv_header_portaudio_h" = xyes then : found_portaudio=yes; fi if test "x$found_portaudio" = "xyes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Pa_OpenStream in -lportaudio" >&5 printf %s "checking for Pa_OpenStream in -lportaudio... " >&6; } if test ${ac_cv_lib_portaudio_Pa_OpenStream+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lportaudio $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char Pa_OpenStream (); int main (void) { return Pa_OpenStream (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_portaudio_Pa_OpenStream=yes else $as_nop ac_cv_lib_portaudio_Pa_OpenStream=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_portaudio_Pa_OpenStream" >&5 printf "%s\n" "$ac_cv_lib_portaudio_Pa_OpenStream" >&6; } if test "x$ac_cv_lib_portaudio_Pa_OpenStream" = xyes then : HAVE_PORTAUDIO=yes fi fi fi if test "x$HAVE_PORTAUDIO" != "xno"; then SOUND_LIBS="$SOUND_LIBS -lportaudio" HAVE_PORTAUDIO=1 else HAVE_PORTAUDIO=0 fi printf "%s\n" "#define HAVE_PORTAUDIO $HAVE_PORTAUDIO" >>confdefs.h sound=$default_all # Check whether --with-sound was given. if test ${with_sound+y} then : withval=$with_sound; if test "x$withval" = "xyes"; then sound=yes elif test "x$withval" = "xdynamic"; then sound=dynamic elif test "x$withval" = "xno"; then sound=no fi fi BUILTIN_SOUND=0 DYNAMIC_SOUND= case $sound in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS sound" BUILTIN_SOUND=1 BASE_LIBS="$BASE_LIBS $SOUND_LIBS" ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS sound" DYNAMIC_SOUND=libgensio_sound.la ;; no) ;; esac if test ${BUILTIN_SOUND} = 1; then BUILTIN_SOUND_TRUE= BUILTIN_SOUND_FALSE='#' else BUILTIN_SOUND_TRUE='#' BUILTIN_SOUND_FALSE= fi # Handle udev support tryudev=yes # Check whether --with-udev was given. if test ${with_udev+y} then : withval=$with_udev; if test "x$withval" = "xyes"; then tryudev=yes elif test "x$withval" = "xno"; then tryudev=no fi fi HAVE_UDEV=no if test "x$tryudev" != "xno"; then found_udev=no ac_fn_c_check_header_compile "$LINENO" "libudev.h" "ac_cv_header_libudev_h" "$ac_includes_default" if test "x$ac_cv_header_libudev_h" = xyes then : found_udev=yes; fi if test "x$found_udev" = "xyes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for udev_new in -ludev" >&5 printf %s "checking for udev_new in -ludev... " >&6; } if test ${ac_cv_lib_udev_udev_new+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ludev $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char udev_new (); int main (void) { return udev_new (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_udev_udev_new=yes else $as_nop ac_cv_lib_udev_udev_new=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_udev_udev_new" >&5 printf "%s\n" "$ac_cv_lib_udev_udev_new" >&6; } if test "x$ac_cv_lib_udev_udev_new" = xyes then : HAVE_UDEV=yes fi fi fi if test "x$HAVE_UDEV" != "xno"; then HAVE_UDEV=1 else HAVE_UDEV=0 fi printf "%s\n" "#define HAVE_UDEV $HAVE_UDEV" >>confdefs.h if test "$HAVE_UDEV" = "1" -o "$version_type" = "windows"; then cm108gpio=$default_all else cm108gpio=no fi # Check whether --with-cm108gpio was given. if test ${with_cm108gpio+y} then : withval=$with_cm108gpio; if test "x$withval" = "xyes"; then cm108gpio=yes elif test "x$withval" = "xdynamic"; then cm108gpio=dynamic elif test "x$withval" = "xno"; then cm108gpio=no fi fi BUILTIN_CM108GPIO=0 DYNAMIC_CM108GPIO= if test "x$HAVE_UDEV" != "0"; then CM108GPIO_LIBS="-ludev" fi if test "$version_type" = "windows"; then CM108GPIO_LIBS="-lhid -lsetupapi" fi case $cm108gpio in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS cm108gpio" BUILTIN_CM108GPIO=1 BASE_LIBS="$BASE_LIBS $CM108GPIO_LIBS" ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS cm108gpio" DYNAMIC_CM108GPIO=libgensio_cm108gpio.la ;; no) ;; esac if test ${BUILTIN_CM108GPIO} = 1; then BUILTIN_CM108GPIO_TRUE= BUILTIN_CM108GPIO_FALSE='#' else BUILTIN_CM108GPIO_TRUE='#' BUILTIN_CM108GPIO_FALSE= fi HAVE_OPENSSL=0 found=false tryopenssl=true ssldirs="" # Check whether --with-openssl was given. if test ${with_openssl+y} then : withval=$with_openssl; case "$withval" in "" | y | ye | yes) ;; n | no) tryopenssl=false ;; *) ssldirs="$withval" ;; esac fi if $tryopenssl; then if test x"$ssldirs" = x""; then # if pkg-config is installed and openssl has installed a .pc file, # then use that information and don't search ssldirs # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_PKG_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 printf "%s\n" "$PKG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test x"$PKG_CONFIG" != x""; then OPENSSL_LDFLAGS=`$PKG_CONFIG openssl --libs-only-L 2>/dev/null` if test $? = 0; then OPENSSL_LIBS=`$PKG_CONFIG openssl --libs-only-l 2>/dev/null` OPENSSL_INCLUDES=`$PKG_CONFIG openssl --cflags-only-I 2>/dev/null` found=true fi fi # no such luck; use some default ssldirs if ! $found; then ssldirs="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr" # Defaults for some specific targets case $target_os in mingw*) case $target_cpu in i686) ssldirs="/mingw32 $ssldirs" ;; x86_64) case "$MSYSTEM" in UCRT64) ssldirs="/ucrt64 $ssldirs" ;; MINGW64) ssldirs="/mingw64 $ssldirs" ;; esac ;; esac ;; darwin*) ssldirs="$ssldirs /opt/homebrew" ;; esac fi fi # note that we #include , so the OpenSSL headers have to be in # an 'openssl' subdirectory if ! $found; then OPENSSL_INCLUDES= for ssldir in $ssldirs; do { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for openssl/ssl.h in $ssldir" >&5 printf %s "checking for openssl/ssl.h in $ssldir... " >&6; } if test -f "$ssldir/include/openssl/ssl.h"; then OPENSSL_INCLUDES="-I$ssldir/include" OPENSSL_LDFLAGS="-L$ssldir/lib" OPENSSL_LIBS="-lssl -lcrypto" found=true { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } break else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi done # if the file wasn't found, well, go ahead and try the link anyway -- maybe # it will just work! fi # try the preprocessor and linker with our new flags, # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiling and linking against OpenSSL works" >&5 printf %s "checking whether compiling and linking against OpenSSL works... " >&6; } echo "Trying link with OPENSSL_LDFLAGS=$OPENSSL_LDFLAGS;" \ "OPENSSL_LIBS=$OPENSSL_LIBS; OPENSSL_INCLUDES=$OPENSSL_INCLUDES" >&5 save_LIBS="$LIBS" save_LDFLAGS="$LDFLAGS" save_CPPFLAGS="$CPPFLAGS" LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS" LIBS="$OPENSSL_LIBS $LIBS" CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { SSL_new(NULL) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } HAVE_OPENSSL=1 else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Skipping openssl check, openssl disabled" >&5 printf "%s\n" "$as_me: Skipping openssl check, openssl disabled" >&6;} fi HAVE_RAND_SET_DRBG_TYPE=0 if test "$HAVE_OPENSSL" = "1"; then ssl=$default_all certauth=$default_all { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for RAND_set_DRBG_type in -lcrypto" >&5 printf %s "checking for RAND_set_DRBG_type in -lcrypto... " >&6; } if test ${ac_cv_lib_crypto_RAND_set_DRBG_type+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypto $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char RAND_set_DRBG_type (); int main (void) { return RAND_set_DRBG_type (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_crypto_RAND_set_DRBG_type=yes else $as_nop ac_cv_lib_crypto_RAND_set_DRBG_type=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_RAND_set_DRBG_type" >&5 printf "%s\n" "$ac_cv_lib_crypto_RAND_set_DRBG_type" >&6; } if test "x$ac_cv_lib_crypto_RAND_set_DRBG_type" = xyes then : HAVE_RAND_SET_DRBG_TYPE=1 fi else ssl=no certauth=no fi printf "%s\n" "#define HAVE_OPENSSL $HAVE_OPENSSL" >>confdefs.h printf "%s\n" "#define HAVE_RAND_SET_DRBG_TYPE $HAVE_RAND_SET_DRBG_TYPE" >>confdefs.h # Check whether --with-ssl was given. if test ${with_ssl+y} then : withval=$with_ssl; if test "x$withval" = "xyes"; then ssl=yes elif test "x$withval" = "xdynamic"; then ssl=dynamic elif test "x$withval" = "xno"; then ssl=no fi fi BUILTIN_SSL=0 DYNAMIC_SSL= case $ssl in yes) if test $HAVE_OPENSSL = 0; then as_fn_error $? "\"ssl enabled but openssl not found\"" "$LINENO" 5 fi BUILTIN_GENSIOS="$BUILTIN_GENSIOS ssl" BUILTIN_SSL=1 ;; dynamic) if test $HAVE_OPENSSL = 0; then as_fn_error $? "\"ssl enabled but openssl not found\"" "$LINENO" 5 fi DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS ssl" DYNAMIC_SSL=libgensio_ssl.la ;; no) ;; esac if test ${BUILTIN_SSL} = 1; then BUILTIN_SSL_TRUE= BUILTIN_SSL_FALSE='#' else BUILTIN_SSL_TRUE='#' BUILTIN_SSL_FALSE= fi # Check whether --with-certauth was given. if test ${with_certauth+y} then : withval=$with_certauth; if test "x$withval" = "xyes"; then certauth=yes elif test "x$withval" = "xdynamic"; then certauth=dynamic elif test "x$withval" = "xno"; then certauth=no fi fi BUILTIN_CERTAUTH=0 DYNAMIC_CERTAUTH= case $certauth in yes) if test $HAVE_OPENCERTAUTH = 0; then as_fn_error $? "\"certauth enabled but openssl not found\"" "$LINENO" 5 fi BUILTIN_GENSIOS="$BUILTIN_GENSIOS certauth" BUILTIN_CERTAUTH=1 ;; dynamic) if test $HAVE_OPENSSL = 0; then as_fn_error $? "\"certauth enabled but openssl not found\"" "$LINENO" 5 fi DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS certauth" DYNAMIC_CERTAUTH=libgensio_certauth.la ;; no) ;; esac if test ${BUILTIN_CERTAUTH} = 1; then BUILTIN_CERTAUTH_TRUE= BUILTIN_CERTAUTH_FALSE='#' else BUILTIN_CERTAUTH_TRUE='#' BUILTIN_CERTAUTH_FALSE= fi if test $ssl = yes -o $certauth = yes -o $link_ssl_with_main = yes; then BASE_LIBS="$BASE_LIBS $OPENSSL_LIBS" LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS" fi mux=$default_all # Check whether --with-mux was given. if test ${with_mux+y} then : withval=$with_mux; if test "x$withval" = "xyes"; then mux=yes elif test "x$withval" = "xdynamic"; then mux=dynamic elif test "x$withval" = "xno"; then mux=no fi fi BUILTIN_MUX=0 DYNAMIC_MUX= case $mux in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS mux" BUILTIN_MUX=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS mux" DYNAMIC_MUX=libgensio_mux.la ;; no) ;; esac if test ${BUILTIN_MUX} = 1; then BUILTIN_MUX_TRUE= BUILTIN_MUX_FALSE='#' else BUILTIN_MUX_TRUE='#' BUILTIN_MUX_FALSE= fi telnet=$default_all # Check whether --with-telnet was given. if test ${with_telnet+y} then : withval=$with_telnet; if test "x$withval" = "xyes"; then telnet=yes elif test "x$withval" = "xdynamic"; then telnet=dynamic elif test "x$withval" = "xno"; then telnet=no fi fi BUILTIN_TELNET=0 DYNAMIC_TELNET= case $telnet in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS telnet" BUILTIN_TELNET=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS telnet" DYNAMIC_TELNET=libgensio_telnet.la ;; no) ;; esac if test ${BUILTIN_TELNET} = 1; then BUILTIN_TELNET_TRUE= BUILTIN_TELNET_FALSE='#' else BUILTIN_TELNET_TRUE='#' BUILTIN_TELNET_FALSE= fi msgdelim=$default_all # Check whether --with-msgdelim was given. if test ${with_msgdelim+y} then : withval=$with_msgdelim; if test "x$withval" = "xyes"; then msgdelim=yes elif test "x$withval" = "xdynamic"; then msgdelim=dynamic elif test "x$withval" = "xno"; then msgdelim=no fi fi BUILTIN_MSGDELIM=0 DYNAMIC_MSGDELIM= case $msgdelim in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS msgdelim" BUILTIN_MSGDELIM=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS msgdelim" DYNAMIC_MSGDELIM=libgensio_msgdelim.la ;; no) ;; esac if test ${BUILTIN_MSGDELIM} = 1; then BUILTIN_MSGDELIM_TRUE= BUILTIN_MSGDELIM_FALSE='#' else BUILTIN_MSGDELIM_TRUE='#' BUILTIN_MSGDELIM_FALSE= fi relpkt=$default_all # Check whether --with-relpkt was given. if test ${with_relpkt+y} then : withval=$with_relpkt; if test "x$withval" = "xyes"; then relpkt=yes elif test "x$withval" = "xdynamic"; then relpkt=dynamic elif test "x$withval" = "xno"; then relpkt=no fi fi BUILTIN_RELPKT=0 DYNAMIC_RELPKT= case $relpkt in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS relpkt" BUILTIN_RELPKT=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS relpkt" DYNAMIC_RELPKT=libgensio_relpkt.la ;; no) ;; esac if test ${BUILTIN_RELPKT} = 1; then BUILTIN_RELPKT_TRUE= BUILTIN_RELPKT_FALSE='#' else BUILTIN_RELPKT_TRUE='#' BUILTIN_RELPKT_FALSE= fi trace=$default_all # Check whether --with-trace was given. if test ${with_trace+y} then : withval=$with_trace; if test "x$withval" = "xyes"; then trace=yes elif test "x$withval" = "xdynamic"; then trace=dynamic elif test "x$withval" = "xno"; then trace=no fi fi BUILTIN_TRACE=0 DYNAMIC_TRACE= case $trace in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS trace" BUILTIN_TRACE=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS trace" DYNAMIC_TRACE=libgensio_trace.la ;; no) ;; esac if test ${BUILTIN_TRACE} = 1; then BUILTIN_TRACE_TRUE= BUILTIN_TRACE_FALSE='#' else BUILTIN_TRACE_TRUE='#' BUILTIN_TRACE_FALSE= fi perf=$default_all # Check whether --with-perf was given. if test ${with_perf+y} then : withval=$with_perf; if test "x$withval" = "xyes"; then perf=yes elif test "x$withval" = "xdynamic"; then perf=dynamic elif test "x$withval" = "xno"; then perf=no fi fi BUILTIN_PERF=0 DYNAMIC_PERF= case $perf in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS perf" BUILTIN_PERF=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS perf" DYNAMIC_PERF=libgensio_perf.la ;; no) ;; esac if test ${BUILTIN_PERF} = 1; then BUILTIN_PERF_TRUE= BUILTIN_PERF_FALSE='#' else BUILTIN_PERF_TRUE='#' BUILTIN_PERF_FALSE= fi kiss=$default_all # Check whether --with-kiss was given. if test ${with_kiss+y} then : withval=$with_kiss; if test "x$withval" = "xyes"; then kiss=yes elif test "x$withval" = "xdynamic"; then kiss=dynamic elif test "x$withval" = "xno"; then kiss=no fi fi BUILTIN_KISS=0 DYNAMIC_KISS= case $kiss in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS kiss" BUILTIN_KISS=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS kiss" DYNAMIC_KISS=libgensio_kiss.la ;; no) ;; esac if test ${BUILTIN_KISS} = 1; then BUILTIN_KISS_TRUE= BUILTIN_KISS_FALSE='#' else BUILTIN_KISS_TRUE='#' BUILTIN_KISS_FALSE= fi ax25=$default_all # Check whether --with-ax25 was given. if test ${with_ax25+y} then : withval=$with_ax25; if test "x$withval" = "xyes"; then ax25=yes elif test "x$withval" = "xdynamic"; then ax25=dynamic elif test "x$withval" = "xno"; then ax25=no fi fi BUILTIN_AX25=0 DYNAMIC_AX25= case $ax25 in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS ax25" BUILTIN_AX25=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS ax25" DYNAMIC_AX25=libgensio_ax25.la ;; no) ;; esac if test ${BUILTIN_AX25} = 1; then BUILTIN_AX25_TRUE= BUILTIN_AX25_FALSE='#' else BUILTIN_AX25_TRUE='#' BUILTIN_AX25_FALSE= fi xlt=$default_all # Check whether --with-xlt was given. if test ${with_xlt+y} then : withval=$with_xlt; if test "x$withval" = "xyes"; then xlt=yes elif test "x$withval" = "xdynamic"; then xlt=dynamic elif test "x$withval" = "xno"; then xlt=no fi fi BUILTIN_XLT=0 DYNAMIC_XLT= case $xlt in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS xlt" BUILTIN_XLT=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS xlt" DYNAMIC_XLT=libgensio_xlt.la ;; no) ;; esac if test ${BUILTIN_XLT} = 1; then BUILTIN_XLT_TRUE= BUILTIN_XLT_FALSE='#' else BUILTIN_XLT_TRUE='#' BUILTIN_XLT_FALSE= fi keepopen=$default_all # Check whether --with-keepopen was given. if test ${with_keepopen+y} then : withval=$with_keepopen; if test "x$withval" = "xyes"; then keepopen=yes elif test "x$withval" = "xdynamic"; then keepopen=dynamic elif test "x$withval" = "xno"; then keepopen=no fi fi BUILTIN_KEEPOPEN=0 DYNAMIC_KEEPOPEN= case $keepopen in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS keepopen" BUILTIN_KEEPOPEN=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS keepopen" DYNAMIC_KEEPOPEN=libgensio_keepopen.la ;; no) ;; esac if test ${BUILTIN_KEEPOPEN} = 1; then BUILTIN_KEEPOPEN_TRUE= BUILTIN_KEEPOPEN_FALSE='#' else BUILTIN_KEEPOPEN_TRUE='#' BUILTIN_KEEPOPEN_FALSE= fi script=$default_all # Check whether --with-script was given. if test ${with_script+y} then : withval=$with_script; if test "x$withval" = "xyes"; then script=yes elif test "x$withval" = "xdynamic"; then script=dynamic elif test "x$withval" = "xno"; then script=no fi fi BUILTIN_SCRIPT=0 DYNAMIC_SCRIPT= case $script in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS script" BUILTIN_SCRIPT=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS script" DYNAMIC_SCRIPT=libgensio_script.la ;; no) ;; esac if test ${BUILTIN_SCRIPT} = 1; then BUILTIN_SCRIPT_TRUE= BUILTIN_SCRIPT_FALSE='#' else BUILTIN_SCRIPT_TRUE='#' BUILTIN_SCRIPT_FALSE= fi ratelimit=$default_all # Check whether --with-ratelimit was given. if test ${with_ratelimit+y} then : withval=$with_ratelimit; if test "x$withval" = "xyes"; then ratelimit=yes elif test "x$withval" = "xdynamic"; then ratelimit=dynamic elif test "x$withval" = "xno"; then ratelimit=no fi fi BUILTIN_RATELIMIT=0 DYNAMIC_RATELIMIT= case $ratelimit in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS ratelimit" BUILTIN_RATELIMIT=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS ratelimit" DYNAMIC_RATELIMIT=libgensio_ratelimit.la ;; no) ;; esac if test ${BUILTIN_RATELIMIT} = 1; then BUILTIN_RATELIMIT_TRUE= BUILTIN_RATELIMIT_FALSE='#' else BUILTIN_RATELIMIT_TRUE='#' BUILTIN_RATELIMIT_FALSE= fi afskmdm=$default_all # Check whether --with-afskmdm was given. if test ${with_afskmdm+y} then : withval=$with_afskmdm; if test "x$withval" = "xyes"; then afskmdm=yes elif test "x$withval" = "xdynamic"; then afskmdm=dynamic elif test "x$withval" = "xno"; then afskmdm=no fi fi BUILTIN_AFSKMDM=0 DYNAMIC_AFSKMDM= case $afskmdm in yes) BUILTIN_GENSIOS="$BUILTIN_GENSIOS afskmdm" BUILTIN_AFSKMDM=1 ;; dynamic) DYNAMIC_GENSIOS="$DYNAMIC_GENSIOS afskmdm" DYNAMIC_AFSKMDM=libgensio_afskmdm.la ;; no) ;; esac if test ${BUILTIN_AFSKMDM} = 1; then BUILTIN_AFSKMDM_TRUE= BUILTIN_AFSKMDM_FALSE='#' else BUILTIN_AFSKMDM_TRUE='#' BUILTIN_AFSKMDM_FALSE= fi echo "creating builtin_gensios.h" rm -f "$ac_pwd/lib/builtin_gensios.h" if ! test -e "$ac_pwd/lib"; then mkdir "$ac_pwd/lib" fi echo "/* Do not edit, created by configure.h */" >"$ac_pwd/lib/builtin_gensios.h" for i in $BUILTIN_GENSIOS; do echo "INIT_GENSIO($i);" >>"$ac_pwd/lib/builtin_gensios.h" done tryswig=yes swigprog= # Check whether --with-swig was given. if test ${with_swig+y} then : withval=$with_swig; if test "x$withval" = "x"; then tryswig=yes elif test "x$withval" = "xyes"; then tryswig=yes elif test "x$withval" = "xno"; then tryswig=no else swigprog=$withval fi fi trypython=yes # Check whether --with-python was given. if test ${with_python+y} then : withval=$with_python; if test "x$withval" = "x"; then trypython=yes elif test "x$withval" = "xyes"; then trypython=yes elif test "x$withval" = "xno"; then trypython=no else pythonprog="$withval" trypython=yes fi fi # Check whether --with-pythoninstall was given. if test ${with_pythoninstall+y} then : withval=$with_pythoninstall; pythoninstalldir="$withval" fi # Check whether --with-pythoninstalllib was given. if test ${with_pythoninstalllib+y} then : withval=$with_pythoninstalllib; pythoninstalllibdir="$withval" fi # Check whether --with-pythoncflags was given. if test ${with_pythoncflags+y} then : withval=$with_pythoncflags; pythoncflags="$withval" fi # Check whether --with-pythonusepthreads was given. if test ${with_pythonusepthreads+y} then : withval=$with_pythonusepthreads; if test "x$withval" = "xyes"; then pythonusepthreads="yes" elif test "x$withval" = "xno"; then pythonusepthreads="no" elif test "x$withval" = "x"; then pythonusepthreads="yes" fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 printf %s "checking for library containing clock_gettime... " >&6; } if test ${ac_cv_search_clock_gettime+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char clock_gettime (); int main (void) { return clock_gettime (); ; return 0; } _ACEOF for ac_lib in '' rt posix4 do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_clock_gettime=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_clock_gettime+y} then : break fi done if test ${ac_cv_search_clock_gettime+y} then : else $as_nop ac_cv_search_clock_gettime=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5 printf "%s\n" "$ac_cv_search_clock_gettime" >&6; } ac_res=$ac_cv_search_clock_gettime if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi # Handle RS485 support { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC options needed to detect all undeclared functions" >&5 printf %s "checking for $CC options needed to detect all undeclared functions... " >&6; } if test ${ac_cv_c_undeclared_builtin_options+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_CFLAGS=$CFLAGS ac_cv_c_undeclared_builtin_options='cannot detect' for ac_arg in '' -fno-builtin; do CFLAGS="$ac_save_CFLAGS $ac_arg" # This test program should *not* compile successfully. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { (void) strchr; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop # This test program should compile successfully. # No library function is consistently available on # freestanding implementations, so test against a dummy # declaration. Include always-available headers on the # off chance that they somehow elicit warnings. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include extern void ac_decl (int, char *); int main (void) { (void) ac_decl (0, (char *) 0); (void) ac_decl; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : if test x"$ac_arg" = x then : ac_cv_c_undeclared_builtin_options='none needed' else $as_nop ac_cv_c_undeclared_builtin_options=$ac_arg fi break fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done CFLAGS=$ac_save_CFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5 printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; } case $ac_cv_c_undeclared_builtin_options in #( 'cannot detect') : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot make $CC report undeclared builtins See \`config.log' for more details" "$LINENO" 5; } ;; #( 'none needed') : ac_c_undeclared_builtin_options='' ;; #( *) : ac_c_undeclared_builtin_options=$ac_cv_c_undeclared_builtin_options ;; esac ac_fn_check_decl "$LINENO" "TIOCSRS485" "ac_cv_have_decl_TIOCSRS485" "#include " "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl_TIOCSRS485" = xyes then : ac_have_decl=1 else $as_nop ac_have_decl=0 fi printf "%s\n" "#define HAVE_DECL_TIOCSRS485 $ac_have_decl" >>confdefs.h # enable silent build # Check whether --enable-silent-rules was given. if test ${enable_silent_rules+y} then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 printf %s "checking whether $am_make supports nested variables... " >&6; } if test ${am_cv_make_support_nested_variables+y} then : printf %s "(cached) " >&6 else $as_nop if printf "%s\n" 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lnsl" >&5 printf %s "checking for main in -lnsl... " >&6; } if test ${ac_cv_lib_nsl_main+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_nsl_main=yes else $as_nop ac_cv_lib_nsl_main=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_main" >&5 printf "%s\n" "$ac_cv_lib_nsl_main" >&6; } if test "x$ac_cv_lib_nsl_main" = xyes then : HAVE_LIBNSL=1; OSH_LIBS="-lnsl $OSH_LIBS" fi # Now check for swig SWIG_DIR= SWIG_CPP_DIR= SWIG= available_swig_vernum=0 if test "x$tryswig" = "xyes"; then if test "x$swigprog" != "x"; then SWIG="$swigprog" fi # Find path to the "swig" executable. for ac_prog in swig swig3.0 swig2.0 do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_SWIG+y} then : printf %s "(cached) " >&6 else $as_nop case $SWIG in [\\/]* | ?:[\\/]*) ac_cv_path_SWIG="$SWIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_SWIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi SWIG=$ac_cv_path_SWIG if test -n "$SWIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SWIG" >&5 printf "%s\n" "$SWIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$SWIG" && break done if test -z "$SWIG" ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 4.1.0 is required for C++ swig." >&5 printf "%s\n" "$as_me: WARNING: SWIG version >= 4.1.0 is required for C++ swig." >&2;} # Find path to the "swig" executable. for ac_prog in swig swig3.0 swig2.0 do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_SWIG+y} then : printf %s "(cached) " >&6 else $as_nop case $SWIG in [\\/]* | ?:[\\/]*) ac_cv_path_SWIG="$SWIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_SWIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi SWIG=$ac_cv_path_SWIG if test -n "$SWIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SWIG" >&5 printf "%s\n" "$SWIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$SWIG" && break done if test -z "$SWIG" ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 4.0.0 is required for C swig." >&5 printf "%s\n" "$as_me: WARNING: SWIG version >= 4.0.0 is required for C swig." >&2;} elif test -z "4.0.0" ; then printf "%s\n" "#define HAVE_SWIG /**/" >>confdefs.h SWIG_DIR=swig else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking SWIG version" >&5 printf %s "checking SWIG version... " >&6; } swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $swig_version" >&5 printf "%s\n" "$swig_version" >&6; } if test -n "$swig_version" ; then # Calculate the required version number components required=4.0.0 required_major=`echo $required | sed 's/[^0-9].*//'` if test -z "$required_major" ; then required_major=0 fi required=`echo $required. | sed 's/[0-9]*[^0-9]//'` required_minor=`echo $required | sed 's/[^0-9].*//'` if test -z "$required_minor" ; then required_minor=0 fi required=`echo $required. | sed 's/[0-9]*[^0-9]//'` required_patch=`echo $required | sed 's/[^0-9].*//'` if test -z "$required_patch" ; then required_patch=0 fi # Calculate the available version number components available=$swig_version available_major=`echo $available | sed 's/[^0-9].*//'` if test -z "$available_major" ; then available_major=0 fi available=`echo $available | sed 's/[0-9]*[^0-9]//'` available_minor=`echo $available | sed 's/[^0-9].*//'` if test -z "$available_minor" ; then available_minor=0 fi available=`echo $available | sed 's/[0-9]*[^0-9]//'` available_patch=`echo $available | sed 's/[^0-9].*//'` if test -z "$available_patch" ; then available_patch=0 fi # Convert the version tuple into a single number for easier comparison. # Using base 100 should be safe since SWIG internally uses BCD values # to encode its version number. required_swig_vernum=`expr $required_major \* 10000 \ \+ $required_minor \* 100 \+ $required_patch` available_swig_vernum=`expr $available_major \* 10000 \ \+ $available_minor \* 100 \+ $available_patch` if test $available_swig_vernum -lt $required_swig_vernum; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 4.0.0 is required. You have $swig_version." >&5 printf "%s\n" "$as_me: WARNING: SWIG version >= 4.0.0 is required. You have $swig_version." >&2;} SWIG='' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 4.0.0 is required for C swig." >&5 printf "%s\n" "$as_me: WARNING: SWIG version >= 4.0.0 is required for C swig." >&2;} else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SWIG library" >&5 printf %s "checking for SWIG library... " >&6; } SWIG_LIB=`$SWIG -swiglib | tr '\r\n' ' '` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SWIG_LIB" >&5 printf "%s\n" "$SWIG_LIB" >&6; } printf "%s\n" "#define HAVE_SWIG /**/" >>confdefs.h SWIG_DIR=swig fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine SWIG version" >&5 printf "%s\n" "$as_me: WARNING: cannot determine SWIG version" >&2;} SWIG='' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 4.0.0 is required for C swig." >&5 printf "%s\n" "$as_me: WARNING: SWIG version >= 4.0.0 is required for C swig." >&2;} fi fi elif test -z "4.1.0" ; then printf "%s\n" "#define HAVE_SWIG /**/" >>confdefs.h SWIG_DIR=swig SWIG_CPP_DIR=swig else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking SWIG version" >&5 printf %s "checking SWIG version... " >&6; } swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $swig_version" >&5 printf "%s\n" "$swig_version" >&6; } if test -n "$swig_version" ; then # Calculate the required version number components required=4.1.0 required_major=`echo $required | sed 's/[^0-9].*//'` if test -z "$required_major" ; then required_major=0 fi required=`echo $required. | sed 's/[0-9]*[^0-9]//'` required_minor=`echo $required | sed 's/[^0-9].*//'` if test -z "$required_minor" ; then required_minor=0 fi required=`echo $required. | sed 's/[0-9]*[^0-9]//'` required_patch=`echo $required | sed 's/[^0-9].*//'` if test -z "$required_patch" ; then required_patch=0 fi # Calculate the available version number components available=$swig_version available_major=`echo $available | sed 's/[^0-9].*//'` if test -z "$available_major" ; then available_major=0 fi available=`echo $available | sed 's/[0-9]*[^0-9]//'` available_minor=`echo $available | sed 's/[^0-9].*//'` if test -z "$available_minor" ; then available_minor=0 fi available=`echo $available | sed 's/[0-9]*[^0-9]//'` available_patch=`echo $available | sed 's/[^0-9].*//'` if test -z "$available_patch" ; then available_patch=0 fi # Convert the version tuple into a single number for easier comparison. # Using base 100 should be safe since SWIG internally uses BCD values # to encode its version number. required_swig_vernum=`expr $required_major \* 10000 \ \+ $required_minor \* 100 \+ $required_patch` available_swig_vernum=`expr $available_major \* 10000 \ \+ $available_minor \* 100 \+ $available_patch` if test $available_swig_vernum -lt $required_swig_vernum; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 4.1.0 is required. You have $swig_version." >&5 printf "%s\n" "$as_me: WARNING: SWIG version >= 4.1.0 is required. You have $swig_version." >&2;} SWIG='' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 4.1.0 is required for C++ swig." >&5 printf "%s\n" "$as_me: WARNING: SWIG version >= 4.1.0 is required for C++ swig." >&2;} # Find path to the "swig" executable. for ac_prog in swig swig3.0 swig2.0 do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_SWIG+y} then : printf %s "(cached) " >&6 else $as_nop case $SWIG in [\\/]* | ?:[\\/]*) ac_cv_path_SWIG="$SWIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_SWIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi SWIG=$ac_cv_path_SWIG if test -n "$SWIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SWIG" >&5 printf "%s\n" "$SWIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$SWIG" && break done if test -z "$SWIG" ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 4.0.0 is required for C swig." >&5 printf "%s\n" "$as_me: WARNING: SWIG version >= 4.0.0 is required for C swig." >&2;} elif test -z "4.0.0" ; then printf "%s\n" "#define HAVE_SWIG /**/" >>confdefs.h SWIG_DIR=swig else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking SWIG version" >&5 printf %s "checking SWIG version... " >&6; } swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $swig_version" >&5 printf "%s\n" "$swig_version" >&6; } if test -n "$swig_version" ; then # Calculate the required version number components required=4.0.0 required_major=`echo $required | sed 's/[^0-9].*//'` if test -z "$required_major" ; then required_major=0 fi required=`echo $required. | sed 's/[0-9]*[^0-9]//'` required_minor=`echo $required | sed 's/[^0-9].*//'` if test -z "$required_minor" ; then required_minor=0 fi required=`echo $required. | sed 's/[0-9]*[^0-9]//'` required_patch=`echo $required | sed 's/[^0-9].*//'` if test -z "$required_patch" ; then required_patch=0 fi # Calculate the available version number components available=$swig_version available_major=`echo $available | sed 's/[^0-9].*//'` if test -z "$available_major" ; then available_major=0 fi available=`echo $available | sed 's/[0-9]*[^0-9]//'` available_minor=`echo $available | sed 's/[^0-9].*//'` if test -z "$available_minor" ; then available_minor=0 fi available=`echo $available | sed 's/[0-9]*[^0-9]//'` available_patch=`echo $available | sed 's/[^0-9].*//'` if test -z "$available_patch" ; then available_patch=0 fi # Convert the version tuple into a single number for easier comparison. # Using base 100 should be safe since SWIG internally uses BCD values # to encode its version number. required_swig_vernum=`expr $required_major \* 10000 \ \+ $required_minor \* 100 \+ $required_patch` available_swig_vernum=`expr $available_major \* 10000 \ \+ $available_minor \* 100 \+ $available_patch` if test $available_swig_vernum -lt $required_swig_vernum; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 4.0.0 is required. You have $swig_version." >&5 printf "%s\n" "$as_me: WARNING: SWIG version >= 4.0.0 is required. You have $swig_version." >&2;} SWIG='' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 4.0.0 is required for C swig." >&5 printf "%s\n" "$as_me: WARNING: SWIG version >= 4.0.0 is required for C swig." >&2;} else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SWIG library" >&5 printf %s "checking for SWIG library... " >&6; } SWIG_LIB=`$SWIG -swiglib | tr '\r\n' ' '` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SWIG_LIB" >&5 printf "%s\n" "$SWIG_LIB" >&6; } printf "%s\n" "#define HAVE_SWIG /**/" >>confdefs.h SWIG_DIR=swig fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine SWIG version" >&5 printf "%s\n" "$as_me: WARNING: cannot determine SWIG version" >&2;} SWIG='' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 4.0.0 is required for C swig." >&5 printf "%s\n" "$as_me: WARNING: SWIG version >= 4.0.0 is required for C swig." >&2;} fi fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SWIG library" >&5 printf %s "checking for SWIG library... " >&6; } SWIG_LIB=`$SWIG -swiglib | tr '\r\n' ' '` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SWIG_LIB" >&5 printf "%s\n" "$SWIG_LIB" >&6; } printf "%s\n" "#define HAVE_SWIG /**/" >>confdefs.h SWIG_DIR=swig SWIG_CPP_DIR=swig fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine SWIG version" >&5 printf "%s\n" "$as_me: WARNING: cannot determine SWIG version" >&2;} SWIG='' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 4.1.0 is required for C++ swig." >&5 printf "%s\n" "$as_me: WARNING: SWIG version >= 4.1.0 is required for C++ swig." >&2;} # Find path to the "swig" executable. for ac_prog in swig swig3.0 swig2.0 do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_SWIG+y} then : printf %s "(cached) " >&6 else $as_nop case $SWIG in [\\/]* | ?:[\\/]*) ac_cv_path_SWIG="$SWIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_SWIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi SWIG=$ac_cv_path_SWIG if test -n "$SWIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SWIG" >&5 printf "%s\n" "$SWIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$SWIG" && break done if test -z "$SWIG" ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 4.0.0 is required for C swig." >&5 printf "%s\n" "$as_me: WARNING: SWIG version >= 4.0.0 is required for C swig." >&2;} elif test -z "4.0.0" ; then printf "%s\n" "#define HAVE_SWIG /**/" >>confdefs.h SWIG_DIR=swig else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking SWIG version" >&5 printf %s "checking SWIG version... " >&6; } swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $swig_version" >&5 printf "%s\n" "$swig_version" >&6; } if test -n "$swig_version" ; then # Calculate the required version number components required=4.0.0 required_major=`echo $required | sed 's/[^0-9].*//'` if test -z "$required_major" ; then required_major=0 fi required=`echo $required. | sed 's/[0-9]*[^0-9]//'` required_minor=`echo $required | sed 's/[^0-9].*//'` if test -z "$required_minor" ; then required_minor=0 fi required=`echo $required. | sed 's/[0-9]*[^0-9]//'` required_patch=`echo $required | sed 's/[^0-9].*//'` if test -z "$required_patch" ; then required_patch=0 fi # Calculate the available version number components available=$swig_version available_major=`echo $available | sed 's/[^0-9].*//'` if test -z "$available_major" ; then available_major=0 fi available=`echo $available | sed 's/[0-9]*[^0-9]//'` available_minor=`echo $available | sed 's/[^0-9].*//'` if test -z "$available_minor" ; then available_minor=0 fi available=`echo $available | sed 's/[0-9]*[^0-9]//'` available_patch=`echo $available | sed 's/[^0-9].*//'` if test -z "$available_patch" ; then available_patch=0 fi # Convert the version tuple into a single number for easier comparison. # Using base 100 should be safe since SWIG internally uses BCD values # to encode its version number. required_swig_vernum=`expr $required_major \* 10000 \ \+ $required_minor \* 100 \+ $required_patch` available_swig_vernum=`expr $available_major \* 10000 \ \+ $available_minor \* 100 \+ $available_patch` if test $available_swig_vernum -lt $required_swig_vernum; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 4.0.0 is required. You have $swig_version." >&5 printf "%s\n" "$as_me: WARNING: SWIG version >= 4.0.0 is required. You have $swig_version." >&2;} SWIG='' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 4.0.0 is required for C swig." >&5 printf "%s\n" "$as_me: WARNING: SWIG version >= 4.0.0 is required for C swig." >&2;} else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SWIG library" >&5 printf %s "checking for SWIG library... " >&6; } SWIG_LIB=`$SWIG -swiglib | tr '\r\n' ' '` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SWIG_LIB" >&5 printf "%s\n" "$SWIG_LIB" >&6; } printf "%s\n" "#define HAVE_SWIG /**/" >>confdefs.h SWIG_DIR=swig fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine SWIG version" >&5 printf "%s\n" "$as_me: WARNING: cannot determine SWIG version" >&2;} SWIG='' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 4.0.0 is required for C swig." >&5 printf "%s\n" "$as_me: WARNING: SWIG version >= 4.0.0 is required for C swig." >&2;} fi fi fi fi fi # Handle PYTHON support PYTHON_DIR= PYGENSIO_DIR= PYTHON_INSTALL_DIR= PYTHON_INSTALL_LIB_DIR= PYTHON_SWIG_FLAGS= if test "x$trypython" = "xyes"; then if test "x$pythonprog" != "x"; then PYTHON="$pythonprog" else if test -z "$PYTHON_VERSION"; then # Extract the first word of "python3", so it can be a program name with args. set dummy python3; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_PYTHON+y} then : printf %s "(cached) " >&6 else $as_nop case $PYTHON in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTHON=$ac_cv_path_PYTHON if test -n "$PYTHON"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 printf "%s\n" "$PYTHON" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test ! -z "$PYTHON"; then PYTHON_VERSION="3" fi fi fi if test "x$pythoncflags" != "x"; then PYTHON_CPPFLAGS="$pythoncflags" fi # Get whether it's optional if test -z "true"; then ax_python_devel_optional=false else ax_python_devel_optional=true fi ax_python_devel_found=yes # # Allow the use of a (user set) custom python version # # Extract the first word of "python[$PYTHON_VERSION]", so it can be a program name with args. set dummy python$PYTHON_VERSION; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_PYTHON+y} then : printf %s "(cached) " >&6 else $as_nop case $PYTHON in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTHON=$ac_cv_path_PYTHON if test -n "$PYTHON"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 printf "%s\n" "$PYTHON" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test -z "$PYTHON"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find python$PYTHON_VERSION in your system path" >&5 printf "%s\n" "$as_me: WARNING: Cannot find python$PYTHON_VERSION in your system path" >&2;} if ! $ax_python_devel_optional; then as_fn_error $? "Giving up, python development not available" "$LINENO" 5 fi ax_python_devel_found=no PYTHON_VERSION="" fi if test $ax_python_devel_found = yes; then # # Check for a version of Python >= 2.1.0 # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a version of Python >= '2.1.0'" >&5 printf %s "checking for a version of Python >= '2.1.0'... " >&6; } ac_supports_python_ver=`$PYTHON -c "import sys; \ ver = sys.version.split ()[0]; \ print (ver >= '2.1.0')"` if test "$ac_supports_python_ver" != "True"; then if test -z "$PYTHON_NOVERSIONCHECK"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: This version of the AC_PYTHON_DEVEL macro doesn't work properly with versions of Python before 2.1.0. You may need to re-run configure, setting the variables PYTHON_CPPFLAGS, PYTHON_LIBS, PYTHON_SITE_PKG, PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand. Moreover, to disable this check, set PYTHON_NOVERSIONCHECK to something else than an empty string. " >&5 printf "%s\n" "$as_me: WARNING: This version of the AC_PYTHON_DEVEL macro doesn't work properly with versions of Python before 2.1.0. You may need to re-run configure, setting the variables PYTHON_CPPFLAGS, PYTHON_LIBS, PYTHON_SITE_PKG, PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand. Moreover, to disable this check, set PYTHON_NOVERSIONCHECK to something else than an empty string. " >&2;} if ! $ax_python_devel_optional; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Giving up See \`config.log' for more details" "$LINENO" 5; } fi ax_python_devel_found=no PYTHON_VERSION="" else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: skip at user request" >&5 printf "%s\n" "skip at user request" >&6; } fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi fi if test $ax_python_devel_found = yes; then # # If the macro parameter ``version'' is set, honour it. # A Python shim class, VPy, is used to implement correct version comparisons via # string expressions, since e.g. a naive textual ">= 2.7.3" won't work for # Python 2.7.10 (the ".1" being evaluated as less than ".3"). # if test -n ""; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a version of Python " >&5 printf %s "checking for a version of Python ... " >&6; } cat << EOF > ax_python_devel_vpy.py class VPy: def vtup(self, s): return tuple(map(int, s.strip().replace("rc", ".").split("."))) def __init__(self): import sys self.vpy = tuple(sys.version_info)[:3] def __eq__(self, s): return self.vpy == self.vtup(s) def __ne__(self, s): return self.vpy != self.vtup(s) def __lt__(self, s): return self.vpy < self.vtup(s) def __gt__(self, s): return self.vpy > self.vtup(s) def __le__(self, s): return self.vpy <= self.vtup(s) def __ge__(self, s): return self.vpy >= self.vtup(s) EOF ac_supports_python_ver=`$PYTHON -c "import ax_python_devel_vpy; \ ver = ax_python_devel_vpy.VPy(); \ print (ver )"` rm -rf ax_python_devel_vpy*.py* __pycache__/ax_python_devel_vpy*.py* if test "$ac_supports_python_ver" = "True"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: this package requires Python . If you have it installed, but it isn't the default Python interpreter in your system path, please pass the PYTHON_VERSION variable to configure. See \`\`configure --help'' for reference. " >&5 printf "%s\n" "$as_me: WARNING: this package requires Python . If you have it installed, but it isn't the default Python interpreter in your system path, please pass the PYTHON_VERSION variable to configure. See \`\`configure --help'' for reference. " >&2;} if ! $ax_python_devel_optional; then as_fn_error $? "Giving up" "$LINENO" 5 fi ax_python_devel_found=no PYTHON_VERSION="" fi fi fi if test $ax_python_devel_found = yes; then # # Check if you have distutils, else fail # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the sysconfig Python package" >&5 printf %s "checking for the sysconfig Python package... " >&6; } ac_sysconfig_result=`$PYTHON -c "import sysconfig" 2>&1` if test $? -eq 0; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } IMPORT_SYSCONFIG="import sysconfig" else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the distutils Python package" >&5 printf %s "checking for the distutils Python package... " >&6; } ac_sysconfig_result=`$PYTHON -c "from distutils import sysconfig" 2>&1` if test $? -eq 0; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } IMPORT_SYSCONFIG="from distutils import sysconfig" else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cannot import Python module \"distutils\". Please check your Python installation. The error was: $ac_sysconfig_result" >&5 printf "%s\n" "$as_me: WARNING: cannot import Python module \"distutils\". Please check your Python installation. The error was: $ac_sysconfig_result" >&2;} if ! $ax_python_devel_optional; then as_fn_error $? "Giving up" "$LINENO" 5 fi ax_python_devel_found=no PYTHON_VERSION="" fi fi fi if test $ax_python_devel_found = yes; then # # Check for Python include path # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python include path" >&5 printf %s "checking for Python include path... " >&6; } if test -z "$PYTHON_CPPFLAGS"; then if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then # sysconfig module has different functions python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \ print (sysconfig.get_path ('include'));"` plat_python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \ print (sysconfig.get_path ('platinclude'));"` else # old distutils way python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \ print (sysconfig.get_python_inc ());"` plat_python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \ print (sysconfig.get_python_inc (plat_specific=1));"` fi if test -n "${python_path}"; then if test "${plat_python_path}" != "${python_path}"; then python_path="-I$python_path -I$plat_python_path" else python_path="-I$python_path" fi fi PYTHON_CPPFLAGS=$python_path fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_CPPFLAGS" >&5 printf "%s\n" "$PYTHON_CPPFLAGS" >&6; } # # Check for Python library path # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python library path" >&5 printf %s "checking for Python library path... " >&6; } if test -z "$PYTHON_LIBS"; then # (makes two attempts to ensure we've got a version number # from the interpreter) ac_python_version=`cat<>confdefs.h # First, the library directory: ac_python_libdir=`cat<&5 printf "%s\n" "$as_me: WARNING: Cannot determine location of your Python DSO. Please check it was installed with dynamic libraries enabled, or try setting PYTHON_LIBS by hand. " >&2;} if ! $ax_python_devel_optional; then as_fn_error $? "Giving up" "$LINENO" 5 fi ax_python_devel_found=no PYTHON_VERSION="" fi fi fi if test $ax_python_devel_found = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_LIBS" >&5 printf "%s\n" "$PYTHON_LIBS" >&6; } # # Check for site packages # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python site-packages path" >&5 printf %s "checking for Python site-packages path... " >&6; } if test -z "$PYTHON_SITE_PKG"; then if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then PYTHON_SITE_PKG=`$PYTHON -c " $IMPORT_SYSCONFIG; if hasattr(sysconfig, 'get_default_scheme'): scheme = sysconfig.get_default_scheme() else: scheme = sysconfig._get_default_scheme() if scheme == 'posix_local': # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/ scheme = 'posix_prefix' prefix = '$prefix' if prefix == 'NONE': prefix = '$ac_default_prefix' sitedir = sysconfig.get_path('purelib', scheme, vars={'base': prefix}) print(sitedir)"` else # distutils.sysconfig way PYTHON_SITE_PKG=`$PYTHON -c "$IMPORT_SYSCONFIG; \ print (sysconfig.get_python_lib(0,0));"` fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_SITE_PKG" >&5 printf "%s\n" "$PYTHON_SITE_PKG" >&6; } # # Check for platform-specific site packages # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python platform specific site-packages path" >&5 printf %s "checking for Python platform specific site-packages path... " >&6; } if test -z "$PYTHON_PLATFORM_SITE_PKG"; then if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then PYTHON_PLATFORM_SITE_PKG=`$PYTHON -c " $IMPORT_SYSCONFIG; if hasattr(sysconfig, 'get_default_scheme'): scheme = sysconfig.get_default_scheme() else: scheme = sysconfig._get_default_scheme() if scheme == 'posix_local': # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/ scheme = 'posix_prefix' prefix = '$prefix' if prefix == 'NONE': prefix = '$ac_default_prefix' sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase': prefix}) print(sitedir)"` else # distutils.sysconfig way PYTHON_PLATFORM_SITE_PKG=`$PYTHON -c "$IMPORT_SYSCONFIG; \ print (sysconfig.get_python_lib(1,0));"` fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_PLATFORM_SITE_PKG" >&5 printf "%s\n" "$PYTHON_PLATFORM_SITE_PKG" >&6; } # # libraries which must be linked in when embedding # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking python extra libraries" >&5 printf %s "checking python extra libraries... " >&6; } if test -z "$PYTHON_EXTRA_LIBS"; then PYTHON_EXTRA_LIBS=`$PYTHON -c "$IMPORT_SYSCONFIG; \ conf = sysconfig.get_config_var; \ print (conf('LIBS') + ' ' + conf('SYSLIBS'))"` fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_EXTRA_LIBS" >&5 printf "%s\n" "$PYTHON_EXTRA_LIBS" >&6; } # # linking flags needed when embedding # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking python extra linking flags" >&5 printf %s "checking python extra linking flags... " >&6; } if test -z "$PYTHON_EXTRA_LDFLAGS"; then PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "$IMPORT_SYSCONFIG; \ conf = sysconfig.get_config_var; \ print (conf('LINKFORSHARED'))"` # Hack for macos, it sticks this in here. PYTHON_EXTRA_LDFLAGS=`echo $PYTHON_EXTRA_LDFLAGS | sed 's/CoreFoundation.*$/CoreFoundation/'` fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_EXTRA_LDFLAGS" >&5 printf "%s\n" "$PYTHON_EXTRA_LDFLAGS" >&6; } # # final check to see if everything compiles alright # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking consistency of all components of python development environment" >&5 printf %s "checking consistency of all components of python development environment... " >&6; } # save current global flags ac_save_LIBS="$LIBS" ac_save_LDFLAGS="$LDFLAGS" ac_save_CPPFLAGS="$CPPFLAGS" LIBS="$ac_save_LIBS $PYTHON_LIBS $PYTHON_EXTRA_LIBS" LDFLAGS="$ac_save_LDFLAGS $PYTHON_EXTRA_LDFLAGS" CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { Py_Initialize(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : pythonexists=yes else $as_nop pythonexists=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # turn back to default flags CPPFLAGS="$ac_save_CPPFLAGS" LIBS="$ac_save_LIBS" LDFLAGS="$ac_save_LDFLAGS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $pythonexists" >&5 printf "%s\n" "$pythonexists" >&6; } if test ! "x$pythonexists" = "xyes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Could not link test program to Python. Maybe the main Python library has been installed in some non-standard library path. If so, pass it to configure, via the LIBS environment variable. Example: ./configure LIBS=\"-L/usr/non-standard-path/python/lib\" ============================================================================ ERROR! You probably have to install the development version of the Python package for your distribution. The exact name of this package varies among them. ============================================================================ " >&5 printf "%s\n" "$as_me: WARNING: Could not link test program to Python. Maybe the main Python library has been installed in some non-standard library path. If so, pass it to configure, via the LIBS environment variable. Example: ./configure LIBS=\"-L/usr/non-standard-path/python/lib\" ============================================================================ ERROR! You probably have to install the development version of the Python package for your distribution. The exact name of this package varies among them. ============================================================================ " >&2;} if ! $ax_python_devel_optional; then as_fn_error $? "Giving up" "$LINENO" 5 fi ax_python_devel_found=no PYTHON_VERSION="" fi fi # # all done! # else ax_python_devel_found=no fi if test $ax_python_devel_found = yes; then if test -n "$PYTHON" then : ax_python_version="3.0.0" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for python version" >&5 printf %s "checking for python version... " >&6; } python_version=`$PYTHON -V 2>&1 | $GREP "^Python " | $SED -e 's/^.* \([0-9]*\.[0-9]*\.[0-9]*\)/\1/'` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $python_version" >&5 printf "%s\n" "$python_version" >&6; } PYTHON_VERSION=$python_version # Used to indicate true or false condition ax_compare_version=false # Convert the two version strings to be compared into a format that # allows a simple string comparison. The end result is that a version # string of the form 1.12.5-r617 will be converted to the form # 0001001200050617. In other words, each number is zero padded to four # digits, and non digits are removed. ax_compare_version_A=`echo "$ax_python_version" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version_B=`echo "$python_version" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/[^0-9]//g'` ax_compare_version=`echo "x$ax_compare_version_A x$ax_compare_version_B" | sed 's/^ *//' | sort | sed "s/x${ax_compare_version_A}/true/;s/x${ax_compare_version_B}/false/;1q"` if test "$ax_compare_version" = "true" ; then : PYTHON_SWIG_FLAGS=-py3 PYGENSIO_DIR=pygensio else : fi else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: could not find the python interpreter" >&5 printf "%s\n" "$as_me: WARNING: could not find the python interpreter" >&2;} fi PYTHON_DIR=python if test "x$pythoninstalldir" = "x"; then PYTHON_INSTALL_DIR="$PYTHON_SITE_PKG" else PYTHON_INSTALL_DIR="$pythoninstalldir" fi if test "x$pythoninstalllibdir" = "x"; then PYTHON_INSTALL_LIB_DIR="$PYTHON_INSTALL_DIR" else PYTHON_INSTALL_LIB_DIR="$pythoninstalllibdir" fi if test "x$pythonusepthreads" = "x"; then cat - <<_ACEOF >conftest.py try: import threading print('yes') except: print('no') _ACEOF pythonusepthreads=`$PYTHON conftest.py` rm -f conftest.py fi echo "checking for python threads... $pythonusepthreads" if test "x$pythonusepthreads" = "xyes"; then PYTHON_HAS_THREADS=1 else PYTHON_HAS_THREADS=0 fi fi PYTHON_UNDEF_LIBS= if test $PYTHON_UNDEF_FLAG = "-no-undefined"; then PYTHON_UNDEF_LIBS="$PYTHON_LIBS" fi PYTHON_EXECUTABLE="${PYTHON}" if test $available_swig_vernum -ge 40100 -a "${enable_shared}" = yes -a $DISABLE_GO != yes; then trygo=yes else trygo=no fi GOPROG= # Check whether --with-go was given. if test ${with_go+y} then : withval=$with_go; if test "x$withval" = "x"; then trygo=yes elif test "x$withval" = "xyes"; then trygo=yes elif test "x$withval" = "xno"; then trygo=no else GOPROG="$withval" trygo=yes fi fi if test $trygo = yes -a $available_swig_vernum -lt 40100; then as_fn_error $? "Go enabled, but swig version must be >= 4.1.0 for that" "$LINENO" 5 fi GODIR= if test $trygo = yes; then if test "x$GOPROG" = "x"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}go", so it can be a program name with args. set dummy ${ac_tool_prefix}go; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_GOPROG+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$GOPROG"; then ac_cv_prog_GOPROG="$GOPROG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_GOPROG="${ac_tool_prefix}go" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi GOPROG=$ac_cv_prog_GOPROG if test -n "$GOPROG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $GOPROG" >&5 printf "%s\n" "$GOPROG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_GOPROG"; then ac_ct_GOPROG=$GOPROG # Extract the first word of "go", so it can be a program name with args. set dummy go; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_GOPROG+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_GOPROG"; then ac_cv_prog_ac_ct_GOPROG="$ac_ct_GOPROG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_GOPROG="go" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_GOPROG=$ac_cv_prog_ac_ct_GOPROG if test -n "$ac_ct_GOPROG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_GOPROG" >&5 printf "%s\n" "$ac_ct_GOPROG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_GOPROG" = x; then GOPROG="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac GOPROG=$ac_ct_GOPROG fi else GOPROG="$ac_cv_prog_GOPROG" fi fi fi if test "x$GOPROG" != "x"; then printf "%s\n" "#define HAVE_GO /**/" >>confdefs.h GO_DIR=go fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pam_start in -lpam" >&5 printf %s "checking for pam_start in -lpam... " >&6; } if test ${ac_cv_lib_pam_pam_start+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lpam $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char pam_start (); int main (void) { return pam_start (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_pam_pam_start=yes else $as_nop ac_cv_lib_pam_pam_start=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pam_pam_start" >&5 printf "%s\n" "$ac_cv_lib_pam_pam_start" >&6; } if test "x$ac_cv_lib_pam_pam_start" = xyes then : HAVE_PAM=1 else $as_nop HAVE_PAM=0 fi if test $HAVE_PAM -eq 1; then printf "%s\n" "#define HAVE_LIBPAM 1" >>confdefs.h PAMLIB=-lpam fi # python annoyingly defined HAVE_GETRANDOM ac_fn_c_check_func "$LINENO" "getrandom" "ac_cv_func_getrandom" if test "x$ac_cv_func_getrandom" = xyes then : printf "%s\n" "#define HAVE_GETRANDOM_FUNC 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "ptsname_r" "ac_cv_func_ptsname_r" if test "x$ac_cv_func_ptsname_r" = xyes then : HAVE_PTSNAME_R=1 else $as_nop HAVE_PTSNAME_R=0 fi printf "%s\n" "#define HAVE_PTSNAME_R $HAVE_PTSNAME_R" >>confdefs.h ac_fn_c_check_func "$LINENO" "cfmakeraw" "ac_cv_func_cfmakeraw" if test "x$ac_cv_func_cfmakeraw" = xyes then : printf "%s\n" "#define HAVE_CFMAKERAW 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "signalfd" "ac_cv_func_signalfd" if test "x$ac_cv_func_signalfd" = xyes then : printf "%s\n" "#define HAVE_SIGNALFD 1" >>confdefs.h fi case $host_os in linux*) HAVE_WORKING_PORT0=1 ;; *) HAVE_WORKING_PORT0=0 ;; esac printf "%s\n" "#define HAVE_WORKING_PORT0 $HAVE_WORKING_PORT0" >>confdefs.h GTLSSH= GTLSSYNC= GTLSSHD= GTLSSH_KEYGEN= GTLSSHMAN= GTLSSYNCMAN= GTLSSHDMAN= GTLSSH_KEYGENMAN= if test $HAVE_OPENSSL -eq 1; then if test $DISABLE_GTLSSHD = yes; then echo "gltsshD disabled" elif test $HAVE_PAM -eq 1; then GTLSSHD="gtlsshd\$(EXEEXT)" GTLSSHDMAN=gtlsshd.8 elif test "$version_type" = "windows"; then GTLSSHD="gtlsshd\$(EXEEXT)" GTLSSHDMAN=gtlsshd.8 fi GTLSSH="gtlssh\$(EXEEXT)" GTLSSHMAN=gtlssh.1 if test ${system_type} = unix; then GTLSSYNC=gtlssync GTLSSYNCMAN=gtlssync.1 fi GTLSSH_KEYGEN="gtlssh-keygen\$(EXEEXT)" GTLSSH_KEYGENMAN=gtlssh-keygen.1 fi ac_fn_c_check_member "$LINENO" "struct termios2" "c_ispeed" "ac_cv_member_struct_termios2_c_ispeed" "#include " if test "x$ac_cv_member_struct_termios2_c_ispeed" = xyes then : printf "%s\n" "#define HAVE_TERMIOS2 1" >>confdefs.h fi # Check whether --enable-internal-trace was given. if test ${enable_internal_trace+y} then : enableval=$enable_internal_trace; case $enableval in "" | y | ye | yes) enable_internal_trace=yes ;; "" | n | no) enable_internal_trace=no ;; *) as_fn_error $? "Invalid --enable-internal-trace option" "$LINENO" 5 ;; esac else $as_nop enable_internal_trace=no fi if test "x$enable_internal_trace" != xno; then printf "%s\n" "#define ENABLE_INTERNAL_TRACE 1" >>confdefs.h ENABLE_INTERNAL_TRACE=1 else ENABLE_INTERNAL_TRACE=0 fi if test ${enable_internal_trace} != no; then ENABLE_INTERNAL_TRACE_TRUE= ENABLE_INTERNAL_TRACE_FALSE='#' else ENABLE_INTERNAL_TRACE_TRUE='#' ENABLE_INTERNAL_TRACE_FALSE= fi HAVE_UNIX=0 ac_fn_c_check_header_compile "$LINENO" "sys/un.h" "ac_cv_header_sys_un_h" "$ac_includes_default" if test "x$ac_cv_header_sys_un_h" = xyes then : HAVE_UNIX=1 fi printf "%s\n" "#define HAVE_UNIX $HAVE_UNIX" >>confdefs.h GENSIO_PTY_HELPER= if test "$version_type" = "windows" -a "$target_os" != "msys"; then # We have PTY support for windows. HAVE_PTY=1 GENSIO_PTY_HELPER="gensio_pty_helper\$(EXEEXT)" else HAVE_PTY=0 for ac_func in posix_openpt do : ac_fn_c_check_func "$LINENO" "posix_openpt" "ac_cv_func_posix_openpt" if test "x$ac_cv_func_posix_openpt" = xyes then : printf "%s\n" "#define HAVE_POSIX_OPENPT 1" >>confdefs.h HAVE_PTY=1 fi done fi printf "%s\n" "#define HAVE_PTY $HAVE_PTY" >>confdefs.h if test ${system_type} != windows; then HAVE_UNIX_OS_TRUE= HAVE_UNIX_OS_FALSE='#' else HAVE_UNIX_OS_TRUE='#' HAVE_UNIX_OS_FALSE= fi if test ${system_type} = windows; then HAVE_WINDOWS_OS_TRUE= HAVE_WINDOWS_OS_FALSE='#' else HAVE_WINDOWS_OS_TRUE='#' HAVE_WINDOWS_OS_FALSE= fi # Check whether --with-file-stdio was given. if test ${with_file_stdio+y} then : withval=$with_file_stdio; if test "x$withval" = "xyes"; then USE_FILE_STDIO=1 elif test "x$withval" = "xno"; then USE_FILE_STDIO=0 elif test "x$withval" = "x"; then USE_FILE_STDIO=1 fi fi printf "%s\n" "#define USE_FILE_STDIO $USE_FILE_STDIO" >>confdefs.h ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_fn_c_check_func "$LINENO" "sendmsg" "ac_cv_func_sendmsg" if test "x$ac_cv_func_sendmsg" = xyes then : printf "%s\n" "#define HAVE_SENDMSG 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "recvmsg" "ac_cv_func_recvmsg" if test "x$ac_cv_func_recvmsg" = xyes then : printf "%s\n" "#define HAVE_RECVMSG 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "isatty" "ac_cv_func_isatty" if test "x$ac_cv_func_isatty" = xyes then : printf "%s\n" "#define HAVE_ISATTY 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp" if test "x$ac_cv_func_strcasecmp" = xyes then : printf "%s\n" "#define HAVE_STRCASECMP 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "strncasecmp" "ac_cv_func_strncasecmp" if test "x$ac_cv_func_strncasecmp" = xyes then : printf "%s\n" "#define HAVE_STRNCASECMP 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "prctl" "ac_cv_func_prctl" if test "x$ac_cv_func_prctl" = xyes then : printf "%s\n" "#define HAVE_PRCTL 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "setutxent" "ac_cv_func_setutxent" if test "x$ac_cv_func_setutxent" = xyes then : printf "%s\n" "#define HAVE_SETUTXENT 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "sigtimedwait" "ac_cv_func_sigtimedwait" if test "x$ac_cv_func_sigtimedwait" = xyes then : printf "%s\n" "#define HAVE_SIGTIMEDWAIT 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "initgroups" "ac_cv_func_initgroups" if test "x$ac_cv_func_initgroups" = xyes then : printf "%s\n" "#define HAVE_INITGROUPS 1" >>confdefs.h fi ac_fn_check_decl "$LINENO" "SIGWINCH" "ac_cv_have_decl_SIGWINCH" "#include " "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl_SIGWINCH" = xyes then : ac_have_decl=1 else $as_nop ac_have_decl=0 fi printf "%s\n" "#define HAVE_DECL_SIGWINCH $ac_have_decl" >>confdefs.h AM_CXXFLAGS="$AM_CXXFLAGS $EXTRA_CFLAGS -I\$(top_srcdir)/c++/include" AM_CFLAGS="$AM_CFLAGS $EXTRA_CFLAGS" CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/include -I\$(top_builddir)/include" ac_config_files="$ac_config_files Makefile lib/libgensioosh.pc lib/libgensio.pc lib/libgensiomdns.pc lib/Makefile swig/Makefile swig/python/libgensio_python_swig.pc swig/python/Makefile swig/include/gensio/Makefile swig/include/Makefile c++/Makefile c++/include/Makefile c++/include/gensio/Makefile c++/lib/Makefile c++/lib/libgensiooshcpp.pc c++/lib/libgensiocpp.pc c++/lib/libgensiomdnscpp.pc c++/tests/Makefile c++/examples/Makefile c++/swig/Makefile c++/swig/include/Makefile c++/swig/pygensio/Makefile c++/swig/pygensio/include/Makefile c++/swig/pygensio/include/gensio/Makefile c++/swig/pygensio/tests/Makefile c++/swig/pygensio/tests/runtest c++/swig/go/Makefile c++/swig/go/gensio/Makefile c++/swig/go/examples/Makefile c++/swig/go/tests/Makefile c++/swig/go/tests/runtest c++/swig/go/tests/testbase/Makefile glib/libgensioglib.pc glib/Makefile glib/include/Makefile glib/include/gensio/Makefile glib/swig/Makefile glib/swig/python/Makefile glib/c++/Makefile glib/c++/include/Makefile glib/c++/include/gensio/Makefile glib/c++/tests/Makefile glib/c++/swig/Makefile glib/c++/swig/pygensio/Makefile tcl/libgensiotcl.pc tcl/Makefile tcl/include/Makefile tcl/include/gensio/Makefile tcl/swig/Makefile tcl/swig/python/Makefile tcl/c++/Makefile tcl/c++/include/Makefile tcl/c++/include/gensio/Makefile tcl/c++/tests/Makefile tcl/c++/swig/Makefile tcl/c++/swig/pygensio/Makefile include/Makefile include/gensio/Makefile include/gensio/gensio_version.h tests/Makefile tools/Makefile man/Makefile examples/Makefile tests/runtest tests/gensios_enabled.py tests/reflector.py" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 printf "%s\n" "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 printf %s "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 printf "%s\n" "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USE_GGL_INT_TRUE}" && test -z "${USE_GGL_INT_FALSE}"; then as_fn_error $? "conditional \"USE_GGL_INT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USE_OPENPTY_TRUE}" && test -z "${USE_OPENPTY_FALSE}"; then as_fn_error $? "conditional \"USE_OPENPTY\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USE_LOGIN_PROGRAM_TRUE}" && test -z "${USE_LOGIN_PROGRAM_FALSE}"; then as_fn_error $? "conditional \"USE_LOGIN_PROGRAM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_UCRED_TRUE}" && test -z "${HAVE_UCRED_FALSE}"; then as_fn_error $? "conditional \"HAVE_UCRED\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${INSTALL_DOC_TRUE}" && test -z "${INSTALL_DOC_FALSE}"; then as_fn_error $? "conditional \"INSTALL_DOC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_GLIB_TRUE}" && test -z "${HAVE_GLIB_FALSE}"; then as_fn_error $? "conditional \"HAVE_GLIB\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_NET_TRUE}" && test -z "${BUILTIN_NET_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_NET\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_DGRAM_TRUE}" && test -z "${BUILTIN_DGRAM_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_DGRAM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_SCTP_TRUE}" && test -z "${BUILTIN_SCTP_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_SCTP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_STDIO_TRUE}" && test -z "${BUILTIN_STDIO_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_STDIO\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_PTY_TRUE}" && test -z "${BUILTIN_PTY_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_PTY\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_DUMMY_TRUE}" && test -z "${BUILTIN_DUMMY_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_DUMMY\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_CONACC_TRUE}" && test -z "${BUILTIN_CONACC_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_CONACC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_SERIALDEV_TRUE}" && test -z "${BUILTIN_SERIALDEV_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_SERIALDEV\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_ECHO_TRUE}" && test -z "${BUILTIN_ECHO_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_ECHO\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_FILE_TRUE}" && test -z "${BUILTIN_FILE_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_FILE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_OPENIPMI_TRUE}" && test -z "${HAVE_OPENIPMI_FALSE}"; then as_fn_error $? "conditional \"HAVE_OPENIPMI\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_IPMISOL_TRUE}" && test -z "${BUILTIN_IPMISOL_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_IPMISOL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_AVAHI_TRUE}" && test -z "${HAVE_AVAHI_FALSE}"; then as_fn_error $? "conditional \"HAVE_AVAHI\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_DNSSD_TRUE}" && test -z "${HAVE_DNSSD_FALSE}"; then as_fn_error $? "conditional \"HAVE_DNSSD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_WINMDNS_TRUE}" && test -z "${HAVE_WINMDNS_FALSE}"; then as_fn_error $? "conditional \"HAVE_WINMDNS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_MDNS_TRUE}" && test -z "${HAVE_MDNS_FALSE}"; then as_fn_error $? "conditional \"HAVE_MDNS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_MDNS_TRUE}" && test -z "${BUILTIN_MDNS_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_MDNS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_SOUND_TRUE}" && test -z "${BUILTIN_SOUND_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_SOUND\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_CM108GPIO_TRUE}" && test -z "${BUILTIN_CM108GPIO_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_CM108GPIO\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_SSL_TRUE}" && test -z "${BUILTIN_SSL_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_SSL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_CERTAUTH_TRUE}" && test -z "${BUILTIN_CERTAUTH_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_CERTAUTH\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_MUX_TRUE}" && test -z "${BUILTIN_MUX_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_MUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_TELNET_TRUE}" && test -z "${BUILTIN_TELNET_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_TELNET\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_MSGDELIM_TRUE}" && test -z "${BUILTIN_MSGDELIM_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_MSGDELIM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_RELPKT_TRUE}" && test -z "${BUILTIN_RELPKT_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_RELPKT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_TRACE_TRUE}" && test -z "${BUILTIN_TRACE_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_TRACE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_PERF_TRUE}" && test -z "${BUILTIN_PERF_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_PERF\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_KISS_TRUE}" && test -z "${BUILTIN_KISS_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_KISS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_AX25_TRUE}" && test -z "${BUILTIN_AX25_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_AX25\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_XLT_TRUE}" && test -z "${BUILTIN_XLT_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_XLT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_KEEPOPEN_TRUE}" && test -z "${BUILTIN_KEEPOPEN_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_KEEPOPEN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_SCRIPT_TRUE}" && test -z "${BUILTIN_SCRIPT_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_SCRIPT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_RATELIMIT_TRUE}" && test -z "${BUILTIN_RATELIMIT_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_RATELIMIT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_AFSKMDM_TRUE}" && test -z "${BUILTIN_AFSKMDM_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_AFSKMDM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_INTERNAL_TRACE_TRUE}" && test -z "${ENABLE_INTERNAL_TRACE_FALSE}"; then as_fn_error $? "conditional \"ENABLE_INTERNAL_TRACE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_UNIX_OS_TRUE}" && test -z "${HAVE_UNIX_OS_FALSE}"; then as_fn_error $? "conditional \"HAVE_UNIX_OS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_WINDOWS_OS_TRUE}" && test -z "${HAVE_WINDOWS_OS_FALSE}"; then as_fn_error $? "conditional \"HAVE_WINDOWS_OS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by gensio $as_me 3.0.0, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ gensio config.status 3.0.0 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" Copyright (C) 2021 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) printf "%s\n" "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX printf "%s\n" "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' FILECMD='`$ECHO "$FILECMD" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ FILECMD \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ lt_cv_nm_interface \ nm_file_list_spec \ lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib \ compiler_lib_search_dirs \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ LD_CXX \ reload_flag_CXX \ compiler_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ lt_prog_compiler_pic_CXX \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_static_CXX \ lt_cv_prog_compiler_c_o_CXX \ export_dynamic_flag_spec_CXX \ whole_archive_flag_spec_CXX \ compiler_needs_object_CXX \ with_gnu_ld_CXX \ allow_undefined_flag_CXX \ no_undefined_flag_CXX \ hardcode_libdir_flag_spec_CXX \ hardcode_libdir_separator_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX \ file_list_spec_CXX \ compiler_lib_search_dirs_CXX \ predep_objects_CXX \ postdep_objects_CXX \ predeps_CXX \ postdeps_CXX \ compiler_lib_search_path_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ configure_time_dlsearch_path \ configure_time_lt_sys_library_path \ reload_cmds_CXX \ old_archive_cmds_CXX \ old_archive_from_new_cmds_CXX \ old_archive_from_expsyms_cmds_CXX \ archive_cmds_CXX \ archive_expsym_cmds_CXX \ module_cmds_CXX \ module_expsym_cmds_CXX \ export_symbols_cmds_CXX \ prelink_cmds_CXX \ postlink_cmds_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "lib/libgensioosh.pc") CONFIG_FILES="$CONFIG_FILES lib/libgensioosh.pc" ;; "lib/libgensio.pc") CONFIG_FILES="$CONFIG_FILES lib/libgensio.pc" ;; "lib/libgensiomdns.pc") CONFIG_FILES="$CONFIG_FILES lib/libgensiomdns.pc" ;; "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; "swig/Makefile") CONFIG_FILES="$CONFIG_FILES swig/Makefile" ;; "swig/python/libgensio_python_swig.pc") CONFIG_FILES="$CONFIG_FILES swig/python/libgensio_python_swig.pc" ;; "swig/python/Makefile") CONFIG_FILES="$CONFIG_FILES swig/python/Makefile" ;; "swig/include/gensio/Makefile") CONFIG_FILES="$CONFIG_FILES swig/include/gensio/Makefile" ;; "swig/include/Makefile") CONFIG_FILES="$CONFIG_FILES swig/include/Makefile" ;; "c++/Makefile") CONFIG_FILES="$CONFIG_FILES c++/Makefile" ;; "c++/include/Makefile") CONFIG_FILES="$CONFIG_FILES c++/include/Makefile" ;; "c++/include/gensio/Makefile") CONFIG_FILES="$CONFIG_FILES c++/include/gensio/Makefile" ;; "c++/lib/Makefile") CONFIG_FILES="$CONFIG_FILES c++/lib/Makefile" ;; "c++/lib/libgensiooshcpp.pc") CONFIG_FILES="$CONFIG_FILES c++/lib/libgensiooshcpp.pc" ;; "c++/lib/libgensiocpp.pc") CONFIG_FILES="$CONFIG_FILES c++/lib/libgensiocpp.pc" ;; "c++/lib/libgensiomdnscpp.pc") CONFIG_FILES="$CONFIG_FILES c++/lib/libgensiomdnscpp.pc" ;; "c++/tests/Makefile") CONFIG_FILES="$CONFIG_FILES c++/tests/Makefile" ;; "c++/examples/Makefile") CONFIG_FILES="$CONFIG_FILES c++/examples/Makefile" ;; "c++/swig/Makefile") CONFIG_FILES="$CONFIG_FILES c++/swig/Makefile" ;; "c++/swig/include/Makefile") CONFIG_FILES="$CONFIG_FILES c++/swig/include/Makefile" ;; "c++/swig/pygensio/Makefile") CONFIG_FILES="$CONFIG_FILES c++/swig/pygensio/Makefile" ;; "c++/swig/pygensio/include/Makefile") CONFIG_FILES="$CONFIG_FILES c++/swig/pygensio/include/Makefile" ;; "c++/swig/pygensio/include/gensio/Makefile") CONFIG_FILES="$CONFIG_FILES c++/swig/pygensio/include/gensio/Makefile" ;; "c++/swig/pygensio/tests/Makefile") CONFIG_FILES="$CONFIG_FILES c++/swig/pygensio/tests/Makefile" ;; "c++/swig/pygensio/tests/runtest") CONFIG_FILES="$CONFIG_FILES c++/swig/pygensio/tests/runtest" ;; "c++/swig/go/Makefile") CONFIG_FILES="$CONFIG_FILES c++/swig/go/Makefile" ;; "c++/swig/go/gensio/Makefile") CONFIG_FILES="$CONFIG_FILES c++/swig/go/gensio/Makefile" ;; "c++/swig/go/examples/Makefile") CONFIG_FILES="$CONFIG_FILES c++/swig/go/examples/Makefile" ;; "c++/swig/go/tests/Makefile") CONFIG_FILES="$CONFIG_FILES c++/swig/go/tests/Makefile" ;; "c++/swig/go/tests/runtest") CONFIG_FILES="$CONFIG_FILES c++/swig/go/tests/runtest" ;; "c++/swig/go/tests/testbase/Makefile") CONFIG_FILES="$CONFIG_FILES c++/swig/go/tests/testbase/Makefile" ;; "glib/libgensioglib.pc") CONFIG_FILES="$CONFIG_FILES glib/libgensioglib.pc" ;; "glib/Makefile") CONFIG_FILES="$CONFIG_FILES glib/Makefile" ;; "glib/include/Makefile") CONFIG_FILES="$CONFIG_FILES glib/include/Makefile" ;; "glib/include/gensio/Makefile") CONFIG_FILES="$CONFIG_FILES glib/include/gensio/Makefile" ;; "glib/swig/Makefile") CONFIG_FILES="$CONFIG_FILES glib/swig/Makefile" ;; "glib/swig/python/Makefile") CONFIG_FILES="$CONFIG_FILES glib/swig/python/Makefile" ;; "glib/c++/Makefile") CONFIG_FILES="$CONFIG_FILES glib/c++/Makefile" ;; "glib/c++/include/Makefile") CONFIG_FILES="$CONFIG_FILES glib/c++/include/Makefile" ;; "glib/c++/include/gensio/Makefile") CONFIG_FILES="$CONFIG_FILES glib/c++/include/gensio/Makefile" ;; "glib/c++/tests/Makefile") CONFIG_FILES="$CONFIG_FILES glib/c++/tests/Makefile" ;; "glib/c++/swig/Makefile") CONFIG_FILES="$CONFIG_FILES glib/c++/swig/Makefile" ;; "glib/c++/swig/pygensio/Makefile") CONFIG_FILES="$CONFIG_FILES glib/c++/swig/pygensio/Makefile" ;; "tcl/libgensiotcl.pc") CONFIG_FILES="$CONFIG_FILES tcl/libgensiotcl.pc" ;; "tcl/Makefile") CONFIG_FILES="$CONFIG_FILES tcl/Makefile" ;; "tcl/include/Makefile") CONFIG_FILES="$CONFIG_FILES tcl/include/Makefile" ;; "tcl/include/gensio/Makefile") CONFIG_FILES="$CONFIG_FILES tcl/include/gensio/Makefile" ;; "tcl/swig/Makefile") CONFIG_FILES="$CONFIG_FILES tcl/swig/Makefile" ;; "tcl/swig/python/Makefile") CONFIG_FILES="$CONFIG_FILES tcl/swig/python/Makefile" ;; "tcl/c++/Makefile") CONFIG_FILES="$CONFIG_FILES tcl/c++/Makefile" ;; "tcl/c++/include/Makefile") CONFIG_FILES="$CONFIG_FILES tcl/c++/include/Makefile" ;; "tcl/c++/include/gensio/Makefile") CONFIG_FILES="$CONFIG_FILES tcl/c++/include/gensio/Makefile" ;; "tcl/c++/tests/Makefile") CONFIG_FILES="$CONFIG_FILES tcl/c++/tests/Makefile" ;; "tcl/c++/swig/Makefile") CONFIG_FILES="$CONFIG_FILES tcl/c++/swig/Makefile" ;; "tcl/c++/swig/pygensio/Makefile") CONFIG_FILES="$CONFIG_FILES tcl/c++/swig/pygensio/Makefile" ;; "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; "include/gensio/Makefile") CONFIG_FILES="$CONFIG_FILES include/gensio/Makefile" ;; "include/gensio/gensio_version.h") CONFIG_FILES="$CONFIG_FILES include/gensio/gensio_version.h" ;; "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;; "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;; "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; "tests/runtest") CONFIG_FILES="$CONFIG_FILES tests/runtest" ;; "tests/gensios_enabled.py") CONFIG_FILES="$CONFIG_FILES tests/gensios_enabled.py" ;; "tests/reflector.py") CONFIG_FILES="$CONFIG_FILES tests/reflector.py" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`printf "%s\n" "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 printf "%s\n" "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. case $CONFIG_FILES in #( *\'*) : eval set x "$CONFIG_FILES" ;; #( *) : set x $CONFIG_FILES ;; #( *) : ;; esac shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`printf "%s\n" "$am_mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`$as_dirname -- "$am_mf" || $as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$am_mf" : 'X\(//\)[^/]' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` am_filepart=`$as_basename -- "$am_mf" || $as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$am_mf" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` { echo "$as_me:$LINENO: cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles" >&5 (cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } || am_rc=$? done if test $am_rc -ne 0; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE=\"gmake\" (or whatever is necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking). See \`config.log' for more details" "$LINENO" 5; } fi { am_dirpart=; unset am_dirpart;} { am_filepart=; unset am_filepart;} { am_mf=; unset am_mf;} { am_rc=; unset am_rc;} rm -f conftest-deps.mk } ;; "libtool":C) # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # The names of the tagged configurations supported by this script. available_tags='CXX ' # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shared archive member basename,for filename based shared library versioning on AIX. shared_archive_member_spec=$shared_archive_member_spec # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # A file(cmd) program that detects file types. FILECMD=$lt_FILECMD # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive (by configure). lt_ar_flags=$lt_ar_flags # Flags to create an archive. AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"} # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm into a list of symbols to manually relocate. global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name lister interface. nm_interface=$lt_lt_cv_nm_interface # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # Command to truncate a binary pipe. lt_truncate_bin=$lt_lt_cv_truncate_bin # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Detected run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects postdep_objects=$lt_postdep_objects predeps=$lt_predeps postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" cat <<_LT_EOF >> "$ofile" # ### BEGIN LIBTOOL TAG CONFIG: CXX # The linker used to build libraries. LD=$lt_LD_CXX # How to create reloadable object files. reload_flag=$lt_reload_flag_CXX reload_cmds=$lt_reload_cmds_CXX # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds_CXX # A language specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU compiler? with_gcc=$GCC_CXX # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_CXX # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object_CXX # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds_CXX archive_expsym_cmds=$lt_archive_expsym_cmds_CXX # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds_CXX module_expsym_cmds=$lt_module_expsym_cmds_CXX # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld_CXX # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_CXX # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_CXX # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct_CXX # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute_CXX # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L_CXX # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic_CXX # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath_CXX # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols_CXX # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_CXX # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_CXX # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_CXX # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds_CXX # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds_CXX # Specify filename containing input files. file_list_spec=$lt_file_list_spec_CXX # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_CXX # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects_CXX postdep_objects=$lt_postdep_objects_CXX predeps=$lt_predeps_CXX postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX # ### END LIBTOOL TAG CONFIG: CXX _LT_EOF ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi pr_op() { #echo "A: '$1' $2" if test "x$2" = x1; then str='Yes' elif test "x$2" = "xyes"; then str='Yes' else str='no' fi echo "$1$str" } pr_vop() { #echo "A: '$1' $2" if test -n "$2"; then str=$2 else str='no' fi echo "$1$str" } prrw() { echo "$1$2" } echo "**************************************************" echo "Options:" pr_op " UUCP Locking: " $USE_UUCP_LOCKING pr_op " flock Locking: " $USE_FLOCK_LOCKING pr_op " Broken pselect(): " $broken_pselect pr_op " TCP Wrappers: " $ac_cv_header_tcpd_h prrw " Regular Expressions: " $ac_cv_func_regexec pr_op " Install Docs: " $enable_doc pr_op " epoll_pwait(): " $ax_config_feature_epoll_pwait pr_op " kevent(): " $ac_cv_func_kevent pr_op " pthreads: " $use_pthreads pr_op " c++11 " $HAVE_CXX11 pr_vop " pkgconfig: " $pkgprog pr_op " glib: " $haveglib pr_op " tcl: " $havetcl pr_op " shared libraries: " $enable_shared pr_op " sctp sendv: " $ac_cv_lib_sctp_sctp_sendv pr_vop " python: " "$ax_python_version" if test "$SWIG_CPP_DIR" = "swig"; then prrw " swig: " "$available_swig_vernum" else prrw " swig: " "no" fi pr_vop " go: " $GOPROG pr_op " pam: " $HAVE_PAM pr_op " internal trace: " $ENABLE_INTERNAL_TRACE pr_op " link ssl with main: " $link_ssl_with_main pr_op " alsa: " $HAVE_ALSA pr_op " win32 sound: " $HAVE_WIN32SOUND pr_op " portaudio: " $HAVE_PORTAUDIO echo echo "**************************************************" echo "Gensios:" echo " net: " $net echo " dgram: " $dgram echo " sctp: " $sctp echo " stdio: " $stdio echo " pty: " $pty echo " dummy: " $dummy echo " conacc: " $conacc echo " serialdev: " $serialdev echo " echo: " $echo echo " file: " $file echo " ipmisol: " $ipmisol echo " mdns: " $mdns echo " sound: " $sound echo " cm108gpio: " $cm108gpio echo " ssl: " $ssl echo " certauth: " $certauth echo " mux: " $mux echo " telnet: " $telnet echo " msgdelim: " $msgdelim echo " relpkt: " $relpkt echo " trace: " $trace echo " perf: " $perf echo " kiss: " $kiss echo " ax25: " $ax25 echo " xlt: " $xlt echo " keepopen: " $keepopen echo " script: " $script echo " ratelimit: " $ratelimit echo " afskmdm: " $afskmdm echo echo "**************************************************" echo gensio-3.0.0/glib/0000775000175000017500000000000015061121735007457 5gensio-3.0.0/glib/Makefile.in0000664000175000017500000010302115061121657011444 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = glib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = libgensioglib.pc CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)" \ "$(DESTDIR)$(pkgconfigexecdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libgensioglib_la_DEPENDENCIES = $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la am_libgensioglib_la_OBJECTS = libgensioglib_la-gensio_glib.lo libgensioglib_la_OBJECTS = $(am_libgensioglib_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libgensioglib_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libgensioglib_la_CFLAGS) $(CFLAGS) \ $(libgensioglib_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/libgensioglib_la-gensio_glib.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libgensioglib_la_SOURCES) DIST_SOURCES = $(libgensioglib_la_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac man3dir = $(mandir)/man3 NROFF = nroff MANS = $(man3_MANS) DATA = $(pkgconfigexec_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/libgensioglib.pc.in \ $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = -I$(top_srcdir)/glib/include @EXTRA_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -DBUILDING_GENSIOGLIB_DLL lib_LTLIBRARIES = libgensioglib.la libgensioglib_la_SOURCES = gensio_glib.c libgensioglib_la_CFLAGS = $(GLIB_CFLAGS) $(AM_CFLAGS) libgensioglib_la_LIBADD = $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ @OPENSSL_LIBS@ @GLIB_LIBS@ libgensioglib_la_LDFLAGS = -no-undefined -rpath $(libdir) \ -version-info $(GENSIO_LIB_VERSION) -fvisibility=hidden SUBDIRS = . $(SWIG_DIR) include $(CPLUSPLUS_DIR) DIST_SUBDIRS = swig include c++ # This variable must have 'exec' in its name, in order to be installed # by 'install-exec' target (instead of default 'install-data') pkgconfigexecdir = $(libdir)/pkgconfig pkgconfigexec_DATA = libgensioglib.pc @INSTALL_DOC_TRUE@man3_MANS = gensio_glib_funcs_alloc.3 EXTRA_DIST = libgensioglib.pc.in $(man3_MANS) all: all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu glib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu glib/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): libgensioglib.pc: $(top_builddir)/config.status $(srcdir)/libgensioglib.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libgensioglib.la: $(libgensioglib_la_OBJECTS) $(libgensioglib_la_DEPENDENCIES) $(EXTRA_libgensioglib_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensioglib_la_LINK) -rpath $(libdir) $(libgensioglib_la_OBJECTS) $(libgensioglib_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensioglib_la-gensio_glib.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libgensioglib_la-gensio_glib.lo: gensio_glib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgensioglib_la_CFLAGS) $(CFLAGS) -MT libgensioglib_la-gensio_glib.lo -MD -MP -MF $(DEPDIR)/libgensioglib_la-gensio_glib.Tpo -c -o libgensioglib_la-gensio_glib.lo `test -f 'gensio_glib.c' || echo '$(srcdir)/'`gensio_glib.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensioglib_la-gensio_glib.Tpo $(DEPDIR)/libgensioglib_la-gensio_glib.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_glib.c' object='libgensioglib_la-gensio_glib.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgensioglib_la_CFLAGS) $(CFLAGS) -c -o libgensioglib_la-gensio_glib.lo `test -f 'gensio_glib.c' || echo '$(srcdir)/'`gensio_glib.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man3: $(man3_MANS) @$(NORMAL_INSTALL) @list1='$(man3_MANS)'; \ list2=''; \ test -n "$(man3dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.3[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ done; } uninstall-man3: @$(NORMAL_UNINSTALL) @list='$(man3_MANS)'; test -n "$(man3dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) install-pkgconfigexecDATA: $(pkgconfigexec_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfigexec_DATA)'; test -n "$(pkgconfigexecdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigexecdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigexecdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigexecdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigexecdir)" || exit $$?; \ done uninstall-pkgconfigexecDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfigexec_DATA)'; test -n "$(pkgconfigexecdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigexecdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(pkgconfigexecdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-recursive -rm -f ./$(DEPDIR)/libgensioglib_la-gensio_glib.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-man install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-libLTLIBRARIES install-pkgconfigexecDATA install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-man3 install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f ./$(DEPDIR)/libgensioglib_la-gensio_glib.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-libLTLIBRARIES uninstall-man \ uninstall-pkgconfigexecDATA uninstall-man: uninstall-man3 .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--depfiles check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-libLTLIBRARIES install-man \ install-man3 install-pdf install-pdf-am \ install-pkgconfigexecDATA install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-libLTLIBRARIES uninstall-man \ uninstall-man3 uninstall-pkgconfigexecDATA .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/glib/gensio_glib.c0000664000175000017500000013420314664224267012043 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* * This library provides a gensio_os_funcs object for use by gensio. * It can be used if you have a project based on glib that you want to * integrate gensio into. * * Unfortunately, it has some limitations because of weaknesses in the * glib interface. * * If you use this, you really want to use the gensio wait functions, * not g_cont_wait..() yourself. you don't strictly have have to, * especially if your app is single threaded, but especially in * multithreaded apps you cannot mix calls to the os funcs wait * functions and the glib wait functions. Which means you can't use * the blocking functions, which all use os func waiters. * * Performance should be ok for a single thread. For multiple * threads, though, only on thing at a time can be waiting on the main * glib thread. This is a weakness in glib. For multiple threads, * one function sits in the main context and the others sit on * condition variables. When the thead sitting on the main context * wakes up, it wakes another waiting thread to take over. * * If performance is important, it might be better to put glib on top * of gensio os funcs with g_main_context_set_poll_func(). I leave * that as an exercise to the reader. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #else #include #include #include #include #include #include #include #include #endif struct gensio_data { GMutex lock; unsigned int refcount; GCond cond; /* Global waiting threads. */ struct gensio_list waiting_threads; struct gensio_wait_thread *main_context_owner; /* Used to track if we did some operation. */ bool did_something; struct gensio_memtrack *mtrack; struct gensio_os_proc_data *pdata; }; static void * gensio_glib_zalloc(struct gensio_os_funcs *f, gensiods size) { struct gensio_data *d = f->user_data; TRACE_MEM; return gensio_i_zalloc(d->mtrack, size, TRACE_MEM_CALLERS, TRACE_MEM_CALLERS_SIZE); } static void gensio_glib_free(struct gensio_os_funcs *f, void *data) { struct gensio_data *d = f->user_data; TRACE_MEM; gensio_i_free(d->mtrack, data, TRACE_MEM_CALLERS, TRACE_MEM_CALLERS_SIZE); } static void gensio_glib_did_something(struct gensio_os_funcs *f) { struct gensio_data *d = f->user_data; g_mutex_lock(&d->lock); d->did_something = true; g_mutex_unlock(&d->lock); } struct gensio_lock { struct gensio_os_funcs *f; GMutex mutex; }; static struct gensio_lock * gensio_glib_alloc_lock(struct gensio_os_funcs *f) { struct gensio_lock *lock; lock = gensio_glib_zalloc(f, sizeof(*lock)); if (!lock) return NULL; lock->f = f; g_mutex_init(&lock->mutex); return lock; } static void gensio_glib_free_lock(struct gensio_lock *lock) { g_mutex_clear(&lock->mutex); gensio_glib_free(lock->f, lock); } static void gensio_glib_lock(struct gensio_lock *lock) { g_mutex_lock(&lock->mutex); } static void gensio_glib_unlock(struct gensio_lock *lock) { g_mutex_unlock(&lock->mutex); } struct gensio_iod_glib { struct gensio_iod r; GMutex lock; GIOChannel *chan; guint read_id; guint write_id; guint except_id; guint idle_id; bool in_clear; unsigned int clear_count; enum { CL_NOT_CALLED, CL_CALLED, CL_DONE } close_state; int orig_fd; int fd; int sfd; enum gensio_iod_type type; void *sockinfo; bool handlers_set; bool is_stdio; void *cb_data; void (*read_handler)(struct gensio_iod *iod, void *cb_data); void (*write_handler)(struct gensio_iod *iod, void *cb_data); void (*except_handler)(struct gensio_iod *iod, void *cb_data); void (*cleared_handler)(struct gensio_iod *iod, void *cb_data); struct stdio_mode *mode; #ifdef _WIN32 HANDLE h; struct gensio_win_commport *comm; #else struct gensio_unix_termios *termios; #endif /* For GENSIO_IOD_FILE */ struct gensio_runner *runner; bool read_enabled; bool write_enabled; bool in_handler; /* For GENSIO_IOD_PTY */ const char **argv; const char **env; char *start_dir; int pid; }; #define i_to_glib(i) gensio_container_of(i, struct gensio_iod_glib, r); static gboolean glib_read_handler(GIOChannel *source, GIOCondition condition, gpointer data) { struct gensio_iod_glib *iod = data; gensio_glib_did_something(iod->r.f); iod->read_handler(&iod->r, iod->cb_data); return G_SOURCE_CONTINUE; } static gboolean glib_write_handler(GIOChannel *source, GIOCondition condition, gpointer data) { struct gensio_iod_glib *iod = data; gensio_glib_did_something(iod->r.f); iod->write_handler(&iod->r, iod->cb_data); return G_SOURCE_CONTINUE; } static gboolean glib_except_handler(GIOChannel *source, GIOCondition condition, gpointer data) { struct gensio_iod_glib *iod = data; gensio_glib_did_something(iod->r.f); iod->except_handler(&iod->r, iod->cb_data); return G_SOURCE_CONTINUE; } static gboolean glib_cleared_done(gpointer data) { struct gensio_iod_glib *iod = data; g_mutex_lock(&iod->lock); iod->handlers_set = false; iod->idle_id = 0; iod->read_handler = NULL; iod->write_handler = NULL; iod->except_handler = NULL; iod->in_clear = false; g_mutex_unlock(&iod->lock); if (iod->cleared_handler) iod->cleared_handler(&iod->r, iod->cb_data); return G_SOURCE_REMOVE; } static gint glib_real_cleared_handler(gpointer data) { struct gensio_iod_glib *iod = data; gensio_glib_did_something(iod->r.f); g_mutex_lock(&iod->lock); assert(iod->clear_count > 0); iod->clear_count--; if (iod->clear_count == 0) { g_mutex_unlock(&iod->lock); glib_cleared_done(iod); } else { g_mutex_unlock(&iod->lock); } return G_SOURCE_REMOVE; } static void glib_cleared_handler(gpointer data) { struct gensio_iod_glib *iod = data; /* This can run from user context, call it from base context. */ gensio_glib_did_something(iod->r.f); g_idle_add(glib_real_cleared_handler, data); } static int gensio_glib_set_fd_handlers(struct gensio_iod *iiod, void *cb_data, void (*read_handler)(struct gensio_iod *iod, void *cb_data), void (*write_handler)(struct gensio_iod *iod, void *cb_data), void (*except_handler)(struct gensio_iod *iod, void *cb_data), void (*cleared_handler)(struct gensio_iod *iod, void *cb_data)) { struct gensio_iod_glib *iod = i_to_glib(iiod); g_mutex_lock(&iod->lock); if (iod->handlers_set) { g_mutex_unlock(&iod->lock); return GE_INUSE; } iod->handlers_set = true; iod->clear_count = 1; iod->cb_data = cb_data; iod->read_handler = read_handler; iod->write_handler = write_handler; iod->except_handler = except_handler; iod->cleared_handler = cleared_handler; g_mutex_unlock(&iod->lock); return 0; } static void gensio_glib_clear_fd_handlers(struct gensio_iod *iiod) { struct gensio_iod_glib *iod = i_to_glib(iiod); g_mutex_lock(&iod->lock); if (!iod->handlers_set || iod->in_clear) goto out_unlock; if (iod->type == GENSIO_IOD_FILE) { iod->in_clear = true; iod->r.f->run(iod->runner); goto out_unlock; } if (iod->read_id) { g_source_remove(iod->read_id); iod->read_id = 0; } if (iod->write_id) { g_source_remove(iod->write_id); iod->write_id = 0; } if (iod->except_id) { g_source_remove(iod->except_id); iod->except_id = 0; } iod->in_clear = true; if (iod->clear_count == 1) { iod->clear_count = 0; iod->idle_id = g_idle_add(glib_cleared_done, iod); } else { iod->clear_count--; /* Done operation will be handled in the cleared handlers. */ } out_unlock: g_mutex_unlock(&iod->lock); } static void gensio_glib_clear_fd_handlers_norpt(struct gensio_iod *iiod) { struct gensio_iod_glib *iod = i_to_glib(iiod); g_mutex_lock(&iod->lock); assert(!iod->read_id && !iod->write_id && !iod->except_id && !iod->idle_id && iod->clear_count <= 1); iod->clear_count = 0; iod->handlers_set = false; g_mutex_unlock(&iod->lock); } static void file_runner(struct gensio_runner *r, void *cb_data) { struct gensio_iod_glib *iod = cb_data; g_mutex_lock(&iod->lock); while (iod->read_enabled || iod->write_enabled) { if (iod->read_enabled) { g_mutex_unlock(&iod->lock); iod->read_handler(&iod->r, iod->cb_data); g_mutex_lock(&iod->lock); } if (iod->write_enabled) { g_mutex_unlock(&iod->lock); iod->write_handler(&iod->r, iod->cb_data); g_mutex_lock(&iod->lock); } } iod->in_handler = false; if (iod->in_clear) { iod->in_clear = false; iod->handlers_set = false; g_mutex_unlock(&iod->lock); iod->cleared_handler(&iod->r, iod->cb_data); g_mutex_lock(&iod->lock); } g_mutex_unlock(&iod->lock); } static void gensio_glib_set_read_handler(struct gensio_iod *iiod, bool enable) { struct gensio_iod_glib *iod = i_to_glib(iiod); struct gensio_os_funcs *f = iod->r.f; g_mutex_lock(&iod->lock); if (iod->type == GENSIO_IOD_FILE) { if (iod->read_enabled == enable || iod->in_clear) goto out_unlock; iod->read_enabled = enable; if (enable && !iod->in_handler) { f->run(iod->runner); iod->in_handler = true; } } else if (iod->read_id && !enable) { g_source_remove(iod->read_id); iod->read_id = 0; } else if (!iod->read_id && enable) { iod->read_id = g_io_add_watch_full(iod->chan, 0, G_IO_IN, glib_read_handler, iod, glib_cleared_handler); assert(iod->read_id); iod->clear_count++; } out_unlock: g_mutex_unlock(&iod->lock); } static void gensio_glib_set_write_handler(struct gensio_iod *iiod, bool enable) { struct gensio_iod_glib *iod = i_to_glib(iiod); struct gensio_os_funcs *f = iod->r.f; g_mutex_lock(&iod->lock); if (iod->type == GENSIO_IOD_FILE) { if (iod->write_enabled == enable || iod->in_clear) goto out_unlock; iod->write_enabled = enable; if (enable && !iod->in_handler) { f->run(iod->runner); iod->in_handler = true; } } else if (iod->write_id && !enable) { g_source_remove(iod->write_id); iod->write_id = 0; } else if (!iod->write_id && enable) { iod->write_id = g_io_add_watch_full(iod->chan, 0, G_IO_OUT, glib_write_handler, iod, glib_cleared_handler); assert(iod->write_id); iod->clear_count++; } out_unlock: g_mutex_unlock(&iod->lock); } static void gensio_glib_set_except_handler(struct gensio_iod *iiod, bool enable) { struct gensio_iod_glib *iod = i_to_glib(iiod); if (iod->type == GENSIO_IOD_FILE) return; g_mutex_lock(&iod->lock); if (iod->except_id && !enable) { g_source_remove(iod->except_id); iod->except_id = 0; } else if (!iod->except_id && enable) { iod->except_id = g_io_add_watch_full(iod->chan, 0, G_IO_PRI | G_IO_ERR | G_IO_HUP, glib_except_handler, iod, glib_cleared_handler); assert(iod->except_id); iod->clear_count++; } g_mutex_unlock(&iod->lock); } struct gensio_timer { struct gensio_os_funcs *o; void (*handler)(struct gensio_timer *t, void *cb_data); void *cb_data; GMutex lock; guint timer_id; unsigned int usecount; enum { GLIB_TIMER_FREE, GLIB_TIMER_IN_STOP, GLIB_TIMER_STOPPED, GLIB_TIMER_RUNNING } state; void (*done_handler)(struct gensio_timer *t, void *cb_data); void *done_cb_data; }; static gboolean gensio_glib_timeout_handler(gpointer data) { struct gensio_timer *t = (void *) data; void (*handler)(struct gensio_timer *t, void *cb_data) = NULL; void *cb_data; gensio_glib_did_something(t->o); g_mutex_lock(&t->lock); if (t->timer_id) { handler = t->handler; cb_data = t->cb_data; t->state = GLIB_TIMER_STOPPED; t->timer_id = 0; } g_mutex_unlock(&t->lock); if (handler) handler(t, cb_data); return G_SOURCE_REMOVE; } static gint glib_real_timeout_destroyed(gpointer data) { struct gensio_timer *t = (void *) data; void (*handler)(struct gensio_timer *t, void *cb_data) = NULL; void *cb_data; unsigned int usecount; gensio_glib_did_something(t->o); g_mutex_lock(&t->lock); if (t->done_handler) { t->state = GLIB_TIMER_STOPPED; handler = t->done_handler; cb_data = t->done_cb_data; t->done_handler = NULL; } t->usecount--; usecount = t->usecount; g_mutex_unlock(&t->lock); if (handler) handler(t, cb_data); if (usecount == 0) { t->state = GLIB_TIMER_FREE; g_mutex_clear(&t->lock); t->o->free(t->o, t); } return G_SOURCE_REMOVE; } static void gensio_glib_timeout_destroyed(gpointer data) { struct gensio_timer *t = (void *) data; /* This can run from user context, call it from base context. */ gensio_glib_did_something(t->o); g_idle_add(glib_real_timeout_destroyed, data); } static struct gensio_timer * gensio_glib_alloc_timer(struct gensio_os_funcs *o, void (*handler)(struct gensio_timer *t, void *cb_data), void *cb_data) { struct gensio_timer *t; t = o->zalloc(o, sizeof(*t)); if (!t) return NULL; t->o = o; t->handler = handler; t->cb_data = cb_data; t->state = GLIB_TIMER_STOPPED; t->usecount = 1; g_mutex_init(&t->lock); return t; } static void gensio_glib_free_timer(struct gensio_timer *t) { unsigned int usecount; g_mutex_lock(&t->lock); assert(t->state != GLIB_TIMER_FREE); if (t->timer_id) { g_source_remove(t->timer_id); t->timer_id = 0; } t->state = GLIB_TIMER_FREE; t->usecount--; usecount = t->usecount; g_mutex_unlock(&t->lock); if (usecount == 0) { t->state = GLIB_TIMER_FREE; g_mutex_clear(&t->lock); t->o->free(t->o, t); } } /* * Various time conversion routines. Note that we always truncate up * to the next time unit. These are used for timers, and if you don't * you can end up with an early timeout. */ static guint gensio_time_to_ms(gensio_time *t) { return t->secs * 1000 + (t->nsecs + 999999) / 1000000; } static guint gensio_time_to_us(gensio_time *t) { return t->secs * 1000000 + (t->nsecs + 999) / 1000; } static guint us_time_to_ms(gint64 t) { return (t + 999) / 1000; } static void us_time_to_gensio(gint64 t, gensio_time *gt) { gt->secs = t / 1000000; gt->nsecs = t % 1000000 * 1000; } static int gensio_glib_start_timer(struct gensio_timer *t, gensio_time *timeout) { guint msec = gensio_time_to_ms(timeout); int rv = 0; g_mutex_lock(&t->lock); assert(t->state != GLIB_TIMER_FREE); if (t->state != GLIB_TIMER_STOPPED) { rv = GE_INUSE; } else { t->done_handler = NULL; t->timer_id = g_timeout_add_full(0, msec, gensio_glib_timeout_handler, t, gensio_glib_timeout_destroyed); if (!t->timer_id) { rv = GE_NOMEM; } else { t->state = GLIB_TIMER_RUNNING; t->usecount++; } } g_mutex_unlock(&t->lock); return rv; } static int gensio_glib_start_timer_abs(struct gensio_timer *t, gensio_time *timeout) { gint64 now, msec; int rv = 0; g_mutex_lock(&t->lock); assert(t->state != GLIB_TIMER_FREE); if (t->state != GLIB_TIMER_STOPPED) { rv = GE_INUSE; } else { t->done_handler = NULL; msec = gensio_time_to_ms(timeout); now = g_get_monotonic_time(); msec -= now; if (msec < 0) msec = 0; t->timer_id = g_timeout_add_full(0, msec, gensio_glib_timeout_handler, t, gensio_glib_timeout_destroyed); if (!t->timer_id) { rv = GE_NOMEM; } else { t->state = GLIB_TIMER_RUNNING; t->usecount++; } } g_mutex_unlock(&t->lock); return rv; } static int gensio_glib_stop_timer(struct gensio_timer *t) { int rv = 0; g_mutex_lock(&t->lock); assert(t->state != GLIB_TIMER_FREE); if (t->state != GLIB_TIMER_RUNNING) { rv = GE_TIMEDOUT; } else { t->state = GLIB_TIMER_STOPPED; g_source_remove(t->timer_id); t->timer_id = 0; } g_mutex_unlock(&t->lock); return rv; } static int gensio_glib_stop_timer_with_done(struct gensio_timer *t, void (*done_handler)(struct gensio_timer *t, void *cb_data), void *cb_data) { int rv = 0; g_mutex_lock(&t->lock); if (t->state == GLIB_TIMER_IN_STOP) { rv = GE_INUSE; } else if (t->state != GLIB_TIMER_RUNNING) { rv = GE_TIMEDOUT; } else { t->state = GLIB_TIMER_IN_STOP; t->done_handler = done_handler; t->done_cb_data = cb_data; g_source_remove(t->timer_id); t->timer_id = 0; } g_mutex_unlock(&t->lock); return rv; } struct gensio_runner { struct gensio_os_funcs *o; void (*handler)(struct gensio_runner *r, void *cb_data); void *cb_data; GMutex lock; guint idle_id; bool freed; }; static gboolean gensio_glib_idle_handler(gpointer data) { struct gensio_runner *r = (void *) data; void (*handler)(struct gensio_runner *r, void *cb_data) = NULL; void *cb_data; gensio_glib_did_something(r->o); g_mutex_lock(&r->lock); if (r->freed) { g_mutex_unlock(&r->lock); g_mutex_clear(&r->lock); r->o->free(r->o, r); } else { handler = r->handler; cb_data = r->cb_data; r->idle_id = 0; g_mutex_unlock(&r->lock); } if (handler) handler(r, cb_data); return G_SOURCE_REMOVE; } static struct gensio_runner * gensio_glib_alloc_runner(struct gensio_os_funcs *o, void (*handler)(struct gensio_runner *r, void *cb_data), void *cb_data) { struct gensio_runner *r; r = o->zalloc(o, sizeof(*r)); if (!r) return NULL; r->o = o; r->handler = handler; r->cb_data = cb_data; g_mutex_init(&r->lock); return r; } static void gensio_glib_free_runner(struct gensio_runner *r) { g_mutex_lock(&r->lock); if (r->idle_id) { r->freed = true; g_mutex_unlock(&r->lock); } else { g_mutex_unlock(&r->lock); g_mutex_clear(&r->lock); r->o->free(r->o, r); } } static int gensio_glib_run(struct gensio_runner *r) { int rv = 0; g_mutex_lock(&r->lock); if (r->idle_id) { rv = GE_INUSE; } else { r->idle_id = g_idle_add(gensio_glib_idle_handler, r); if (!r->idle_id) rv = GE_NOMEM; } g_mutex_unlock(&r->lock); return rv; } struct gensio_waiter { struct gensio_os_funcs *o; GCond cond; unsigned int count; struct gensio_list waiting_threads; }; struct gensio_wait_thread { GCond *cond; unsigned int count; /* Link for a specific waiter. */ struct gensio_link wait_link; /* Link for all threads waiting in the os handler. */ struct gensio_link global_link; }; static struct gensio_waiter * gensio_glib_alloc_waiter(struct gensio_os_funcs *o) { struct gensio_waiter *w; w = o->zalloc(o, sizeof(*w)); if (!w) return NULL; w->o = o; g_cond_init(&w->cond); gensio_list_init(&w->waiting_threads); return w; } static void gensio_glib_free_waiter(struct gensio_waiter *w) { assert(gensio_list_empty(&w->waiting_threads)); g_cond_clear(&w->cond); w->o->free(w->o, w); } static gboolean dummy_timeout_handler(gpointer data) { /* Will be removed in the main loop, avoid races with remove. */ return G_SOURCE_CONTINUE; } #define gensio_glib_wake_next_thread(list, link) do { \ if (!gensio_list_empty(list)) { \ struct gensio_link *l = gensio_list_first(list); \ struct gensio_wait_thread *ot; \ ot = gensio_container_of(l, struct gensio_wait_thread, link); \ g_cond_signal(ot->cond); \ } \ } while(0) static void i_gensio_glib_wake(struct gensio_waiter *w, unsigned int count) { struct gensio_link *l; gensio_list_for_each(&w->waiting_threads, l) { struct gensio_wait_thread *ot; ot = gensio_container_of(l, struct gensio_wait_thread, wait_link); if (ot->count) { if (ot->count >= count) { ot->count -= count; count = 0; } else { count -= ot->count; ot->count = 0; } if (ot->count == 0) { if (ot->cond) { g_cond_signal(ot->cond); } else { g_main_context_wakeup(NULL); } } } if (count == 0) break; } w->count += count; } struct timeout_info { gensio_time *timeout; gint64 start; gint64 now; gint64 end; }; static void setup_timeout(struct timeout_info *t) { if (t->timeout) { t->start = t->now = g_get_monotonic_time(); t->end = t->now + gensio_time_to_us(t->timeout); } else { t->start = 0; t->now = 0; t->end = 0; } } static bool timed_out(struct timeout_info *t) { return t->timeout && t->now >= t->end; } static void timeout_wait(struct timeout_info *t) { if (t->timeout) { guint timerid; timerid = g_timeout_add_full(G_PRIORITY_LOW, us_time_to_ms(t->end - t->now), dummy_timeout_handler, NULL, NULL); g_main_context_iteration(NULL, TRUE); g_source_remove(timerid); } else { g_main_context_iteration(NULL, TRUE); } } static void timeout_end(struct timeout_info *t) { if (t->timeout) { gint64 diff = t->end - t->now; if (diff > 0) { us_time_to_gensio(diff, t->timeout); } else { t->timeout->secs = 0; t->timeout->nsecs = 0; } } } static int i_gensio_glib_wait(struct gensio_waiter *w, unsigned int count, gensio_time *timeout) { struct gensio_data *d = w->o->user_data; struct gensio_wait_thread t; struct timeout_info ti = { .timeout = timeout }; int rv = 0; gensio_list_link_init(&t.wait_link); gensio_list_link_init(&t.global_link); t.count = count; setup_timeout(&ti); g_mutex_lock(&d->lock); if (w->count > 0) { if (w->count >= t.count) { w->count -= t.count; t.count = 0; } else { t.count -= w->count; w->count = 0; } } gensio_list_add_tail(&w->waiting_threads, &t.wait_link); gensio_list_add_tail(&d->waiting_threads, &t.global_link); while (t.count > 0 && !timed_out(&ti)) { if (!d->main_context_owner) d->main_context_owner = &t; if (d->main_context_owner == &t) { /* This is the thread that will run the main context. */ t.cond = NULL; g_mutex_unlock(&d->lock); timeout_wait(&ti); g_mutex_lock(&d->lock); } else { /* Not running the main context, just wait on a cond. */ t.cond = &w->cond; if (timeout) g_cond_wait_until(t.cond, &d->lock, ti.end); else g_cond_wait(t.cond, &d->lock); } ti.now = g_get_monotonic_time(); } gensio_list_rm(&w->waiting_threads, &t.wait_link); gensio_list_rm(&d->waiting_threads, &t.global_link); if (d->main_context_owner == &t) { d->main_context_owner = NULL; /* Need to get another main context owner. */ gensio_glib_wake_next_thread(&d->waiting_threads, global_link); } if (t.count > 0) { rv = GE_TIMEDOUT; /* Re-add whatever was decremented to the waiter. */ i_gensio_glib_wake(w, count - t.count); } g_mutex_unlock(&d->lock); timeout_end(&ti); return rv; } static int gensio_glib_wait_intr_sigmask(struct gensio_waiter *w, unsigned int count, gensio_time *timeout, struct gensio_os_proc_data *proc_data) { #ifdef _WIN32 return gensio_glib_wait(w, count, timeout); #else int rv; sigset_t origmask; if (proc_data) pthread_sigmask(SIG_SETMASK, gensio_os_proc_unix_get_wait_sigset(proc_data), &origmask); rv = i_gensio_glib_wait(w, count, timeout); if (proc_data) { pthread_sigmask(SIG_SETMASK, &origmask, NULL); gensio_os_proc_check_handlers(proc_data); } return rv; #endif } static int gensio_glib_wait_intr(struct gensio_waiter *w, unsigned int count, gensio_time *timeout) { struct gensio_data *d = w->o->user_data; return gensio_glib_wait_intr_sigmask(w, count, timeout, d->pdata); } static int gensio_glib_wait(struct gensio_waiter *w, unsigned int count, gensio_time *timeout) { struct gensio_data *d = w->o->user_data; int err = GE_INTERRUPTED; while (err == GE_INTERRUPTED) err = gensio_glib_wait_intr_sigmask(w, count, timeout, d->pdata); return err; } static void gensio_glib_wake(struct gensio_waiter *w) { struct gensio_data *d = w->o->user_data; g_mutex_lock(&d->lock); i_gensio_glib_wake(w, 1); g_mutex_unlock(&d->lock); } static int gensio_glib_add_iod(struct gensio_os_funcs *o, enum gensio_iod_type type, intptr_t ofd, struct gensio_iod **riod, ...) { struct gensio_iod_glib *iod; bool closefd = false; int err = GE_NOMEM; intptr_t fd = ofd; int sfd = -1; #ifndef _WIN32 if (type == GENSIO_IOD_CONSOLE) { if (fd == 0) fd = open("/dev/tty", O_RDONLY); else if (fd == 1) fd = open("/dev/tty", O_WRONLY); else return GE_INVAL; if (fd == -1) return gensio_os_err_to_err(o, errno); closefd = true; } else if (type == GENSIO_IOD_PTY) { int ufd; err = gensio_unix_pty_alloc(o, &ufd, &sfd); if (err) return err; fd = ufd; closefd = true; } #endif iod = o->zalloc(o, sizeof(*iod)); if (!iod) { if (closefd) close(fd); return GE_NOMEM; } iod->r.f = o; iod->fd = fd; iod->orig_fd = ofd; iod->sfd = sfd; if (type == GENSIO_IOD_STDIO) { #ifndef _WIN32 struct stat statb; iod->is_stdio = true; err = fstat(fd, &statb); if (err == -1) { err = gensio_os_err_to_err(o, errno); goto out_err; } switch (statb.st_mode & S_IFMT) { case S_IFREG: type = GENSIO_IOD_FILE; break; case S_IFCHR: type = GENSIO_IOD_DEV; break; case S_IFIFO: type = GENSIO_IOD_PIPE; break; case S_IFSOCK: type = GENSIO_IOD_SOCKET; break; default: err = GE_INVAL; goto out_err; } } else if (type == GENSIO_IOD_PTY) { iod->pid = -1; #endif } iod->type = type; if (type == GENSIO_IOD_FILE) { iod->runner = o->alloc_runner(o, file_runner, iod); if (!iod->runner) goto out_err; goto out; } #ifdef _WIN32 /* * Windows doesn't have a way to turn a Handle into a glib io * channel. We could do it ourselves like gensio_win.c has * separate threads to handle, but it would be a lot of work. So * just don't do this for now. * * So I have stopped here and in the open_dev function. I'll * leave in the stuff I've done so far, but disable Windows * support in the config. */ #error "No Windows support for glib" #else iod->chan = g_io_channel_unix_new(iod->fd); if (!iod->chan) { o->free(o, iod); return GE_NOMEM; } #endif g_io_channel_set_encoding(iod->chan, NULL, NULL); g_io_channel_set_buffered(iod->chan, FALSE); out: g_mutex_init(&iod->lock); *riod = &iod->r; return 0; out_err: o->free(o, iod); if (closefd) { close(fd); if (sfd != -1) close(sfd); } return err; } static void gensio_glib_release_iod(struct gensio_iod *iiod) { struct gensio_os_funcs *o = iiod->f; struct gensio_iod_glib *iod = i_to_glib(iiod); assert(!iod->handlers_set); g_mutex_clear(&iod->lock); if (iod->type == GENSIO_IOD_FILE) o->free_runner(iod->runner); if (iod->type == GENSIO_IOD_PTY) { if (iod->argv) gensio_argv_free(o, iod->argv); if (iod->env) gensio_argv_free(o, iod->env); } o->free(o, iod); } static int gensio_glib_iod_get_type(struct gensio_iod *iiod) { struct gensio_iod_glib *iod = i_to_glib(iiod); return iod->type; } static int gensio_glib_iod_get_fd(struct gensio_iod *iiod) { struct gensio_iod_glib *iod = i_to_glib(iiod); return iod->fd; } static int gensio_glib_pty_control(struct gensio_iod_glib *iod, int op, bool get, intptr_t val) { struct gensio_os_funcs *o = iod->r.f; int err = 0; const char **nargv; if (get) { if (op == GENSIO_IOD_CONTROL_PID) { if (iod->pid == -1) return GE_NOTREADY; *((intptr_t *) val) = iod->pid; return 0; } return GE_NOTSUP; } switch (op) { case GENSIO_IOD_CONTROL_ARGV: err = gensio_argv_copy(o, (const char **) val, NULL, &nargv); if (err) return err; if (iod->argv) gensio_argv_free(o, iod->argv); iod->argv = nargv; return 0; case GENSIO_IOD_CONTROL_ENV: err = gensio_argv_copy(o, (const char **) val, NULL, &nargv); if (err) return err; if (iod->env) gensio_argv_free(o, iod->env); iod->env = nargv; return 0; case GENSIO_IOD_CONTROL_START: #ifdef _WIN32 return GE_NOTSUP; #else return gensio_unix_pty_start(o, iod->fd, &iod->sfd, iod->argv, iod->env, iod->start_dir, &iod->pid); #endif case GENSIO_IOD_CONTROL_STOP: #ifdef _WIN32 return GE_NOTSUP; #else if (iod->fd != -1) { close(iod->fd); iod->fd = -1; } return 0; #endif case GENSIO_IOD_CONTROL_WIN_SIZE: { struct winsize win; struct gensio_winsize *gwin = (struct gensio_winsize *) val; win.ws_row = gwin->ws_row; win.ws_col = gwin->ws_col; win.ws_xpixel = gwin->ws_xpixel; win.ws_ypixel = gwin->ws_ypixel; if (ioctl(iod->fd, TIOCSWINSZ, &win) == -1) err = gensio_os_err_to_err(o, errno); return err; } case GENSIO_IOD_CONTROL_START_DIR: { char *dir = (char *) val; if (dir) { dir = gensio_strdup(o, dir); if (!dir) return GE_NOMEM; } if (iod->start_dir) o->free(o, iod->start_dir); iod->start_dir = dir; return 0; } default: return GE_NOTSUP; } } static int gensio_glib_iod_control(struct gensio_iod *iiod, int op, bool get, intptr_t val) { struct gensio_iod_glib *iod = i_to_glib(iiod); if (iod->type == GENSIO_IOD_SOCKET) { if (op != GENSIO_IOD_CONTROL_SOCKINFO) return GE_NOTSUP; if (get) *((void **) val) = iod->sockinfo; else iod->sockinfo = (void *) val; return 0; } if (iod->type == GENSIO_IOD_PTY) return gensio_glib_pty_control(iod, op, get, val); if (iod->type != GENSIO_IOD_DEV) return GE_NOTSUP; #ifdef _WIN32 return gensio_win_commport_control(iiod->f, op, get, val, &iod->comm, iod->h); #else return gensio_unix_termios_control(iiod->f, op, get, val, &iod->termios, iod->fd); #endif } static int gensio_glib_set_non_blocking(struct gensio_iod *iiod) { struct gensio_iod_glib *iod = i_to_glib(iiod); int rv = 0; if (iod->type == GENSIO_IOD_FILE) return 0; #ifdef _WIN32 if (iod->type == GENSIO_IOD_SOCKET) { unsigned long flags = 1; rv = ioctlsocket(iod->fd, FIONBIO, &flags); if (rv) rv = gensio_os_err_to_err(iiod->f, errno); } else { GIOFlags flags = g_io_channel_get_flags(iod->chan); flags |= G_IO_FLAG_NONBLOCK; g_io_channel_set_flags(iod->chan, flags, NULL); } #else rv = gensio_unix_do_nonblock(iiod->f, iod->fd, &iod->mode); #endif return rv; } static int gensio_glib_close(struct gensio_iod **iodp) { struct gensio_iod *iiod = *iodp; struct gensio_iod_glib *iod = i_to_glib(iiod); struct gensio_os_funcs *o = iiod->f; int err = 0; assert(iodp); assert(!iod->handlers_set); if (iod->type != GENSIO_IOD_FILE) { #ifdef _WIN32 gensio_win_stdio_cleanup(o, iod->h, &iod->mode); gensio_win_cleanup_commport(o, iod->h, &iod->comm); #else gensio_unix_cleanup_termios(o, &iod->termios, iod->fd); gensio_unix_do_cleanup_nonblock(o, iod->fd, &iod->mode); #endif } if (iod->type == GENSIO_IOD_SOCKET) { g_mutex_lock(&iod->lock); if (iod->close_state == CL_DONE) { err = 0; } else { err = o->close_socket(iiod, iod->close_state == CL_CALLED, false); if (err == GE_INPROGRESS) iod->close_state = CL_CALLED; else iod->close_state = CL_DONE; } g_mutex_unlock(&iod->lock); } else if (!iod->is_stdio) { #ifdef _WIN32 CloseHandle(iod->h); #else if (iod->fd != -1) { err = close(iod->fd); iod->fd = -1; if (err == -1) err = gensio_os_err_to_err(o, errno); #endif #ifdef ENABLE_INTERNAL_TRACE /* Close should never fail, but don't crash in production builds. */ assert(err == 0); #endif } if (iod->sfd != -1) { err = close(iod->sfd); iod->sfd = -1; } } o->release_iod(iiod); *iodp = NULL; return err; } static int glib_err_to_err(struct gensio_os_funcs *o, GError *ierr) { int err; if (!ierr || ierr->code == 0) return 0; switch (ierr->code) { case G_IO_CHANNEL_ERROR_FBIG: err = GE_TOOBIG; break; case G_IO_CHANNEL_ERROR_INVAL: err = GE_INVAL; break; case G_IO_CHANNEL_ERROR_IO: err = GE_IOERR; break; case G_IO_CHANNEL_ERROR_NOSPC: err = GE_NOMEM; break; case G_IO_CHANNEL_ERROR_NXIO: err = GE_NOTFOUND; break; case G_IO_CHANNEL_ERROR_FAILED: /* This happens on remote close */ case G_IO_CHANNEL_ERROR_PIPE: err = GE_REMCLOSE; break; case G_IO_CHANNEL_ERROR_ISDIR: case G_IO_CHANNEL_ERROR_OVERFLOW: default: err = GE_OSERR; } if (err == GE_OSERR) { gensio_log(o, GENSIO_LOG_INFO, "Unhandled glib error: %s (%d)", ierr->message, ierr->code); } return err; } static int gensio_glib_write(struct gensio_iod *iiod, const struct gensio_sg *sg, gensiods sglen, gensiods *rcount) { struct gensio_iod_glib *iod = i_to_glib(iiod); gensiods i; gensiods count = 0; GIOStatus st; GError *err = NULL; gsize size; int rv = 0; for (i = 0; i < sglen; i++) { st = g_io_channel_write_chars(iod->chan, sg[i].buf, sg[i].buflen, &size, &err); switch (st) { case G_IO_STATUS_NORMAL: count += size; break; case G_IO_STATUS_EOF: rv = GE_REMCLOSE; goto out; case G_IO_STATUS_ERROR: rv = glib_err_to_err(iiod->f, err); goto out; case G_IO_STATUS_AGAIN: rv = 0; goto out; default: assert(0); } } out: if (!rv) *rcount = count; return rv; } static int gensio_glib_read(struct gensio_iod *iiod, void *buf, gensiods buflen, gensiods *rcount) { struct gensio_iod_glib *iod = i_to_glib(iiod); gensiods count = 0; GIOStatus st; GError *err = NULL; gsize size; int rv = 0; st = g_io_channel_read_chars(iod->chan, buf, buflen, &size, &err); switch (st) { case G_IO_STATUS_NORMAL: count = size; break; case G_IO_STATUS_EOF: rv = GE_REMCLOSE; goto out; case G_IO_STATUS_ERROR: rv = glib_err_to_err(iiod->f, err); goto out; case G_IO_STATUS_AGAIN: rv = 0; goto out; default: assert(0); } out: if (!rv) *rcount = count; return rv; } static bool gensio_glib_is_regfile(struct gensio_os_funcs *o, intptr_t fd) { #ifdef _WIN32 switch (fd) { case 0: return GetFileType(GetStdHandle(STD_INPUT_HANDLE)) == FILE_TYPE_DISK; case 1: return GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) == FILE_TYPE_DISK; case 2: return GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == FILE_TYPE_DISK; } return GetFileType((HANDLE) fd) == FILE_TYPE_DISK; #else int err; struct stat statb; err = fstat(fd, &statb); if (err == -1) return false; return (statb.st_mode & S_IFMT) == S_IFREG; #endif } static int gensio_glib_bufcount(struct gensio_iod *iiod, int whichbuf, gensiods *count) { #ifdef _WIN32 /* FIXME - any way to do this? */ *count = 0; return 0; #else struct gensio_iod_glib *iod = i_to_glib(iiod); return gensio_unix_get_bufcount(iiod->f, iod->fd, whichbuf, count); #endif } static void gensio_glib_flush(struct gensio_iod *iiod, int whichbuf) { struct gensio_iod_glib *iod = i_to_glib(iiod); GError *err = NULL; g_io_channel_flush(iod->chan, &err); } static int gensio_glib_makeraw(struct gensio_iod *iiod) { struct gensio_iod_glib *iod = i_to_glib(iiod); #ifdef _WIN32 if (iod->type == GENSIO_IOD_STDIO) { if (iod->fd != 0) /* * Nothing to do for stdout. Disabling ENABLE_PROCESSED_OUTPUT * is not a good thing to do. */ return 0; return gensio_win_stdio_makeraw(iiod->f, iod->h, &iod->mode); } else if (iod->type == GENSIO_IOD_DEV) { return 0; /* Nothing to do. */ } else if (iod->type == GENSIO_IOD_PIPE) { return 0; /* Nothing to do. */ } return GE_NOTSUP; #else if (iod->orig_fd == 1 || iod->orig_fd == 2 || iod->type == GENSIO_IOD_FILE) /* Only set this for stdin or other files. */ return 0; return gensio_unix_setup_termios(iiod->f, iod->fd, &iod->termios); #endif } static int gensio_glib_open_dev(struct gensio_os_funcs *o, const char *iname, int options, struct gensio_iod **riod) { #ifdef _WIN32 int rv; HANDLE h = NULL; COMMPROP props; char *name = gensio_alloc_sprintf(o, "\\\\.\\%s", iname); struct gensio_iod *iiod = NULL; struct gensio_iod_glib *iod; if (!name) return GE_NOMEM; h = CreateFileA(name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); free(name); if (!h) goto out_err_conv; if (GetFileType(h) != FILE_TYPE_CHAR) { rv = GE_NOTSUP; goto out_err; } rv = o->add_iod(o, GENSIO_IOD_DEV, (intptr_t) h, &iiod); if (rv) goto out_err; iod = i_to_glib(iiod); if (!GetCommProperties(h, &props)) goto out_err_conv; switch (props.dwProvSubType) { case PST_MODEM: case PST_RS232: case PST_RS422: case PST_RS423: case PST_RS449: rv = gensio_win_setup_commport(o, h, &iod->comminfo, &biod->extrah); if (rv) goto out_err; break; case PST_PARALLELPORT: break; default: rv = GE_NOTSUP; goto out_err; } *riod = iiod; return 0; out_err_conv: rv = gensio_os_err_to_err(o, GetLastError()); out_err: if (iod) o->close(iod); else if (h) CloseHandle(h); return rv; #else int flags, fd, err; flags = O_NONBLOCK | O_NOCTTY; if (options & (GENSIO_OPEN_OPTION_READABLE | GENSIO_OPEN_OPTION_WRITEABLE)) flags |= O_RDWR; else if (options & GENSIO_OPEN_OPTION_READABLE) flags |= O_RDONLY; else if (options & GENSIO_OPEN_OPTION_WRITEABLE) flags |= O_WRONLY; fd = open(iname, flags); if (fd == -1) return gensio_os_err_to_err(o, errno); err = o->add_iod(o, GENSIO_IOD_DEV, fd, riod); if (err) close(fd); return err; #endif } static void generic_close(intptr_t fd) { #ifdef _WIN32 CloseHandle((handle) fd); #else close(fd); #endif } static int gensio_glib_exec_subprog(struct gensio_os_funcs *o, const char *argv[], const char **env, const char *start_dir, unsigned int flags, intptr_t *rpid, struct gensio_iod **rstdin, struct gensio_iod **rstdout, struct gensio_iod **rstderr) { int err; struct gensio_iod *stdiniod = NULL, *stdoutiod = NULL, *stderriod = NULL; intptr_t infd = -1, outfd = -1, errfd = -1; intptr_t pid = -1; #ifdef _WIN32 HANDLE winfd, woutfd, werrfd = NULL, wpid; err = gensio_win_do_exec(o, argv, env, start_dir, flags, &wpid, &winfd, &woutfd, rstderr ? &werrfd : NULL); if (err) return err; infd = (intptr_t) uinfd; outfd = (intptr_t) uoutfd; errfd = (intptr_t) uerrfd; pid = (intptr_t) upid; #else int uinfd = -1, uoutfd = -1, uerrfd = -1; int upid = -1; err = gensio_unix_do_exec(o, argv, env, start_dir, flags, &upid, &uinfd, &uoutfd, rstderr ? &uerrfd : NULL); if (err) return err; infd = uinfd; outfd = uoutfd; errfd = uerrfd; pid = upid; #endif err = o->add_iod(o, GENSIO_IOD_PIPE, infd, &stdiniod); if (err) goto out_err; infd = -1; err = o->add_iod(o, GENSIO_IOD_PIPE, outfd, &stdoutiod); if (err) goto out_err; outfd = -1; err = o->set_non_blocking(stdiniod); if (err) goto out_err; err = o->set_non_blocking(stdoutiod); if (err) goto out_err; if (rstderr) { err = o->add_iod(o, GENSIO_IOD_PIPE, errfd, &stderriod); if (err) goto out_err; errfd = -1; err = o->set_non_blocking(stderriod); if (err) goto out_err; } *rpid = pid; *rstdin = stdiniod; *rstdout = stdoutiod; if (rstderr) *rstderr = stderriod; return 0; out_err: if (stderriod) o->close(&stderriod); else if (errfd != -1) generic_close(errfd); if (stdiniod) o->close(&stdiniod); else if (infd != -1) generic_close(infd); if (stdoutiod) o->close(&stdoutiod); else if (outfd != -1) generic_close(outfd); return err; } static int gensio_glib_kill_subprog(struct gensio_os_funcs *o, intptr_t pid, bool force) { int rv; rv = kill(pid, force ? SIGKILL : SIGTERM); if (rv < 0) return gensio_os_err_to_err(o, errno); return 0; } static int gensio_glib_wait_subprog(struct gensio_os_funcs *o, intptr_t pid, int *retcode) { pid_t rv; rv = waitpid(pid, retcode, WNOHANG); if (rv < 0) return gensio_os_err_to_err(o, errno); if (rv == 0) return GE_INPROGRESS; return 0; } static int gensio_glib_service(struct gensio_os_funcs *o, gensio_time *timeout) { struct gensio_data *d = o->user_data; struct gensio_wait_thread t; struct timeout_info ti = { .timeout = timeout }; int rv = GE_TIMEDOUT; gensio_list_link_init(&t.global_link); t.count = 0; setup_timeout(&ti); g_mutex_lock(&d->lock); gensio_list_add_tail(&d->waiting_threads, &t.global_link); retry: if (!d->main_context_owner) d->main_context_owner = &t; if (d->main_context_owner == &t) { /* This is the thread that will run the main context. */ t.cond = NULL; d->did_something = false; g_mutex_unlock(&d->lock); timeout_wait(&ti); g_mutex_lock(&d->lock); if (d->did_something) rv = 0; ti.now = g_get_monotonic_time(); } else { /* Not running the main context, just wait on a cond. */ t.cond = &d->cond; if (timeout) g_cond_wait_until(t.cond, &d->lock, ti.end); else g_cond_wait(t.cond, &d->lock); ti.now = g_get_monotonic_time(); if (!timed_out(&ti)) goto retry; } gensio_list_rm(&d->waiting_threads, &t.global_link); if (d->main_context_owner == &t) { d->main_context_owner = NULL; /* Need to get another main context owner. */ gensio_glib_wake_next_thread(&d->waiting_threads, global_link); } g_mutex_unlock(&d->lock); timeout_end(&ti); return rv; } static struct gensio_os_funcs * gensio_glib_get_funcs(struct gensio_os_funcs *f) { struct gensio_data *d = f->user_data; g_mutex_lock(&d->lock); assert(d->refcount > 0); d->refcount++; g_mutex_unlock(&d->lock); return f; } static void gensio_glib_free_funcs(struct gensio_os_funcs *f) { struct gensio_data *d = f->user_data; g_mutex_lock(&d->lock); assert(d->refcount > 0); if (d->refcount > 1) { d->refcount--; g_mutex_unlock(&d->lock); return; } g_mutex_unlock(&d->lock); gensio_stdsock_cleanup(f); gensio_memtrack_cleanup(d->mtrack); g_cond_clear(&d->cond); g_mutex_clear(&d->lock); free(d); free(f); } static void gensio_glib_get_monotonic_time(struct gensio_os_funcs *f, gensio_time *time) { us_time_to_gensio(g_get_monotonic_time(), time); } static int gensio_glib_handle_fork(struct gensio_os_funcs *f) { return 0; } static int gensio_glib_get_random(struct gensio_os_funcs *o, void *data, unsigned int len) { int fd; int rv; fd = open("/dev/urandom", O_RDONLY); if (fd == -1) return gensio_os_err_to_err(o, errno); while (len > 0) { rv = read(fd, data, len); if (rv < 0) { rv = errno; goto out; } len -= rv; data += rv; } rv = 0; out: close(fd); return gensio_os_err_to_err(o, rv); } static int gensio_glib_control(struct gensio_os_funcs *o, int func, void *data, gensiods *datalen) { struct gensio_data *d = o->user_data; switch (func) { case GENSIO_CONTROL_SET_PROC_DATA: d->pdata = data; return 0; default: return GE_NOTSUP; } } int gensio_glib_funcs_alloc(struct gensio_os_funcs **ro) { struct gensio_data *d; struct gensio_os_funcs *o; int err; o = malloc(sizeof(*o)); if (!o) return GE_NOMEM; memset(o, 0, sizeof(*o)); d = malloc(sizeof(*d)); if (!d) { free(o); return GE_NOMEM; } memset(d, 0, sizeof(*d)); d->refcount = 1; o->user_data = d; d->mtrack = gensio_memtrack_alloc(); gensio_list_init(&d->waiting_threads); g_mutex_init(&d->lock); g_cond_init(&d->cond); o->zalloc = gensio_glib_zalloc; o->free = gensio_glib_free; o->alloc_lock = gensio_glib_alloc_lock; o->free_lock = gensio_glib_free_lock; o->lock = gensio_glib_lock; o->unlock = gensio_glib_unlock; o->set_fd_handlers = gensio_glib_set_fd_handlers; o->clear_fd_handlers = gensio_glib_clear_fd_handlers; o->clear_fd_handlers_norpt = gensio_glib_clear_fd_handlers_norpt; o->set_read_handler = gensio_glib_set_read_handler; o->set_write_handler = gensio_glib_set_write_handler; o->set_except_handler = gensio_glib_set_except_handler; o->alloc_timer = gensio_glib_alloc_timer; o->free_timer = gensio_glib_free_timer; o->start_timer = gensio_glib_start_timer; o->start_timer_abs = gensio_glib_start_timer_abs; o->stop_timer = gensio_glib_stop_timer; o->stop_timer_with_done = gensio_glib_stop_timer_with_done; o->alloc_runner = gensio_glib_alloc_runner; o->free_runner = gensio_glib_free_runner; o->run = gensio_glib_run; o->alloc_waiter = gensio_glib_alloc_waiter; o->free_waiter = gensio_glib_free_waiter; o->wait = gensio_glib_wait; o->wait_intr = gensio_glib_wait_intr; o->wait_intr_sigmask = gensio_glib_wait_intr_sigmask; o->wake = gensio_glib_wake; o->service = gensio_glib_service; o->get_funcs = gensio_glib_get_funcs; o->free_funcs = gensio_glib_free_funcs; o->call_once = gensio_call_once; o->get_monotonic_time = gensio_glib_get_monotonic_time; o->handle_fork = gensio_glib_handle_fork; o->add_iod = gensio_glib_add_iod; o->release_iod = gensio_glib_release_iod; o->iod_get_type = gensio_glib_iod_get_type; o->iod_get_fd = gensio_glib_iod_get_fd; o->set_non_blocking = gensio_glib_set_non_blocking; o->close = gensio_glib_close; o->graceful_close = gensio_glib_close; o->write = gensio_glib_write; o->read = gensio_glib_read; o->is_regfile = gensio_glib_is_regfile; o->bufcount = gensio_glib_bufcount; o->flush = gensio_glib_flush; o->makeraw = gensio_glib_makeraw; o->open_dev = gensio_glib_open_dev; o->exec_subprog = gensio_glib_exec_subprog; o->kill_subprog = gensio_glib_kill_subprog; o->wait_subprog = gensio_glib_wait_subprog; o->get_random = gensio_glib_get_random; o->iod_control = gensio_glib_iod_control; o->control = gensio_glib_control; gensio_addr_addrinfo_set_os_funcs(o); err = gensio_stdsock_set_os_funcs(o); if (err) { free(o); free(d); return err; } *ro = o; return 0; } gensio-3.0.0/glib/c++/0000775000175000017500000000000015061121735010027 5gensio-3.0.0/glib/c++/Makefile.in0000664000175000017500000005456215061121657012033 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = glib/c++ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = include tests $(SWIG_DIR) DIST_SUBDIRS = include tests swig all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu glib/c++/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu glib/c++/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/glib/c++/tests/0000775000175000017500000000000015061121735011171 5gensio-3.0.0/glib/c++/tests/Makefile.in0000664000175000017500000011016315061121657013163 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ TESTS = basic_glib_test$(EXEEXT) check_PROGRAMS = basic_glib_test$(EXEEXT) subdir = glib/c++/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am_basic_glib_test_OBJECTS = basic_glib_test.$(OBJEXT) basic_glib_test_OBJECTS = $(am_basic_glib_test_OBJECTS) am__DEPENDENCIES_1 = basic_glib_test_DEPENDENCIES = $(top_builddir)/lib/libgensio.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/glib/libgensioglib.la $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/basic_glib_test.Po am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(basic_glib_test_SOURCES) DIST_SOURCES = $(basic_glib_test_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_srcdir)/c++/include -I$(top_srcdir)/glib/c++/include \ -I$(top_srcdir)/glib/include basic_glib_test_SOURCES = basic_glib_test.cc basic_glib_test_LDADD = $(top_builddir)/lib/libgensio.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/glib/libgensioglib.la \ $(OPENSSL_LIBS) all: all-am .SUFFIXES: .SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu glib/c++/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu glib/c++/tests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list basic_glib_test$(EXEEXT): $(basic_glib_test_OBJECTS) $(basic_glib_test_DEPENDENCIES) $(EXTRA_basic_glib_test_DEPENDENCIES) @rm -f basic_glib_test$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(basic_glib_test_OBJECTS) $(basic_glib_test_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basic_glib_test.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: $(check_PROGRAMS) @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? basic_glib_test.log: basic_glib_test$(EXEEXT) @p='basic_glib_test$(EXEEXT)'; \ b='basic_glib_test'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/basic_glib_test.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/basic_glib_test.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/glib/c++/tests/Makefile.am0000664000175000017500000000075714664224267013172 AM_CPPFLAGS = -I$(top_srcdir)/c++/include -I$(top_srcdir)/glib/c++/include \ -I$(top_srcdir)/glib/include TESTS = basic_glib_test basic_glib_test_SOURCES = basic_glib_test.cc basic_glib_test_LDADD = $(top_builddir)/lib/libgensio.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/glib/libgensioglib.la \ $(OPENSSL_LIBS) check_PROGRAMS = basic_glib_test gensio-3.0.0/glib/c++/tests/basic_glib_test.cc0000664000175000017500000002323314664224267014554 // // Copyright 2021 Corey Minyard // // SPDX-License-Identifier: GPL-2.0-only #include #include #include #include #include using namespace std; using namespace gensios; class Open_Done: public Gensio_Open_Done { public: Open_Done(Gensio *g, Waiter *w): io(g), waiter(w) { } const char *get_err() { return errstr; } private: Gensio *io; const char *errstr = NULL; void open_done(int err) override { if (err) errstr = gensio_err_to_str(err); waiter->wake(); } Waiter *waiter; }; class Close_Done: public Gensio_Close_Done { public: Close_Done(Waiter *w): waiter(w) { } void set_gensio(Gensio *g) { io = g; } private: void close_done() override { io->free(); } Gensio *io; Waiter *waiter; }; class Client_Event: public Event { public: Client_Event(Waiter *w, const unsigned char *data, gensiods datalen): ce(w) { waiter = w; this->data = data; this->datalen = datalen; } void set_gensio(Gensio *g) { io = g; ce.set_gensio(g); } const char *get_err() { return errstr; } private: Gensio *io; gensiods read(int err, SimpleUCharVector idata, const char *const *auxdata) override { if (err) { errstr = gensio_err_to_str(err); io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->close(&ce); return 0; } string str((char *) idata.data(), idata.size()); if (readpos + idata.size() > datalen) { errstr = "Too much data"; io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->close(&ce); return idata.size(); } if (memcmp(data + readpos, idata.data(), idata.size()) != 0) { errstr = "Data mismatch"; io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->close(&ce); return idata.size(); } readpos += idata.size(); if (readpos == datalen) { io->set_read_callback_enable(false); io->close(&ce); } return idata.size(); } void write_ready() override { gensiods count; try { count = io->write(data + writepos, datalen - writepos, NULL); } catch (gensio_error e) { errstr = e.what(); io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->close(&ce); return; } writepos += count; if (writepos == datalen) io->set_write_callback_enable(false); } void freed() override { waiter->wake(); } const char *errstr = NULL; const unsigned char *data; gensiods datalen; gensiods readpos = 0; gensiods writepos = 0; Close_Done ce; Waiter *waiter; }; static int do_client_test(Os_Funcs &o, string ios) { Waiter w(o); Gensio *g; string s("This is a test!\r\n"); const char *errstr; gensio_time waittime = { 2, 0 }; Client_Event e(&w, (unsigned char *) s.c_str(), (gensiods) s.size()); int err; g = gensio_alloc(ios, o, &e); e.set_gensio(g); Open_Done oe(g, &w); try { g->open(&oe); } catch (gensio_error e) { cerr << "Error opening '" << ios << "': " << e.what() << endl; return 1; } err = w.wait(1, &waittime); if (err) { g->free(); cerr << "Error from open wait for '" << ios << "': " << gensio_err_to_str(err) << endl; return 1; } errstr = oe.get_err(); if (errstr) { g->free(); cerr << "Error from open for '" << ios << "': " << errstr << endl; return 1; } g->set_read_callback_enable(true); g->set_write_callback_enable(true); waittime = { 2, 0 }; err = w.wait(1, &waittime); if (err) { cerr << "Error from wait for '" << ios << "': " << gensio_err_to_str(err) << endl; return 1; } errstr = e.get_err(); if (errstr) { cerr << "Error handler '" << ios << "': " << errstr << endl; return 1; } return 0; } class Server_Event: public Event { public: Server_Event(Waiter *w) { waiter = w; } void set_gensio(Gensio *g) { io = g; } const char *get_err() { return errstr; } private: Gensio *io; gensiods read(int err, const SimpleUCharVector data, const char *const *auxdata) override { gensiods count; if (err) { if (err != GE_REMCLOSE) errstr = gensio_err_to_str(err); io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->free(); return 0; } try { count = io->write(data, NULL); } catch (gensio_error e) { errstr = e.what(); io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->free(); return data.size(); } if (count < data.size()) { io->set_read_callback_enable(false); io->set_write_callback_enable(true); } return data.size(); } void write_ready() override { io->set_read_callback_enable(true); io->set_write_callback_enable(false); } void freed() override { waiter->wake(); } const char *errstr = NULL; Waiter *waiter; }; class Acc_Event: public Accepter_Event { public: Acc_Event(Waiter *w, Server_Event *e) { waiter = w; ev = e; } void set_accepter(Accepter *a) { acc = a; } private: void log(enum gensio_log_levels level, const std::string log) override { std::cerr << "accepter " << gensio_log_level_to_str(level) << " log: " << log << std::endl; } void new_connection(Gensio *g) override { io = g; ev->set_gensio(g); g->set_event_handler(ev); ev = NULL; g->set_read_callback_enable(true); g->set_write_callback_enable(true); acc->free(); } void freed() override { waiter->wake(); } Accepter *acc; Gensio *io; Waiter *waiter; Server_Event *ev; }; static void do_server_test(Os_Funcs &o, string ios) { Waiter w(o); Accepter *a; Server_Event e(&w); Acc_Event ae(&w, &e); const char *errstr; a = gensio_acc_alloc(ios, o, &ae); ae.set_accepter(a); try { a->startup(); } catch (gensio_error e) { cerr << "Error opening '" << ios << "': " << e.what() << endl; return; } cout << a->get_port() << endl; a->set_callback_enable(true); w.wait(2, NULL); errstr = e.get_err(); if (errstr) { cerr << "Server error handling '" << ios << "': " << errstr << endl; } } // Internal gensio errors come in through this mechanism. class Logger: public Os_Funcs_Log_Handler { void log(enum gensio_log_levels level, const std::string log) override { std::cerr << "gensio " << gensio_log_level_to_str(level) << " log: " << log << std::endl; } }; class Sub_Event: public Event { public: Sub_Event(Waiter *w) { waiter = w; } void set_gensio(Gensio *g) { io = g; } const char *get_err() { return errstr; } string get_port() { return string(port, portpos); } private: Gensio *io; gensiods read(int err, const SimpleUCharVector data, const char *const *auxdata) override { gensiods i; if (portfound) { io->set_read_callback_enable(false); return 0; } if (err) { io->set_read_callback_enable(false); waiter->wake(); errstr = "subprogram failed before reading port"; return 0; } for (i = 0; i < data.size(); i++) { if (portpos >= sizeof(port)) { errstr = "Port from sub too large"; waiter->wake(); io->set_read_callback_enable(false); return i; } if (data[i] == '\n' || data[i] == '\r') { port[portpos] = '\0'; portfound = true; waiter->wake(); io->set_read_callback_enable(false); return i; } port[portpos++] = data[i]; } return i; } void write_ready() override { io->set_write_callback_enable(false); } void freed() override { waiter->wake(); } char port[100]; gensiods portpos = 0; bool portfound = false; const char *errstr = NULL; Waiter *waiter; }; int main(int argc, char *argv[]) { int err = 0; Glib_Os_Funcs o(new Logger); const char *test = "mux,tcp,localhost,"; const char *errstr; o.proc_setup(); if (argc > 1) { do_server_test(o, argv[1]); } else { char *s; string ios("stdio(noredir-stderr),"); string ioc(test); Gensio *sub; Waiter w(o); Sub_Event se(&w); gensio_time waittime = { 2, 0 }; int err2; char buf[10]; gensiods len = sizeof(buf); cout << "Starting subprogram to act as a server" << endl; s = gensio_quote_string(o, argv[0]); if (!s) { cerr << "Out of memory duplicating argv[0]" << endl; err = 1; goto out; } ios += s; gensio_os_funcs_zfree(o, s); ios += " "; ios += test; ios += "0"; try { sub = gensio_alloc(ios, o, &se); } catch (gensio_error e) { cerr << "Unable to open " << ios << ": " << e.what() << endl; err = 1; goto out; } se.set_gensio(sub); sub->open_s(); sub->set_read_callback_enable(true); err = w.wait(1, &waittime); if (err) { cerr << "Error from sub wait for '" << ios << "': " << gensio_err_to_str(err) << endl; err = 1; } else { errstr = se.get_err(); if (errstr) { cerr << "Unable to handle sub " << ios << ": " << errstr << endl; err = 1; } else { ioc += se.get_port(); cout << "Connecting to " << ioc << endl; err = do_client_test(o, ioc); } } cout << "Closing sub program" << endl; sub->close_s(); err2 = sub->control(0, true, GENSIO_CONTROL_EXIT_CODE, buf, &len); if (err2) { cerr << "Error getting exit code: " << gensio_err_to_str(err2) << endl; err = 1; } err2 = strtoul(buf, NULL, 0); if (err2) { cerr << "Error from subprogram: " << err2 << endl; err = 1; } sub->free(); waittime = { 2, 0 }; err2 = w.wait(1, &waittime); if (err2) { cerr << "Error from sub wait for '" << ios << "': " << gensio_err_to_str(err2) << endl; err = 1; } } out: if (!err) cout << "Success!" << endl; return err; } gensio-3.0.0/glib/c++/swig/0000775000175000017500000000000015061121735011000 5gensio-3.0.0/glib/c++/swig/Makefile.in0000664000175000017500000005455715061121657013010 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = glib/c++/swig ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = . $(PYGENSIO_DIR) DIST_SUBDIRS = pygensio all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu glib/c++/swig/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu glib/c++/swig/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/glib/c++/swig/Makefile.am0000664000175000017500000000006414664224267012770 SUBDIRS = . $(PYGENSIO_DIR) DIST_SUBDIRS = pygensio gensio-3.0.0/glib/c++/swig/pygensio/0000775000175000017500000000000015061121735012635 5gensio-3.0.0/glib/c++/swig/pygensio/Makefile.in0000664000175000017500000006500415061121657014632 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = glib/c++/swig/pygensio ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pythonlibdir)" LTLIBRARIES = $(pythonlib_LTLIBRARIES) am__DEPENDENCIES_1 = _pygensioglib_la_DEPENDENCIES = \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/glib/libgensioglib.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) nodist__pygensioglib_la_OBJECTS = pygensioglib_wrap.lo _pygensioglib_la_OBJECTS = $(nodist__pygensioglib_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = _pygensioglib_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(AM_CXXFLAGS) $(CXXFLAGS) $(_pygensioglib_la_LDFLAGS) \ $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/pygensioglib_wrap.Plo am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(nodist__pygensioglib_la_SOURCES) DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = $(PYTHON_CPPFLAGS) \ -I$(top_srcdir)/glib/c++/include -I$(top_srcdir)/glib/include \ -I$(top_srcdir)/c++/swig/pygensio/include pythonlibdir = $(PYTHON_INSTALL_LIB_DIR) pythonlib_LTLIBRARIES = _pygensioglib.la EXTRA_DIST = pygensioglib.i nodist__pygensioglib_la_SOURCES = pygensioglib_wrap.cc _pygensioglib_la_LIBADD = $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/glib/libgensioglib.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(OPENSSL_LIBS) $(PYTHON_UNDEF_LIBS) _pygensioglib_la_LDFLAGS = -module -avoid-version $(OPENSSL_LDFLAGS) \ $(PYTHON_UNDEF_FLAG) $(PYTHON_EXT_EXT_SET) all: all-am .SUFFIXES: .SUFFIXES: .cc .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu glib/c++/swig/pygensio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu glib/c++/swig/pygensio/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pythonlibLTLIBRARIES: $(pythonlib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pythonlib_LTLIBRARIES)'; test -n "$(pythonlibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pythonlibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pythonlibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pythonlibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pythonlibdir)"; \ } uninstall-pythonlibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pythonlib_LTLIBRARIES)'; test -n "$(pythonlibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pythonlibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pythonlibdir)/$$f"; \ done clean-pythonlibLTLIBRARIES: -test -z "$(pythonlib_LTLIBRARIES)" || rm -f $(pythonlib_LTLIBRARIES) @list='$(pythonlib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } _pygensioglib.la: $(_pygensioglib_la_OBJECTS) $(_pygensioglib_la_DEPENDENCIES) $(EXTRA__pygensioglib_la_DEPENDENCIES) $(AM_V_CXXLD)$(_pygensioglib_la_LINK) -rpath $(pythonlibdir) $(_pygensioglib_la_OBJECTS) $(_pygensioglib_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pygensioglib_wrap.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pythonlibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local \ clean-pythonlibLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/pygensioglib_wrap.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pythonlibLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-exec-local install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/pygensioglib_wrap.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local uninstall-pythonlibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-local \ clean-pythonlibLTLIBRARIES cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-exec-local install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-pythonlibLTLIBRARIES install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-local \ uninstall-pythonlibLTLIBRARIES .PRECIOUS: Makefile pygensioglib_wrap.cc pygensioglib.py: \ $(top_srcdir)/c++/swig/include/gensio_base.i \ $(top_srcdir)/c++/swig/pygensio/pygensio.i \ $(top_srcdir)/glib/c++/swig/pygensio/pygensioglib.i \ $(top_srcdir)/c++/include/gensio $(SWIG) $(DEFS) -Wall -python $(PYTHON_SWIG_FLAGS) \ -o pygensioglib_wrap.cc -c++ \ -I$(top_srcdir)/glib/c++/include \ -I$(top_srcdir)/c++/swig/include \ -I$(top_srcdir)/c++/swig/pygensio -I$(top_srcdir)/c++/include \ -I$(top_srcdir)/include -I$(top_builddir)/include \ $(top_srcdir)/glib/c++/swig/pygensio/pygensioglib.i clean-local: rm -rf __pycache__ pygensioglib_wrap.cc pygensioglib_wrap.h \ pygensioglib.py install-exec-local: _pygensioglib.la pygensioglib.py $(INSTALL) -d $(DESTDIR)$(PYTHON_INSTALL_DIR) $(INSTALL_DATA) pygensioglib.py "$(DESTDIR)$(PYTHON_INSTALL_DIR)" uninstall-local: $(LIBTOOL) --mode=uninstall \ rm -f "$(DESTDIR)$(PYTHON_INSTALL_LIB_DIR)/_pygensioglib.$(PYTHON_EXT_EXT)" rm -f "$(DESTDIR)$(PYTHON_INSTALL_DIR)/pygensioglib.py" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/glib/c++/swig/pygensio/Makefile.am0000664000175000017500000000320214664224267014622 AM_CPPFLAGS = $(PYTHON_CPPFLAGS) \ -I$(top_srcdir)/glib/c++/include -I$(top_srcdir)/glib/include \ -I$(top_srcdir)/c++/swig/pygensio/include pythonlibdir=$(PYTHON_INSTALL_LIB_DIR) pythonlib_LTLIBRARIES = _pygensioglib.la pygensioglib_wrap.cc pygensioglib.py: \ $(top_srcdir)/c++/swig/include/gensio_base.i \ $(top_srcdir)/c++/swig/pygensio/pygensio.i \ $(top_srcdir)/glib/c++/swig/pygensio/pygensioglib.i \ $(top_srcdir)/c++/include/gensio $(SWIG) $(DEFS) -Wall -python $(PYTHON_SWIG_FLAGS) \ -o pygensioglib_wrap.cc -c++ \ -I$(top_srcdir)/glib/c++/include \ -I$(top_srcdir)/c++/swig/include \ -I$(top_srcdir)/c++/swig/pygensio -I$(top_srcdir)/c++/include \ -I$(top_srcdir)/include -I$(top_builddir)/include \ $(top_srcdir)/glib/c++/swig/pygensio/pygensioglib.i EXTRA_DIST = pygensioglib.i nodist__pygensioglib_la_SOURCES = pygensioglib_wrap.cc _pygensioglib_la_LIBADD = $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/glib/libgensioglib.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(OPENSSL_LIBS) $(PYTHON_UNDEF_LIBS) _pygensioglib_la_LDFLAGS = -module -avoid-version $(OPENSSL_LDFLAGS) \ $(PYTHON_UNDEF_FLAG) $(PYTHON_EXT_EXT_SET) clean-local: rm -rf __pycache__ pygensioglib_wrap.cc pygensioglib_wrap.h \ pygensioglib.py install-exec-local: _pygensioglib.la pygensioglib.py $(INSTALL) -d $(DESTDIR)$(PYTHON_INSTALL_DIR) $(INSTALL_DATA) pygensioglib.py "$(DESTDIR)$(PYTHON_INSTALL_DIR)" uninstall-local: $(LIBTOOL) --mode=uninstall \ rm -f "$(DESTDIR)$(PYTHON_INSTALL_LIB_DIR)/_pygensioglib.$(PYTHON_EXT_EXT)" rm -f "$(DESTDIR)$(PYTHON_INSTALL_DIR)/pygensioglib.py" gensio-3.0.0/glib/c++/swig/pygensio/pygensioglib.i0000664000175000017500000000122214664224267015433 %module pygensioglib %{ #include #include using namespace gensios; %} %import %catches(gensios::gensio_error) gensios::Glib_Os_Funcs::Glib_Os_Funcs; %extend gensios::Glib_Os_Funcs { Glib_Os_Funcs(gensios::Os_Funcs_Log_Handler *logger = NULL) { gensios::Os_Funcs_Log_Handler *int_handler = NULL; if (logger) int_handler = new Internal_Log_Handler(logger); return new gensios::Glib_Os_Funcs(int_handler); } ~Glib_Os_Funcs() { delete self; } } %ignore gensios::Glib_Os_Funcs::Glib_Os_Funcs; %ignore gensios::Glib_Os_Funcs::~Glib_Os_Funcs; %include gensio-3.0.0/glib/c++/Makefile.am0000664000175000017500000000011014664224267012007 SUBDIRS = include tests $(SWIG_DIR) DIST_SUBDIRS = include tests swig gensio-3.0.0/glib/c++/include/0000775000175000017500000000000015061121735011452 5gensio-3.0.0/glib/c++/include/Makefile.in0000664000175000017500000005455315061121657013456 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = glib/c++/include ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = gensio DIST_SUBDIRS = gensio all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu glib/c++/include/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu glib/c++/include/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/glib/c++/include/Makefile.am0000664000175000017500000000005114664224267013436 SUBDIRS = gensio DIST_SUBDIRS = gensio gensio-3.0.0/glib/c++/include/gensio/0000775000175000017500000000000015061121735012736 5gensio-3.0.0/glib/c++/include/gensio/gensioglib0000664000175000017500000000123114664224267014734 // // gensio - A library for abstracting stream I/O // Copyright (C) 2022 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only // This is a C++ wrapper for the gensio library. #ifndef GENSIOGLIB_CPP_INCLUDE #define GENSIOGLIB_CPP_INCLUDE #include namespace gensios { #include class Glib_Os_Funcs: public Os_Funcs { public: Glib_Os_Funcs(Os_Funcs_Log_Handler *logger = NULL) : Os_Funcs(false) { struct gensio_os_funcs *o; int err = gensio_glib_funcs_alloc(&o); if (err) throw gensio_error(err); init(o, logger); } }; } #endif /* GENSIOGLIB_CPP_INCLUDE */ gensio-3.0.0/glib/c++/include/gensio/Makefile.in0000664000175000017500000005073415061121657014737 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = glib/c++/include/gensio ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(pkginclude_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkgincludedir)" HEADERS = $(pkginclude_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkginclude_HEADERS = gensioglib all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu glib/c++/include/gensio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu glib/c++/include/gensio/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkgincludeHEADERS: $(pkginclude_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ done uninstall-pkgincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pkgincludeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkgincludeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool cscopelist-am ctags ctags-am distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkgincludeHEADERS install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-pkgincludeHEADERS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/glib/c++/include/gensio/Makefile.am0000664000175000017500000000004014664224267014720 pkginclude_HEADERS = gensioglib gensio-3.0.0/glib/gensio_glib_funcs_alloc.30000664000175000017500000000317714664224267014340 .TH gensio_glib_funcs_alloc 3 "03 Feb 2021" .SH NAME gensio_glib_funcs_alloc \- Abstraction for some operating system functions done with glib .SH SYNOPSIS .B #include .PP .B int gensio_glib_funcs_alloc(struct gensio_os_funcs **o) .SH "DESCRIPTION" This structure provides an abstraction for the gensio library that lets it work on top of glib. See the gensio_os_funcs.3 man page for details on what this does. This can be used if you have a project based on glib that you want to integrate gensio into. Unfortunately, it has some limitations because of weaknesses in the glib interface. If you use this, you really want to use the gensio wait functions, not g_cont_wait..() yourself. You don't strictly have have to, especially if your app is single threaded, but especially in multithreaded apps you cannot mix calls to the os funcs wait functions and the glib wait functions. Which means you can't use the blocking functions, which all use os func waiters. Performance should be ok for a single thread. For multiple threads, though, only on thing at a time can be waiting on the main glib thread. This is a weakness in glib. For multiple threads, one function sits in the main context and the others sit on condition variables. When the thead sitting on the main context wakes up, it wakes another waiting thread to take over. If performance is important, it might be better to put glib on top of gensio os funcs with .B g_main_context_set_poll_func(). I leave that as an exercise to the reader. .SH "RETURN VALUES" .B A gensio_err returns a standard gensio error. .SH "SEE ALSO" gensio_os_funcs(3), gensio(5), gensio_err(3) gensio-3.0.0/glib/libgensioglib.pc.in0000664000175000017500000000044214664224267013155 prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libgensioglib Description: A library to abstract stream I/O like serial port, TCP, telnet, UDP, SSL, IPMI SOL, etc. Version: @VERSION@ Libs: -L${libdir} -lgensioglib -lgensio Libs.private: @GLIB_LIBS@ gensio-3.0.0/glib/swig/0000775000175000017500000000000015061121735010430 5gensio-3.0.0/glib/swig/Makefile.in0000664000175000017500000005457115061121657012434 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = glib/swig ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = gensioglib.i SUBDIRS = . $(PYTHON_DIR) DIST_SUBDIRS = python all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu glib/swig/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu glib/swig/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/glib/swig/Makefile.am0000664000175000017500000000011414664224267012414 EXTRA_DIST = gensioglib.i SUBDIRS = . $(PYTHON_DIR) DIST_SUBDIRS = python gensio-3.0.0/glib/swig/gensioglib.i0000664000175000017500000000166014664224267012663 %module gensioglib %import %{ #include "config.h" #include #include #include #include #include struct gensio_os_funcs *alloc_glib_os_funcs(swig_cb *log_handler) { struct gensio_os_funcs *o; int err; err = gensio_glib_funcs_alloc(&o); if (err) { fprintf(stderr, "Unable to allocate gensio os funcs: %s, giving up\n", gensio_err_to_str(err)); exit(1); } err = gensio_swig_setup_os_funcs(o, log_handler); if (err) { fprintf(stderr, "Unable to set up gensio os funcs: %s, giving up\n", gensio_err_to_str(err)); exit(1); } return o; } %} %nodefaultctor gensio_os_funcs; struct gensio_os_funcs { }; %extend gensio_os_funcs { ~gensio_os_funcs() { check_os_funcs_free(self); } } %newobject alloc_glib_os_funcs; struct gensio_os_funcs *alloc_glib_os_funcs(swig_cb *log_handler); gensio-3.0.0/glib/swig/python/0000775000175000017500000000000015061121735011751 5gensio-3.0.0/glib/swig/python/Makefile.in0000664000175000017500000006406315061121657013752 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = glib/swig/python ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pythonlibdir)" LTLIBRARIES = $(pythonlib_LTLIBRARIES) am__DEPENDENCIES_1 = _gensioglib_la_DEPENDENCIES = $(top_builddir)/glib/libgensioglib.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la $(am__DEPENDENCIES_1) \ $(top_builddir)/swig/python/libgensio_python_swig.la \ $(am__DEPENDENCIES_1) nodist__gensioglib_la_OBJECTS = gensioglib_wrap.lo _gensioglib_la_OBJECTS = $(nodist__gensioglib_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = _gensioglib_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(_gensioglib_la_LDFLAGS) $(LDFLAGS) -o \ $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/gensioglib_wrap.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(nodist__gensioglib_la_SOURCES) DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = $(PYTHON_CPPFLAGS) \ -I $(top_srcdir)/include \ -I$(top_builddir)/include \ -I $(top_srcdir) \ -I$(top_srcdir)/glib/include \ -I$(top_srcdir)/swig/include \ -DPYTHON_HAS_THREADS=@PYTHON_HAS_THREADS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pythonlibdir = $(PYTHON_INSTALL_LIB_DIR) pythonlib_LTLIBRARIES = _gensioglib.la nodist__gensioglib_la_SOURCES = gensioglib_wrap.c _gensioglib_la_LIBADD = $(top_builddir)/glib/libgensioglib.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(OPENSSL_LIBS) \ $(top_builddir)/swig/python/libgensio_python_swig.la \ $(PYTHON_UNDEF_LIBS) _gensioglib_la_LDFLAGS = -module -avoid-version $(OPENSSL_LDFLAGS) \ $(PYTHON_UNDEF_FLAG) $(PYTHON_EXT_EXT_SET) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu glib/swig/python/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu glib/swig/python/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pythonlibLTLIBRARIES: $(pythonlib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pythonlib_LTLIBRARIES)'; test -n "$(pythonlibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pythonlibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pythonlibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pythonlibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pythonlibdir)"; \ } uninstall-pythonlibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pythonlib_LTLIBRARIES)'; test -n "$(pythonlibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pythonlibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pythonlibdir)/$$f"; \ done clean-pythonlibLTLIBRARIES: -test -z "$(pythonlib_LTLIBRARIES)" || rm -f $(pythonlib_LTLIBRARIES) @list='$(pythonlib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } _gensioglib.la: $(_gensioglib_la_OBJECTS) $(_gensioglib_la_DEPENDENCIES) $(EXTRA__gensioglib_la_DEPENDENCIES) $(AM_V_CCLD)$(_gensioglib_la_LINK) -rpath $(pythonlibdir) $(_gensioglib_la_OBJECTS) $(_gensioglib_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensioglib_wrap.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pythonlibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local \ clean-pythonlibLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/gensioglib_wrap.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pythonlibLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-exec-local install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/gensioglib_wrap.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local uninstall-pythonlibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-local \ clean-pythonlibLTLIBRARIES cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-exec-local install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-pythonlibLTLIBRARIES install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-local \ uninstall-pythonlibLTLIBRARIES .PRECIOUS: Makefile gensioglib_wrap.c gensioglib.py: $(top_srcdir)/glib/swig/gensioglib.i $(SWIG) $(DEFS) -python $(PYTHON_SWIG_FLAGS) -o gensioglib_wrap.c \ -I$(top_srcdir)/include -I$(top_srcdir)/swig/include \ $(top_srcdir)/glib/swig/gensioglib.i clean-local: rm -rf __pycache__ gensioglib_wrap.c gensioglib.py install-exec-local: _gensioglib.la gensioglib.py $(INSTALL) -d $(DESTDIR)$(PYTHON_INSTALL_DIR) $(INSTALL_DATA) gensioglib.py "$(DESTDIR)$(PYTHON_INSTALL_DIR)" uninstall-local: $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(PYTHON_INSTALL_LIB_DIR)/_gensioglib.$(PYTHON_EXT_EXT)" rm -f "$(DESTDIR)$(PYTHON_INSTALL_DIR)/gensioglib.py" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/glib/swig/python/Makefile.am0000664000175000017500000000252714664224267013747 AM_CFLAGS = $(PYTHON_CPPFLAGS) \ -I $(top_srcdir)/include \ -I$(top_builddir)/include \ -I $(top_srcdir) \ -I$(top_srcdir)/glib/include \ -I$(top_srcdir)/swig/include \ -DPYTHON_HAS_THREADS=@PYTHON_HAS_THREADS@ pythonlibdir=$(PYTHON_INSTALL_LIB_DIR) pythonlib_LTLIBRARIES = _gensioglib.la gensioglib_wrap.c gensioglib.py: $(top_srcdir)/glib/swig/gensioglib.i $(SWIG) $(DEFS) -python $(PYTHON_SWIG_FLAGS) -o gensioglib_wrap.c \ -I$(top_srcdir)/include -I$(top_srcdir)/swig/include \ $(top_srcdir)/glib/swig/gensioglib.i nodist__gensioglib_la_SOURCES = gensioglib_wrap.c _gensioglib_la_LIBADD = $(top_builddir)/glib/libgensioglib.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(OPENSSL_LIBS) \ $(top_builddir)/swig/python/libgensio_python_swig.la \ $(PYTHON_UNDEF_LIBS) _gensioglib_la_LDFLAGS = -module -avoid-version $(OPENSSL_LDFLAGS) \ $(PYTHON_UNDEF_FLAG) $(PYTHON_EXT_EXT_SET) clean-local: rm -rf __pycache__ gensioglib_wrap.c gensioglib.py install-exec-local: _gensioglib.la gensioglib.py $(INSTALL) -d $(DESTDIR)$(PYTHON_INSTALL_DIR) $(INSTALL_DATA) gensioglib.py "$(DESTDIR)$(PYTHON_INSTALL_DIR)" uninstall-local: $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(PYTHON_INSTALL_LIB_DIR)/_gensioglib.$(PYTHON_EXT_EXT)" rm -f "$(DESTDIR)$(PYTHON_INSTALL_DIR)/gensioglib.py" gensio-3.0.0/glib/Makefile.am0000664000175000017500000000155314664224267011453 AM_CPPFLAGS = -DBUILDING_GENSIOGLIB_DLL AM_CFLAGS = -I$(top_srcdir)/glib/include @EXTRA_CFLAGS@ lib_LTLIBRARIES = libgensioglib.la libgensioglib_la_SOURCES = gensio_glib.c libgensioglib_la_CFLAGS = $(GLIB_CFLAGS) $(AM_CFLAGS) libgensioglib_la_LIBADD = $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ @OPENSSL_LIBS@ @GLIB_LIBS@ libgensioglib_la_LDFLAGS = -no-undefined -rpath $(libdir) \ -version-info $(GENSIO_LIB_VERSION) -fvisibility=hidden SUBDIRS = . $(SWIG_DIR) include $(CPLUSPLUS_DIR) DIST_SUBDIRS = swig include c++ # This variable must have 'exec' in its name, in order to be installed # by 'install-exec' target (instead of default 'install-data') pkgconfigexecdir = $(libdir)/pkgconfig pkgconfigexec_DATA = libgensioglib.pc if INSTALL_DOC man3_MANS = gensio_glib_funcs_alloc.3 endif EXTRA_DIST = libgensioglib.pc.in $(man3_MANS) gensio-3.0.0/glib/include/0000775000175000017500000000000015061121735011102 5gensio-3.0.0/glib/include/Makefile.in0000664000175000017500000005454315061121657013105 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = glib/include ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = gensio all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu glib/include/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu glib/include/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/glib/include/Makefile.am0000664000175000017500000000002214664224267013064 SUBDIRS = gensio gensio-3.0.0/glib/include/gensio/0000775000175000017500000000000015061121735012366 5gensio-3.0.0/glib/include/gensio/Makefile.in0000664000175000017500000005075715061121657014374 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = glib/include/gensio ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(pkginclude_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkgincludedir)" HEADERS = $(pkginclude_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkginclude_HEADERS = gensio_glib.h gensio_glib_dllvisibility.h all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu glib/include/gensio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu glib/include/gensio/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkgincludeHEADERS: $(pkginclude_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ done uninstall-pkgincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pkgincludeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkgincludeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool cscopelist-am ctags ctags-am distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkgincludeHEADERS install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-pkgincludeHEADERS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/glib/include/gensio/gensio_glib.h0000664000175000017500000000076714664224267014766 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #ifndef GENSIO_GLIB_H #define GENSIO_GLIB_H #ifdef __cplusplus extern "C" { #endif #include #include /* * Allocate a glib-based os funcs. */ GENSIOGLIB_DLL_PUBLIC int gensio_glib_funcs_alloc(struct gensio_os_funcs **o); #ifdef __cplusplus } #endif #endif /* GENSIO_GLIB_H */ gensio-3.0.0/glib/include/gensio/gensio_glib_dllvisibility.h0000664000175000017500000000225014664224267017716 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #ifndef GENSIOGLIB_DLLVISIBILITY #define GENSIOGLIB_DLLVISIBILITY #if defined GENSIO_LINK_STATIC #define GENSIOGLIB_DLL_PUBLIC #define GENSIOGLIB_DLL_LOCAL #elif defined _WIN32 || defined __CYGWIN__ #ifdef BUILDING_GENSIOGLIB_DLL #ifdef __GNUC__ #define GENSIOGLIB_DLL_PUBLIC __attribute__ ((dllexport)) #else #define GENSIOGLIB_DLL_PUBLIC __declspec(dllexport) // Note: actually gcc seems to also supports this syntax. #endif #else #ifdef __GNUC__ #define GENSIOGLIB_DLL_PUBLIC __attribute__ ((dllimport)) #else #define GENSIOGLIB_DLL_PUBLIC __declspec(dllimport) // Note: actually gcc seems to also supports this syntax. #endif #endif #define GENSIOGLIB_DLL_LOCAL #else #if __GNUC__ >= 4 #define GENSIOGLIB_DLL_PUBLIC __attribute__ ((visibility ("default"))) #define GENSIOGLIB_DLL_LOCAL __attribute__ ((visibility ("hidden"))) #else #define GENSIOGLIB_DLL_PUBLIC #define GENSIOGLIB_DLL_LOCAL #endif #endif #endif /* GENSIOGLIB_DLLVISIBILITY */ gensio-3.0.0/glib/include/gensio/Makefile.am0000664000175000017500000000010014664224267014345 pkginclude_HEADERS = gensio_glib.h gensio_glib_dllvisibility.h gensio-3.0.0/Makefile.in0000664000175000017500000007422515061121657010544 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @INSTALL_DOC_TRUE@am__append_1 = man subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir distdir-am dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \ COPYING COPYING.LIB ChangeLog INSTALL NEWS README TODO ar-lib \ compile config.guess config.sub depcomp install-sh ltmain.sh \ missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip # Exists only to be overridden by the user if desired. AM_DISTCHECK_DVI_TARGET = dvi distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = lib $(SWIG_DIR) $(CPLUSPLUS_DIR) include $(GLIB_DIR) \ $(TCL_DIR) tests tools examples $(am__append_1) DIST_SUBDIRS = lib swig c++ include glib tcl tests tools examples man EXTRA_DIST = README.rst reconf ISSUES TODO # Set distcheck up so python files get installed someplace that will # work, and enable internal trace so oomtest will work. AM_DISTCHECK_CONFIGURE_FLAGS = --enable-internal-trace \ --with-pythoninstall=$(abs_top_builddir)/$(distdir)/_inst/lib/python \ --with-pythoninstalllib=$(abs_top_builddir)/$(distdir)/_inst/lib/python all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-zstd: distdir tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ *.tar.zst*) \ zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) all install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ dist-xz dist-zip dist-zstd distcheck distclean \ distclean-generic distclean-hdr distclean-libtool \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile clean_keys: rm -rf c++/swig/go/tests/ca rm -rf c++/swig/pygensio/tests/ca rm -rf tests/ca # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/tcl/0000775000175000017500000000000015061121735007324 5gensio-3.0.0/tcl/Makefile.in0000664000175000017500000010267415061121660011320 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = tcl ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = libgensiotcl.pc CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)" \ "$(DESTDIR)$(pkgconfigexecdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libgensiotcl_la_DEPENDENCIES = $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la am_libgensiotcl_la_OBJECTS = libgensiotcl_la-gensio_tcl.lo libgensiotcl_la_OBJECTS = $(am_libgensiotcl_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libgensiotcl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libgensiotcl_la_CFLAGS) $(CFLAGS) $(libgensiotcl_la_LDFLAGS) \ $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/libgensiotcl_la-gensio_tcl.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libgensiotcl_la_SOURCES) DIST_SOURCES = $(libgensiotcl_la_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac man3dir = $(mandir)/man3 NROFF = nroff MANS = $(man3_MANS) DATA = $(pkgconfigexec_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/libgensiotcl.pc.in \ $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = -I$(top_srcdir)/tcl/include @EXTRA_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -DBUILDING_GENSIOTCL_DLL lib_LTLIBRARIES = libgensiotcl.la libgensiotcl_la_SOURCES = gensio_tcl.c libgensiotcl_la_CFLAGS = $(TCL_CFLAGS) $(AM_CFLAGS) libgensiotcl_la_LIBADD = $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ @TCL_LIBS@ libgensiotcl_la_LDFLAGS = -no-undefined -rpath $(libdir) \ -version-info $(GENSIO_LIB_VERSION) -fvisibility=hidden SUBDIRS = . $(SWIG_DIR) include $(CPLUSPLUS_DIR) DIST_SUBDIRS = swig include c++ # This variable must have 'exec' in its name, in order to be installed # by 'install-exec' target (instead of default 'install-data') pkgconfigexecdir = $(libdir)/pkgconfig pkgconfigexec_DATA = libgensiotcl.pc @INSTALL_DOC_TRUE@man3_MANS = gensio_tcl_funcs_alloc.3 EXTRA_DIST = libgensiotcl.pc.in $(man3_MANS) all: all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tcl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tcl/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): libgensiotcl.pc: $(top_builddir)/config.status $(srcdir)/libgensiotcl.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libgensiotcl.la: $(libgensiotcl_la_OBJECTS) $(libgensiotcl_la_DEPENDENCIES) $(EXTRA_libgensiotcl_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensiotcl_la_LINK) -rpath $(libdir) $(libgensiotcl_la_OBJECTS) $(libgensiotcl_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensiotcl_la-gensio_tcl.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libgensiotcl_la-gensio_tcl.lo: gensio_tcl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgensiotcl_la_CFLAGS) $(CFLAGS) -MT libgensiotcl_la-gensio_tcl.lo -MD -MP -MF $(DEPDIR)/libgensiotcl_la-gensio_tcl.Tpo -c -o libgensiotcl_la-gensio_tcl.lo `test -f 'gensio_tcl.c' || echo '$(srcdir)/'`gensio_tcl.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensiotcl_la-gensio_tcl.Tpo $(DEPDIR)/libgensiotcl_la-gensio_tcl.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_tcl.c' object='libgensiotcl_la-gensio_tcl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgensiotcl_la_CFLAGS) $(CFLAGS) -c -o libgensiotcl_la-gensio_tcl.lo `test -f 'gensio_tcl.c' || echo '$(srcdir)/'`gensio_tcl.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man3: $(man3_MANS) @$(NORMAL_INSTALL) @list1='$(man3_MANS)'; \ list2=''; \ test -n "$(man3dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.3[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ done; } uninstall-man3: @$(NORMAL_UNINSTALL) @list='$(man3_MANS)'; test -n "$(man3dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) install-pkgconfigexecDATA: $(pkgconfigexec_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfigexec_DATA)'; test -n "$(pkgconfigexecdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigexecdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigexecdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigexecdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigexecdir)" || exit $$?; \ done uninstall-pkgconfigexecDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfigexec_DATA)'; test -n "$(pkgconfigexecdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigexecdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(pkgconfigexecdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-recursive -rm -f ./$(DEPDIR)/libgensiotcl_la-gensio_tcl.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-man install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-libLTLIBRARIES install-pkgconfigexecDATA install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-man3 install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f ./$(DEPDIR)/libgensiotcl_la-gensio_tcl.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-libLTLIBRARIES uninstall-man \ uninstall-pkgconfigexecDATA uninstall-man: uninstall-man3 .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--depfiles check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-libLTLIBRARIES install-man \ install-man3 install-pdf install-pdf-am \ install-pkgconfigexecDATA install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-libLTLIBRARIES uninstall-man \ uninstall-man3 uninstall-pkgconfigexecDATA .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/tcl/c++/0000775000175000017500000000000015061121735007674 5gensio-3.0.0/tcl/c++/Makefile.in0000664000175000017500000005455715061121660011676 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = tcl/c++ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = include tests $(SWIG_DIR) DIST_SUBDIRS = include tests swig all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tcl/c++/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tcl/c++/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/tcl/c++/tests/0000775000175000017500000000000015061121735011036 5gensio-3.0.0/tcl/c++/tests/basic_tcl_test.cc0000664000175000017500000002316414664224267014271 // // Copyright 2021 Corey Minyard // // SPDX-License-Identifier: GPL-2.0-only #include #include #include #include #include using namespace std; using namespace gensios; class Open_Done: public Gensio_Open_Done { public: Open_Done(Waiter *w) { waiter = w; } const char *get_err() { return errstr; } private: const char *errstr = NULL; void open_done(int err) override { if (err) errstr = gensio_err_to_str(err); waiter->wake(); } Waiter *waiter; }; class Close_Done: public Gensio_Close_Done { public: Close_Done(Waiter *w) { waiter = w; } void set_gensio(Gensio *g) { io = g; } private: Gensio *io; void close_done() override { io->free(); } Waiter *waiter; }; class Client_Event: public Event { public: Client_Event(Waiter *w, const unsigned char *data, gensiods datalen): ce(w) { waiter = w; this->data = data; this->datalen = datalen; } void set_gensio(Gensio *g) { io = g; ce.set_gensio(g); } const char *get_err() { return errstr; } private: Gensio *io; gensiods read(int err, SimpleUCharVector idata, const char *const *auxdata) override { if (err) { errstr = gensio_err_to_str(err); io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->close(&ce); return 0; } string str((char *) idata.data(), idata.size()); if (readpos + idata.size() > datalen) { errstr = "Too much data"; io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->close(&ce); return idata.size(); } if (memcmp(data + readpos, idata.data(), idata.size()) != 0) { errstr = "Data mismatch"; io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->close(&ce); return idata.size(); } readpos += idata.size(); if (readpos == datalen) { io->set_read_callback_enable(false); io->close(&ce); } return idata.size(); } void write_ready() override { gensiods count; try { count = io->write(data + writepos, datalen - writepos, NULL); } catch (gensio_error e) { errstr = e.what(); io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->close(&ce); return; } writepos += count; if (writepos == datalen) io->set_write_callback_enable(false); } void freed() override { waiter->wake(); } const char *errstr = NULL; const unsigned char *data; gensiods datalen; gensiods readpos = 0; gensiods writepos = 0; Close_Done ce; Waiter *waiter; }; static int do_client_test(Os_Funcs &o, string ios) { Waiter w(o); Gensio *g; string s("This is a test!\r\n"); Open_Done oe(&w); Client_Event e(&w, (unsigned char *) s.c_str(), (gensiods) s.size()); const char *errstr; gensio_time waittime = { 2, 0 }; int err; g = gensio_alloc(ios, o, &e); e.set_gensio(g); try { g->open(&oe); } catch (gensio_error e) { cerr << "Error opening '" << ios << "': " << e.what() << endl; return 1; } err = w.wait(1, &waittime); if (err) { g->free(); cerr << "Error from open wait for '" << ios << "': " << gensio_err_to_str(err) << endl; return 1; } errstr = oe.get_err(); if (errstr) { g->free(); cerr << "Error from open for '" << ios << "': " << errstr << endl; return 1; } g->set_read_callback_enable(true); g->set_write_callback_enable(true); waittime = { 2, 0 }; err = w.wait(1, &waittime); if (err) { cerr << "Error from wait for '" << ios << "': " << gensio_err_to_str(err) << endl; return 1; } errstr = e.get_err(); if (errstr) { cerr << "Error handler '" << ios << "': " << errstr << endl; return 1; } return 0; } class Server_Event: public Event { public: Server_Event(Waiter *w) { waiter = w; } void set_gensio(Gensio *g) { io = g; } const char *get_err() { return errstr; } private: Gensio *io; gensiods read(int err, const SimpleUCharVector data, const char *const *auxdata) override { gensiods count; if (err) { if (err != GE_REMCLOSE) errstr = gensio_err_to_str(err); io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->free(); return 0; } try { count = io->write(data, NULL); } catch (gensio_error e) { errstr = e.what(); io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->free(); return data.size(); } if (count < data.size()) { io->set_read_callback_enable(false); io->set_write_callback_enable(true); } return data.size(); } void write_ready() override { io->set_read_callback_enable(true); io->set_write_callback_enable(false); } void freed() override { waiter->wake(); } const char *errstr = NULL; Waiter *waiter; }; class Acc_Event: public Accepter_Event { public: Acc_Event(Waiter *w, Server_Event *e) { waiter = w; ev = e; } void set_accepter(Accepter *a) { acc = a; } private: void log(enum gensio_log_levels level, const std::string log) override { std::cerr << "accepter " << gensio_log_level_to_str(level) << " log: " << log << std::endl; } void new_connection(Gensio *g) override { io = g; ev->set_gensio(g); g->set_event_handler(ev); ev = NULL; g->set_read_callback_enable(true); g->set_write_callback_enable(true); acc->free(); } void freed() override { waiter->wake(); } Accepter *acc; Gensio *io; Waiter *waiter; Server_Event *ev; }; static void do_server_test(Os_Funcs &o, string ios) { Waiter w(o); Accepter *a; Server_Event e(&w); Acc_Event ae(&w, &e); const char *errstr; a = gensio_acc_alloc(ios, o, &ae); ae.set_accepter(a); try { a->startup(); } catch (gensio_error e) { cerr << "Error opening '" << ios << "': " << e.what() << endl; return; } cout << a->get_port() << endl; a->set_callback_enable(true); w.wait(2, NULL); errstr = e.get_err(); if (errstr) { cerr << "Server error handling '" << ios << "': " << errstr << endl; } } // Internal gensio errors come in through this mechanism. class Logger: public Os_Funcs_Log_Handler { void log(enum gensio_log_levels level, const std::string log) override { std::cerr << "gensio " << gensio_log_level_to_str(level) << " log: " << log << std::endl; } }; class Sub_Event: public Event { public: Sub_Event(Waiter *w) { waiter = w; } void set_gensio(Gensio *g) { io = g; } const char *get_err() { return errstr; } string get_port() { return string(port, portpos); } private: Gensio *io; gensiods read(int err, const SimpleUCharVector data, const char *const *auxdata) override { gensiods i; if (portfound) { io->set_read_callback_enable(false); return 0; } if (err) { io->set_read_callback_enable(false); waiter->wake(); errstr = "subprogram failed before reading port"; return 0; } for (i = 0; i < data.size(); i++) { if (portpos >= sizeof(port)) { errstr = "Port from sub too large"; waiter->wake(); io->set_read_callback_enable(false); return i; } if (data[i] == '\n' || data[i] == '\r') { port[portpos] = '\0'; portfound = true; waiter->wake(); io->set_read_callback_enable(false); return i; } port[portpos++] = data[i]; } return i; } void write_ready() override { io->set_write_callback_enable(false); } void freed() override { waiter->wake(); } char port[100]; gensiods portpos = 0; bool portfound = false; const char *errstr = NULL; Waiter *waiter; }; int main(int argc, char *argv[]) { int err = 0; Tcl_Os_Funcs o(new Logger); const char *test = "mux,tcp,localhost,"; const char *errstr; o.proc_setup(); if (argc > 1) { do_server_test(o, argv[1]); } else { char *s; string ios("stdio(noredir-stderr),"); string ioc(test); Gensio *sub; Waiter w(o); Sub_Event se(&w); gensio_time waittime = { 2, 0 }; int err2; char buf[10]; gensiods len = sizeof(buf); cout << "Starting subprogram to act as a server" << endl; s = gensio_quote_string(o, argv[0]); if (!s) { cerr << "Out of memory duplicating argv[0]" << endl; err = 1; goto out; } ios += s; gensio_os_funcs_zfree(o, s); ios += " "; ios += test; ios += "0"; try { sub = gensio_alloc(ios, o, &se); } catch (gensio_error e) { cerr << "Unable to open " << ios << ": " << e.what() << endl; err = 1; goto out; } se.set_gensio(sub); sub->open_s(); sub->set_read_callback_enable(true); err = w.wait(1, &waittime); if (err) { cerr << "Error from sub wait for '" << ios << "': " << gensio_err_to_str(err) << endl; err = 1; } else { errstr = se.get_err(); if (errstr) { cerr << "Unable to handle sub " << ios << ": " << errstr << endl; err = 1; } else { ioc += se.get_port(); cout << "Connecting to " << ioc << endl; err = do_client_test(o, ioc); } } cout << "Closing sub program" << endl; sub->close_s(); err2 = sub->control(0, true, GENSIO_CONTROL_EXIT_CODE, buf, &len); if (err2) { cerr << "Error getting exit code: " << gensio_err_to_str(err2) << endl; err = 1; } err2 = strtoul(buf, NULL, 0); if (err2) { cerr << "Error from subprogram: " << err2 << endl; err = 1; } sub->free(); waittime = { 2, 0 }; err2 = w.wait(1, &waittime); if (err2) { cerr << "Error from sub wait for '" << ios << "': " << gensio_err_to_str(err2) << endl; err = 1; } } out: if (!err) cout << "Success!" << endl; return err; } gensio-3.0.0/tcl/c++/tests/Makefile.in0000664000175000017500000011016415061121660013023 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ TESTS = basic_tcl_test$(EXEEXT) check_PROGRAMS = basic_tcl_test$(EXEEXT) subdir = tcl/c++/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am_basic_tcl_test_OBJECTS = basic_tcl_test.$(OBJEXT) basic_tcl_test_OBJECTS = $(am_basic_tcl_test_OBJECTS) am__DEPENDENCIES_1 = basic_tcl_test_DEPENDENCIES = $(top_builddir)/lib/libgensio.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/tcl/libgensiotcl.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/basic_tcl_test.Po am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(basic_tcl_test_SOURCES) DIST_SOURCES = $(basic_tcl_test_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_srcdir)/c++/include -I$(top_srcdir)/tcl/c++/include \ -I$(top_srcdir)/tcl/include basic_tcl_test_SOURCES = basic_tcl_test.cc basic_tcl_test_LDADD = $(top_builddir)/lib/libgensio.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/tcl/libgensiotcl.la \ $(TCL_LIBS) $(OPENSSL_LIBS) all: all-am .SUFFIXES: .SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tcl/c++/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tcl/c++/tests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list basic_tcl_test$(EXEEXT): $(basic_tcl_test_OBJECTS) $(basic_tcl_test_DEPENDENCIES) $(EXTRA_basic_tcl_test_DEPENDENCIES) @rm -f basic_tcl_test$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(basic_tcl_test_OBJECTS) $(basic_tcl_test_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basic_tcl_test.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: $(check_PROGRAMS) @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? basic_tcl_test.log: basic_tcl_test$(EXEEXT) @p='basic_tcl_test$(EXEEXT)'; \ b='basic_tcl_test'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/basic_tcl_test.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/basic_tcl_test.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/tcl/c++/tests/Makefile.am0000664000175000017500000000076214664224267013033 AM_CPPFLAGS = -I$(top_srcdir)/c++/include -I$(top_srcdir)/tcl/c++/include \ -I$(top_srcdir)/tcl/include TESTS = basic_tcl_test basic_tcl_test_SOURCES = basic_tcl_test.cc basic_tcl_test_LDADD = $(top_builddir)/lib/libgensio.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/tcl/libgensiotcl.la \ $(TCL_LIBS) $(OPENSSL_LIBS) check_PROGRAMS = basic_tcl_test gensio-3.0.0/tcl/c++/swig/0000775000175000017500000000000015061121735010645 5gensio-3.0.0/tcl/c++/swig/Makefile.in0000664000175000017500000005455415061121660012644 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = tcl/c++/swig ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = . $(PYGENSIO_DIR) DIST_SUBDIRS = pygensio all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tcl/c++/swig/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tcl/c++/swig/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/tcl/c++/swig/Makefile.am0000664000175000017500000000006614664224267012637 SUBDIRS = . $(PYGENSIO_DIR) DIST_SUBDIRS = pygensio gensio-3.0.0/tcl/c++/swig/pygensio/0000775000175000017500000000000015061121735012502 5gensio-3.0.0/tcl/c++/swig/pygensio/pygensiotcl.i0000664000175000017500000000110014664224267015140 %module pygensiotcl; %{ #include #include using namespace gensios; %} %import %extend gensios::Tcl_Os_Funcs { Tcl_Os_Funcs(gensios::Os_Funcs_Log_Handler *logger = NULL) { gensios::Os_Funcs_Log_Handler *int_handler = NULL; if (logger) int_handler = new Internal_Log_Handler(logger); return new gensios::Tcl_Os_Funcs(int_handler); } ~Tcl_Os_Funcs() { delete self; } } %ignore gensios::Tcl_Os_Funcs::Tcl_Os_Funcs; %ignore gensios::Tcl_Os_Funcs::~Tcl_Os_Funcs; %include gensio-3.0.0/tcl/c++/swig/pygensio/Makefile.in0000664000175000017500000006476415061121660014505 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = tcl/c++/swig/pygensio ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pythonlibdir)" LTLIBRARIES = $(pythonlib_LTLIBRARIES) am__DEPENDENCIES_1 = _pygensiotcl_la_DEPENDENCIES = \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/tcl/libgensiotcl.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) nodist__pygensiotcl_la_OBJECTS = pygensiotcl_wrap.lo _pygensiotcl_la_OBJECTS = $(nodist__pygensiotcl_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = _pygensiotcl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(AM_CXXFLAGS) $(CXXFLAGS) $(_pygensiotcl_la_LDFLAGS) \ $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/pygensiotcl_wrap.Plo am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(nodist__pygensiotcl_la_SOURCES) DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = $(PYTHON_CPPFLAGS) \ -I$(top_srcdir)/tcl/c++/include -I$(top_srcdir)/tcl/include \ -I$(top_srcdir)/c++/swig/pygensio/include pythonlibdir = $(PYTHON_INSTALL_LIB_DIR) pythonlib_LTLIBRARIES = _pygensiotcl.la EXTRA_DIST = pygensiotcl.i nodist__pygensiotcl_la_SOURCES = pygensiotcl_wrap.cc _pygensiotcl_la_LIBADD = $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/tcl/libgensiotcl.la \ $(OPENSSL_LIBS) $(PYTHON_UNDEF_LIBS) $(TCL_LIBS) _pygensiotcl_la_LDFLAGS = -module -avoid-version $(OPENSSL_LDFLAGS) \ $(PYTHON_UNDEF_FLAG) $(PYTHON_EXT_EXT_SET) all: all-am .SUFFIXES: .SUFFIXES: .cc .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tcl/c++/swig/pygensio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tcl/c++/swig/pygensio/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pythonlibLTLIBRARIES: $(pythonlib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pythonlib_LTLIBRARIES)'; test -n "$(pythonlibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pythonlibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pythonlibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pythonlibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pythonlibdir)"; \ } uninstall-pythonlibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pythonlib_LTLIBRARIES)'; test -n "$(pythonlibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pythonlibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pythonlibdir)/$$f"; \ done clean-pythonlibLTLIBRARIES: -test -z "$(pythonlib_LTLIBRARIES)" || rm -f $(pythonlib_LTLIBRARIES) @list='$(pythonlib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } _pygensiotcl.la: $(_pygensiotcl_la_OBJECTS) $(_pygensiotcl_la_DEPENDENCIES) $(EXTRA__pygensiotcl_la_DEPENDENCIES) $(AM_V_CXXLD)$(_pygensiotcl_la_LINK) -rpath $(pythonlibdir) $(_pygensiotcl_la_OBJECTS) $(_pygensiotcl_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pygensiotcl_wrap.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pythonlibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local \ clean-pythonlibLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/pygensiotcl_wrap.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pythonlibLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-exec-local install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/pygensiotcl_wrap.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local uninstall-pythonlibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-local \ clean-pythonlibLTLIBRARIES cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-exec-local install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-pythonlibLTLIBRARIES install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-local \ uninstall-pythonlibLTLIBRARIES .PRECIOUS: Makefile pygensiotcl_wrap.cc pygensiotcl.py: \ $(top_srcdir)/c++/swig/include/gensio_base.i \ $(top_srcdir)/c++/swig/pygensio/pygensio.i \ $(top_srcdir)/tcl/c++/swig/pygensio/pygensiotcl.i \ $(top_srcdir)/c++/include/gensio $(SWIG) $(DEFS) -Wall -python $(PYTHON_SWIG_FLAGS) \ -o pygensiotcl_wrap.cc -c++ \ -I$(top_srcdir)/tcl/c++/include \ -I$(top_srcdir)/c++/swig/include \ -I$(top_srcdir)/c++/swig/pygensio -I$(top_srcdir)/c++/include \ -I$(top_srcdir)/include -I$(top_builddir)/include \ $(top_srcdir)/tcl/c++/swig/pygensio/pygensiotcl.i clean-local: rm -rf __pycache__ pygensiotcl_wrap.cc pygensiotcl_wrap.h \ pygensiotcl.py install-exec-local: _pygensiotcl.la pygensiotcl.py $(INSTALL) -d $(DESTDIR)$(PYTHON_INSTALL_DIR) $(INSTALL_DATA) pygensiotcl.py "$(DESTDIR)$(PYTHON_INSTALL_DIR)" uninstall-local: $(LIBTOOL) --mode=uninstall \ rm -f "$(DESTDIR)$(PYTHON_INSTALL_LIB_DIR)/_pygensiotcl.$(PYTHON_EXT_EXT)" rm -f "$(DESTDIR)$(PYTHON_INSTALL_DIR)/pygensiotcl.py" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/tcl/c++/swig/pygensio/Makefile.am0000664000175000017500000000316414664224267014476 AM_CPPFLAGS = $(PYTHON_CPPFLAGS) \ -I$(top_srcdir)/tcl/c++/include -I$(top_srcdir)/tcl/include \ -I$(top_srcdir)/c++/swig/pygensio/include pythonlibdir=$(PYTHON_INSTALL_LIB_DIR) pythonlib_LTLIBRARIES = _pygensiotcl.la pygensiotcl_wrap.cc pygensiotcl.py: \ $(top_srcdir)/c++/swig/include/gensio_base.i \ $(top_srcdir)/c++/swig/pygensio/pygensio.i \ $(top_srcdir)/tcl/c++/swig/pygensio/pygensiotcl.i \ $(top_srcdir)/c++/include/gensio $(SWIG) $(DEFS) -Wall -python $(PYTHON_SWIG_FLAGS) \ -o pygensiotcl_wrap.cc -c++ \ -I$(top_srcdir)/tcl/c++/include \ -I$(top_srcdir)/c++/swig/include \ -I$(top_srcdir)/c++/swig/pygensio -I$(top_srcdir)/c++/include \ -I$(top_srcdir)/include -I$(top_builddir)/include \ $(top_srcdir)/tcl/c++/swig/pygensio/pygensiotcl.i EXTRA_DIST = pygensiotcl.i nodist__pygensiotcl_la_SOURCES = pygensiotcl_wrap.cc _pygensiotcl_la_LIBADD = $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/tcl/libgensiotcl.la \ $(OPENSSL_LIBS) $(PYTHON_UNDEF_LIBS) $(TCL_LIBS) _pygensiotcl_la_LDFLAGS = -module -avoid-version $(OPENSSL_LDFLAGS) \ $(PYTHON_UNDEF_FLAG) $(PYTHON_EXT_EXT_SET) clean-local: rm -rf __pycache__ pygensiotcl_wrap.cc pygensiotcl_wrap.h \ pygensiotcl.py install-exec-local: _pygensiotcl.la pygensiotcl.py $(INSTALL) -d $(DESTDIR)$(PYTHON_INSTALL_DIR) $(INSTALL_DATA) pygensiotcl.py "$(DESTDIR)$(PYTHON_INSTALL_DIR)" uninstall-local: $(LIBTOOL) --mode=uninstall \ rm -f "$(DESTDIR)$(PYTHON_INSTALL_LIB_DIR)/_pygensiotcl.$(PYTHON_EXT_EXT)" rm -f "$(DESTDIR)$(PYTHON_INSTALL_DIR)/pygensiotcl.py" gensio-3.0.0/tcl/c++/Makefile.am0000664000175000017500000000011014664224267011654 SUBDIRS = include tests $(SWIG_DIR) DIST_SUBDIRS = include tests swig gensio-3.0.0/tcl/c++/include/0000775000175000017500000000000015061121735011317 5gensio-3.0.0/tcl/c++/include/Makefile.in0000664000175000017500000005455015061121660013312 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = tcl/c++/include ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = gensio DIST_SUBDIRS = gensio all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tcl/c++/include/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tcl/c++/include/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/tcl/c++/include/Makefile.am0000664000175000017500000000005114664224267013303 SUBDIRS = gensio DIST_SUBDIRS = gensio gensio-3.0.0/tcl/c++/include/gensio/0000775000175000017500000000000015061121735012603 5gensio-3.0.0/tcl/c++/include/gensio/Makefile.in0000664000175000017500000005073015061121660014572 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = tcl/c++/include/gensio ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(pkginclude_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkgincludedir)" HEADERS = $(pkginclude_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkginclude_HEADERS = gensiotcl all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tcl/c++/include/gensio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tcl/c++/include/gensio/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkgincludeHEADERS: $(pkginclude_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ done uninstall-pkgincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pkgincludeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkgincludeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool cscopelist-am ctags ctags-am distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkgincludeHEADERS install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-pkgincludeHEADERS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/tcl/c++/include/gensio/Makefile.am0000664000175000017500000000003714664224267014573 pkginclude_HEADERS = gensiotcl gensio-3.0.0/tcl/c++/include/gensio/gensiotcl0000664000175000017500000000122414664224267014450 // // gensio - A library for abstracting stream I/O // Copyright (C) 2022 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only // This is a C++ wrapper for the gensio library. #ifndef GENSIOGLIB_CPP_INCLUDE #define GENSIOGLIB_CPP_INCLUDE #include namespace gensios { #include class Tcl_Os_Funcs: public Os_Funcs { public: Tcl_Os_Funcs(Os_Funcs_Log_Handler *logger = NULL) : Os_Funcs(true) { struct gensio_os_funcs *o; int err = gensio_tcl_funcs_alloc(&o); if (err) throw gensio_error(err); init(o, logger); } }; } #endif /* GENSIOGLIB_CPP_INCLUDE */ gensio-3.0.0/tcl/gensio_tcl_funcs_alloc.30000664000175000017500000000242514664212465014042 .TH gensio_tcl_funcs_alloc 3 "03 Feb 2021" .SH NAME gensio_tcl_funcs_alloc \- Abstraction for some operating system functions done with tcl .SH SYNOPSIS .B #include .PP .B int gensio_tcl_funcs_alloc(struct gensio_os_funcs **o) .SH "DESCRIPTION" This structure provides an abstraction for the gensio library that lets it work on top of tcl. See the tcl_os_funcs.3 man page for details on what this does. This can be used if you have a project based on tcl that you want to integrate gensio into. Unfortunately, it has some limitations because of weaknesses in the tcl interface. Basically, no threads. In tcl, if you start a timer, that timer will only fire in that thread's call to Tcl_DoOneEvent. Same with file handlers. Basically, timers, idle calls, and file handlers belong to a thread. You could, theoretically, have multiple threads as long as you allocate an os handler per thread and did everything with an os handler only in the thread that created it. But that's not very useful. If you really want real threading to work, you put tcl on top of gensio os funcs using Tcl_NotifierProcs. I leave that as an exercise to the reader. .SH "RETURN VALUES" .B A gensio_err returns a standard gensio error. .SH "SEE ALSO" gensio_os_funcs(3), gensio(5), gensio_err(3) gensio-3.0.0/tcl/swig/0000775000175000017500000000000015061121735010275 5gensio-3.0.0/tcl/swig/Makefile.in0000664000175000017500000005456515061121660012276 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = tcl/swig ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = gensiotcl.i SUBDIRS = . $(PYTHON_DIR) DIST_SUBDIRS = python all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tcl/swig/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tcl/swig/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/tcl/swig/Makefile.am0000664000175000017500000000011314664224267012260 EXTRA_DIST = gensiotcl.i SUBDIRS = . $(PYTHON_DIR) DIST_SUBDIRS = python gensio-3.0.0/tcl/swig/gensiotcl.i0000664000175000017500000000165214664224267012376 %module gensiotcl %import %{ #include "config.h" #include #include #include #include #include struct gensio_os_funcs *alloc_tcl_os_funcs(swig_cb *log_handler) { struct gensio_os_funcs *o; int err; err = gensio_tcl_funcs_alloc(&o); if (err) { fprintf(stderr, "Unable to allocate gensio os funcs: %s, giving up\n", gensio_err_to_str(err)); exit(1); } err = gensio_swig_setup_os_funcs(o, log_handler); if (err) { fprintf(stderr, "Unable to set up gensio os funcs: %s, giving up\n", gensio_err_to_str(err)); exit(1); } return o; } %} %nodefaultctor gensio_os_funcs; struct gensio_os_funcs { }; %extend gensio_os_funcs { ~gensio_os_funcs() { check_os_funcs_free(self); } } %newobject alloc_tcl_os_funcs; struct gensio_os_funcs *alloc_tcl_os_funcs(swig_cb *log_handler); gensio-3.0.0/tcl/swig/python/0000775000175000017500000000000015061121735011616 5gensio-3.0.0/tcl/swig/python/Makefile.in0000664000175000017500000006404715061121660013613 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = tcl/swig/python ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pythonlibdir)" LTLIBRARIES = $(pythonlib_LTLIBRARIES) am__DEPENDENCIES_1 = _gensiotcl_la_DEPENDENCIES = $(top_builddir)/tcl/libgensiotcl.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) \ $(top_builddir)/swig/python/libgensio_python_swig.la \ $(am__DEPENDENCIES_1) nodist__gensiotcl_la_OBJECTS = gensiotcl_wrap.lo _gensiotcl_la_OBJECTS = $(nodist__gensiotcl_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = _gensiotcl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(_gensiotcl_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/gensiotcl_wrap.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(nodist__gensiotcl_la_SOURCES) DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = $(PYTHON_CPPFLAGS) \ -I $(top_srcdir)/include \ -I$(top_builddir)/include \ -I $(top_srcdir) \ -I$(top_srcdir)/tcl/include \ -I$(top_srcdir)/swig/include \ -DPYTHON_HAS_THREADS=@PYTHON_HAS_THREADS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pythonlibdir = $(PYTHON_INSTALL_LIB_DIR) pythonlib_LTLIBRARIES = _gensiotcl.la nodist__gensiotcl_la_SOURCES = gensiotcl_wrap.c _gensiotcl_la_LIBADD = $(top_builddir)/tcl/libgensiotcl.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(OPENSSL_LIBS) $(TCL_LIBS) \ $(top_builddir)/swig/python/libgensio_python_swig.la \ $(PYTHON_UNDEF_LIBS) _gensiotcl_la_LDFLAGS = -module -avoid-version $(OPENSSL_LDFLAGS) \ $(PYTHON_UNDEF_FLAG) $(PYTHON_EXT_EXT_SET) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tcl/swig/python/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tcl/swig/python/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pythonlibLTLIBRARIES: $(pythonlib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pythonlib_LTLIBRARIES)'; test -n "$(pythonlibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pythonlibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pythonlibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pythonlibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pythonlibdir)"; \ } uninstall-pythonlibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pythonlib_LTLIBRARIES)'; test -n "$(pythonlibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pythonlibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pythonlibdir)/$$f"; \ done clean-pythonlibLTLIBRARIES: -test -z "$(pythonlib_LTLIBRARIES)" || rm -f $(pythonlib_LTLIBRARIES) @list='$(pythonlib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } _gensiotcl.la: $(_gensiotcl_la_OBJECTS) $(_gensiotcl_la_DEPENDENCIES) $(EXTRA__gensiotcl_la_DEPENDENCIES) $(AM_V_CCLD)$(_gensiotcl_la_LINK) -rpath $(pythonlibdir) $(_gensiotcl_la_OBJECTS) $(_gensiotcl_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensiotcl_wrap.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pythonlibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local \ clean-pythonlibLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/gensiotcl_wrap.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pythonlibLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-exec-local install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/gensiotcl_wrap.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local uninstall-pythonlibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-local \ clean-pythonlibLTLIBRARIES cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-exec-local install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-pythonlibLTLIBRARIES install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-local \ uninstall-pythonlibLTLIBRARIES .PRECIOUS: Makefile gensiotcl_wrap.c gensiotcl.py: $(top_srcdir)/tcl/swig/gensiotcl.i $(SWIG) $(DEFS) -python $(PYTHON_SWIG_FLAGS) -o gensiotcl_wrap.c \ -I$(top_srcdir)/include -I$(top_srcdir)/swig/include \ $(top_srcdir)/tcl/swig/gensiotcl.i clean-local: rm -rf __pycache__ gensiotcl_wrap.c gensiotcl.py install-exec-local: _gensiotcl.la gensiotcl.py $(INSTALL) -d $(DESTDIR)$(PYTHON_INSTALL_DIR) $(INSTALL_DATA) gensiotcl.py "$(DESTDIR)$(PYTHON_INSTALL_DIR)" uninstall-local: $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(PYTHON_INSTALL_LIB_DIR)/_gensiotcl.$(PYTHON_EXT_EXT)" rm -f "$(DESTDIR)$(PYTHON_INSTALL_DIR)/gensiotcl.py" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/tcl/swig/python/Makefile.am0000664000175000017500000000251514664224267013611 AM_CFLAGS = $(PYTHON_CPPFLAGS) \ -I $(top_srcdir)/include \ -I$(top_builddir)/include \ -I $(top_srcdir) \ -I$(top_srcdir)/tcl/include \ -I$(top_srcdir)/swig/include \ -DPYTHON_HAS_THREADS=@PYTHON_HAS_THREADS@ pythonlibdir=$(PYTHON_INSTALL_LIB_DIR) pythonlib_LTLIBRARIES = _gensiotcl.la gensiotcl_wrap.c gensiotcl.py: $(top_srcdir)/tcl/swig/gensiotcl.i $(SWIG) $(DEFS) -python $(PYTHON_SWIG_FLAGS) -o gensiotcl_wrap.c \ -I$(top_srcdir)/include -I$(top_srcdir)/swig/include \ $(top_srcdir)/tcl/swig/gensiotcl.i nodist__gensiotcl_la_SOURCES = gensiotcl_wrap.c _gensiotcl_la_LIBADD = $(top_builddir)/tcl/libgensiotcl.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(OPENSSL_LIBS) $(TCL_LIBS) \ $(top_builddir)/swig/python/libgensio_python_swig.la \ $(PYTHON_UNDEF_LIBS) _gensiotcl_la_LDFLAGS = -module -avoid-version $(OPENSSL_LDFLAGS) \ $(PYTHON_UNDEF_FLAG) $(PYTHON_EXT_EXT_SET) clean-local: rm -rf __pycache__ gensiotcl_wrap.c gensiotcl.py install-exec-local: _gensiotcl.la gensiotcl.py $(INSTALL) -d $(DESTDIR)$(PYTHON_INSTALL_DIR) $(INSTALL_DATA) gensiotcl.py "$(DESTDIR)$(PYTHON_INSTALL_DIR)" uninstall-local: $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(PYTHON_INSTALL_LIB_DIR)/_gensiotcl.$(PYTHON_EXT_EXT)" rm -f "$(DESTDIR)$(PYTHON_INSTALL_DIR)/gensiotcl.py" gensio-3.0.0/tcl/Makefile.am0000664000175000017500000000151714664224267011320 AM_CPPFLAGS = -DBUILDING_GENSIOTCL_DLL AM_CFLAGS = -I$(top_srcdir)/tcl/include @EXTRA_CFLAGS@ lib_LTLIBRARIES = libgensiotcl.la libgensiotcl_la_SOURCES = gensio_tcl.c libgensiotcl_la_CFLAGS = $(TCL_CFLAGS) $(AM_CFLAGS) libgensiotcl_la_LIBADD = $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ @TCL_LIBS@ libgensiotcl_la_LDFLAGS = -no-undefined -rpath $(libdir) \ -version-info $(GENSIO_LIB_VERSION) -fvisibility=hidden SUBDIRS = . $(SWIG_DIR) include $(CPLUSPLUS_DIR) DIST_SUBDIRS = swig include c++ # This variable must have 'exec' in its name, in order to be installed # by 'install-exec' target (instead of default 'install-data') pkgconfigexecdir = $(libdir)/pkgconfig pkgconfigexec_DATA = libgensiotcl.pc if INSTALL_DOC man3_MANS = gensio_tcl_funcs_alloc.3 endif EXTRA_DIST = libgensiotcl.pc.in $(man3_MANS) gensio-3.0.0/tcl/libgensiotcl.pc.in0000664000175000017500000000044014664224267012665 prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libgensioglib Description: A library to abstract stream I/O like serial port, TCP, telnet, UDP, SSL, IPMI SOL, etc. Version: @VERSION@ Libs: -L${libdir} -lgensiotcl -lgensio Libs.private: @TCL_LIBS@ gensio-3.0.0/tcl/gensio_tcl.c0000664000175000017500000010405214664224267011554 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* * This library provides a gensio_os_funcs object for use by gensio. * It can be used if you have a project based on tcl that you want to * integrate gensio into. * * Unfortunately, it has some limitations because of weaknesses in the * tcl interface. Basically, no threads. * * In tcl, if you start a timer, that timer will only fire in that * thread's call to Tcl_DoOneEvent. Same with file handlers. * Basically, timers, idle calls, and file handlers belong to a thread. * * You could, theoretically, have multiple threads as long as you * allocate an os handler per thread and did everything with an os * handler only in the thread that created it. But that's not very * useful. * * If you really want real threading to work, you put tcl on top of * gensio os funcs using Tcl_NotifierProcs. I leave that as an * exercise to the reader. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #define TCL_THREADS 1 #include #include #include #include #include #include #include #include #include #include #include struct gensio_data { struct gensio_memtrack *mtrack; unsigned int refcount; struct gensio_os_proc_data *pdata; }; static void * gensio_tcl_zalloc(struct gensio_os_funcs *f, gensiods size) { struct gensio_data *d = f->user_data; TRACE_MEM; return gensio_i_zalloc(d->mtrack, size, TRACE_MEM_CALLERS, TRACE_MEM_CALLERS_SIZE); } static void gensio_tcl_free(struct gensio_os_funcs *f, void *data) { struct gensio_data *d = f->user_data; TRACE_MEM; gensio_i_free(d->mtrack, data, TRACE_MEM_CALLERS, TRACE_MEM_CALLERS_SIZE); } struct gensio_lock { struct gensio_os_funcs *f; Tcl_Mutex mutex; }; static struct gensio_lock * gensio_tcl_alloc_lock(struct gensio_os_funcs *f) { struct gensio_lock *lock; lock = gensio_tcl_zalloc(f, sizeof(*lock)); if (!lock) return NULL; lock->f = f; return lock; } static void gensio_tcl_free_lock(struct gensio_lock *lock) { Tcl_MutexFinalize(&lock->mutex); gensio_tcl_free(lock->f, lock); } static void gensio_tcl_lock(struct gensio_lock *lock) { Tcl_MutexLock(&lock->mutex); } static void gensio_tcl_unlock(struct gensio_lock *lock) { Tcl_MutexUnlock(&lock->mutex); } struct gensio_iod_tcl { struct gensio_iod r; Tcl_Mutex lock; int mask; bool in_clear; enum { CL_NOT_CALLED, CL_CALLED, CL_DONE } close_state; int orig_fd; int fd; int sfd; enum gensio_iod_type type; void *sockinfo; bool handlers_set; bool is_stdio; void *cb_data; void (*read_handler)(struct gensio_iod *iod, void *cb_data); void (*write_handler)(struct gensio_iod *iod, void *cb_data); void (*except_handler)(struct gensio_iod *iod, void *cb_data); void (*cleared_handler)(struct gensio_iod *iod, void *cb_data); struct stdio_mode *mode; struct gensio_unix_termios *termios; /* For GENSIO_IOD_FILE */ struct gensio_runner *runner; bool read_enabled; bool write_enabled; bool in_handler; /* For GENSIO_IOD_PTY */ const char **argv; const char **env; char *start_dir; int pid; }; #define i_to_tcl(i) gensio_container_of(i, struct gensio_iod_tcl, r); static void tcl_file_handler(ClientData data, int mask) { struct gensio_iod_tcl *iod = data; if (mask & TCL_READABLE) iod->read_handler(&iod->r, iod->cb_data); if (mask & TCL_WRITABLE) iod->write_handler(&iod->r, iod->cb_data); if (mask & TCL_EXCEPTION) iod->except_handler(&iod->r, iod->cb_data); } static void tcl_cleared_done(ClientData data) { struct gensio_iod_tcl *iod = data; Tcl_MutexLock(&iod->lock); iod->handlers_set = false; iod->read_handler = NULL; iod->write_handler = NULL; iod->except_handler = NULL; iod->in_clear = false; Tcl_MutexUnlock(&iod->lock); if (iod->cleared_handler) iod->cleared_handler(&iod->r, iod->cb_data); } static int gensio_tcl_set_fd_handlers(struct gensio_iod *iiod, void *cb_data, void (*read_handler)(struct gensio_iod *iod, void *cb_data), void (*write_handler)(struct gensio_iod *iod, void *cb_data), void (*except_handler)(struct gensio_iod *iod, void *cb_data), void (*cleared_handler)(struct gensio_iod *iod, void *cb_data)) { struct gensio_iod_tcl *iod = i_to_tcl(iiod); Tcl_MutexLock(&iod->lock); if (iod->handlers_set) { Tcl_MutexUnlock(&iod->lock); return GE_INUSE; } iod->handlers_set = true; iod->cb_data = cb_data; iod->read_handler = read_handler; iod->write_handler = write_handler; iod->except_handler = except_handler; iod->cleared_handler = cleared_handler; Tcl_MutexUnlock(&iod->lock); return 0; } static void gensio_tcl_clear_fd_handlers(struct gensio_iod *iiod) { struct gensio_iod_tcl *iod = i_to_tcl(iiod); Tcl_MutexLock(&iod->lock); if (!iod->handlers_set || iod->in_clear) goto out_unlock; if (iod->mask) Tcl_DeleteFileHandler(iod->fd); iod->in_clear = true; Tcl_DoWhenIdle(tcl_cleared_done, iod); out_unlock: Tcl_MutexUnlock(&iod->lock); } static void gensio_tcl_clear_fd_handlers_norpt(struct gensio_iod *iiod) { struct gensio_iod_tcl *iod = i_to_tcl(iiod); Tcl_MutexLock(&iod->lock); assert(iod->mask == 0); iod->handlers_set = false; Tcl_MutexUnlock(&iod->lock); } static void file_runner(struct gensio_runner *r, void *cb_data) { struct gensio_iod_tcl *iod = cb_data; Tcl_MutexLock(&iod->lock); while (iod->read_enabled || iod->write_enabled) { if (iod->read_enabled) { Tcl_MutexUnlock(&iod->lock); iod->read_handler(&iod->r, iod->cb_data); Tcl_MutexLock(&iod->lock); } if (iod->write_enabled) { Tcl_MutexUnlock(&iod->lock); iod->write_handler(&iod->r, iod->cb_data); Tcl_MutexLock(&iod->lock); } } iod->in_handler = false; if (iod->in_clear) { iod->in_clear = false; iod->handlers_set = false; Tcl_MutexUnlock(&iod->lock); iod->cleared_handler(&iod->r, iod->cb_data); Tcl_MutexLock(&iod->lock); } Tcl_MutexUnlock(&iod->lock); } static void gensio_tcl_set_read_handler(struct gensio_iod *iiod, bool enable) { struct gensio_iod_tcl *iod = i_to_tcl(iiod); int new_mask; Tcl_MutexLock(&iod->lock); if (iod->type == GENSIO_IOD_FILE) { if (iod->read_enabled == enable || iod->in_clear) goto out_unlock; iod->read_enabled = enable; if (enable && !iod->in_handler) { iod->r.f->run(iod->runner); iod->in_handler = true; } goto out_unlock; } new_mask = iod->mask; if (enable) new_mask |= TCL_READABLE; else new_mask &= ~TCL_READABLE; if (new_mask == iod->mask) goto out_unlock; iod->mask = new_mask; if (new_mask == 0) Tcl_DeleteFileHandler(iod->fd); else Tcl_CreateFileHandler(iod->fd, new_mask, tcl_file_handler, iod); out_unlock: Tcl_MutexUnlock(&iod->lock); } static void gensio_tcl_set_write_handler(struct gensio_iod *iiod, bool enable) { struct gensio_iod_tcl *iod = i_to_tcl(iiod); int new_mask; Tcl_MutexLock(&iod->lock); if (iod->type == GENSIO_IOD_FILE) { if (iod->write_enabled == enable || iod->in_clear) goto out_unlock; iod->write_enabled = enable; if (enable && !iod->in_handler) { iod->r.f->run(iod->runner); iod->in_handler = true; } goto out_unlock; } new_mask = iod->mask; if (enable) new_mask |= TCL_WRITABLE; else new_mask &= ~TCL_WRITABLE; if (new_mask == iod->mask) goto out_unlock; iod->mask = new_mask; Tcl_CreateFileHandler(iod->fd, new_mask, tcl_file_handler, iod); out_unlock: Tcl_MutexUnlock(&iod->lock); } static void gensio_tcl_set_except_handler(struct gensio_iod *iiod, bool enable) { struct gensio_iod_tcl *iod = i_to_tcl(iiod); int new_mask; if (iod->type == GENSIO_IOD_FILE) return; Tcl_MutexLock(&iod->lock); new_mask = iod->mask; if (enable) new_mask |= TCL_EXCEPTION; else new_mask &= ~TCL_EXCEPTION; if (new_mask == iod->mask) goto out_unlock; iod->mask = new_mask; Tcl_CreateFileHandler(iod->fd, new_mask, tcl_file_handler, iod); out_unlock: Tcl_MutexUnlock(&iod->lock); } struct gensio_timer { struct gensio_os_funcs *o; void (*handler)(struct gensio_timer *t, void *cb_data); void *cb_data; Tcl_Mutex lock; Tcl_TimerToken timer_id; enum { TCL_TIMER_FREE, TCL_TIMER_IN_STOP, TCL_TIMER_STOPPED, TCL_TIMER_RUNNING } state; void (*done_handler)(struct gensio_timer *t, void *cb_data); void *done_cb_data; }; static void gensio_tcl_timeout_handler(ClientData data) { struct gensio_timer *t = data; void (*handler)(struct gensio_timer *t, void *cb_data) = NULL; void *cb_data; Tcl_MutexLock(&t->lock); if (t->timer_id) { handler = t->handler; cb_data = t->cb_data; t->state = TCL_TIMER_STOPPED; t->timer_id = 0; } Tcl_MutexUnlock(&t->lock); if (handler) handler(t, cb_data); } static struct gensio_timer * gensio_tcl_alloc_timer(struct gensio_os_funcs *o, void (*handler)(struct gensio_timer *t, void *cb_data), void *cb_data) { struct gensio_timer *t; t = o->zalloc(o, sizeof(*t)); if (!t) return NULL; t->o = o; t->handler = handler; t->cb_data = cb_data; t->state = TCL_TIMER_STOPPED; return t; } static void gensio_tcl_free_timer(struct gensio_timer *t) { Tcl_MutexLock(&t->lock); assert(t->state != TCL_TIMER_FREE); if (t->state == TCL_TIMER_RUNNING) { Tcl_DeleteTimerHandler(t->timer_id); t->timer_id = NULL; } t->state = TCL_TIMER_FREE; Tcl_MutexUnlock(&t->lock); t->o->free(t->o, t); } /* * Various time conversion routines. Note that we always truncate up * to the next time unit. These are used for timers, and if you don't * you can end up with an early timeout. */ static unsigned int gensio_time_to_ms(gensio_time *t) { return t->secs * 1000 + (t->nsecs + 999999) / 1000000; } static int64_t gensio_time_to_us(gensio_time *t) { return t->secs * 1000000ULL + (t->nsecs + 999) / 1000; } static unsigned int us_time_to_ms(int64_t t) { return (t + 999) / 1000; } static void us_time_to_gensio(int64_t t, gensio_time *gt) { gt->secs = t / 1000000; gt->nsecs = t % 1000000 * 1000; } static int gensio_tcl_start_timer(struct gensio_timer *t, gensio_time *timeout) { int msec = gensio_time_to_ms(timeout); int rv = 0; Tcl_MutexLock(&t->lock); assert(t->state != TCL_TIMER_FREE); if (t->state != TCL_TIMER_STOPPED) { rv = GE_INUSE; } else { t->done_handler = NULL; t->timer_id = Tcl_CreateTimerHandler(msec, gensio_tcl_timeout_handler, t); if (!t->timer_id) { rv = GE_NOMEM; } else { t->state = TCL_TIMER_RUNNING; } } Tcl_MutexUnlock(&t->lock); return rv; } static int gensio_tcl_start_timer_abs(struct gensio_timer *t, gensio_time *timeout) { struct timespec ts; int64_t tnsecs, nnsecs; int msec; int rv = 0; clock_gettime(CLOCK_MONOTONIC, &ts); tnsecs = timeout->secs * 1000000000ULL + timeout->nsecs; nnsecs = ts.tv_sec * 1000000000ULL | ts.tv_nsec; if (tnsecs < nnsecs) tnsecs = 0; else tnsecs -= nnsecs; msec = (tnsecs + 999999ULL) / 1000000; Tcl_MutexLock(&t->lock); assert(t->state != TCL_TIMER_FREE); if (t->state != TCL_TIMER_STOPPED) { rv = GE_INUSE; } else { t->done_handler = NULL; t->timer_id = Tcl_CreateTimerHandler(msec, gensio_tcl_timeout_handler, t); if (!t->timer_id) { rv = GE_NOMEM; } else { t->state = TCL_TIMER_RUNNING; } } Tcl_MutexUnlock(&t->lock); return rv; } static int gensio_tcl_stop_timer(struct gensio_timer *t) { int rv = 0; Tcl_MutexLock(&t->lock); assert(t->state != TCL_TIMER_FREE); if (t->state != TCL_TIMER_RUNNING) { rv = GE_TIMEDOUT; } else { t->state = TCL_TIMER_STOPPED; Tcl_DeleteTimerHandler(t->timer_id); t->timer_id = NULL; } Tcl_MutexUnlock(&t->lock); return rv; } static void gensio_tcl_timeout_done(ClientData data) { struct gensio_timer *t = data; void (*done_handler)(struct gensio_timer *t, void *cb_data) = NULL; void *done_cb_data; Tcl_MutexLock(&t->lock); if (t->state == TCL_TIMER_FREE) { Tcl_MutexFinalize(&t->lock); t->o->free(t->o, t); } else { t->state = TCL_TIMER_STOPPED; done_handler = t->done_handler; done_cb_data = t->done_cb_data; t->done_handler = NULL; } Tcl_MutexUnlock(&t->lock); if (done_handler) done_handler(t, done_cb_data); } static int gensio_tcl_stop_timer_with_done(struct gensio_timer *t, void (*done_handler)(struct gensio_timer *t, void *cb_data), void *cb_data) { int rv = 0; Tcl_MutexLock(&t->lock); if (t->state == TCL_TIMER_IN_STOP) { rv = GE_INUSE; } else if (t->state != TCL_TIMER_RUNNING) { rv = GE_TIMEDOUT; } else { t->state = TCL_TIMER_IN_STOP; t->done_handler = done_handler; t->done_cb_data = cb_data; Tcl_DeleteTimerHandler(t->timer_id); t->timer_id = NULL; Tcl_DoWhenIdle(gensio_tcl_timeout_done, t); } Tcl_MutexUnlock(&t->lock); return rv; } struct gensio_runner { struct gensio_os_funcs *o; void (*handler)(struct gensio_runner *r, void *cb_data); void *cb_data; bool freed; bool in_use; Tcl_Mutex lock; }; static void gensio_tcl_idle_handler(ClientData data) { struct gensio_runner *r = (void *) data; void (*handler)(struct gensio_runner *r, void *cb_data) = NULL; void *cb_data; Tcl_MutexLock(&r->lock); if (r->freed) { Tcl_MutexUnlock(&r->lock); Tcl_MutexFinalize(&r->lock); r->o->free(r->o, r); } else { handler = r->handler; cb_data = r->cb_data; r->in_use = false; Tcl_MutexUnlock(&r->lock); } if (handler) handler(r, cb_data); } static struct gensio_runner * gensio_tcl_alloc_runner(struct gensio_os_funcs *o, void (*handler)(struct gensio_runner *r, void *cb_data), void *cb_data) { struct gensio_runner *r; r = o->zalloc(o, sizeof(*r)); if (!r) return NULL; r->o = o; r->handler = handler; r->cb_data = cb_data; return r; } static void gensio_tcl_free_runner(struct gensio_runner *r) { Tcl_MutexLock(&r->lock); if (r->in_use) { r->freed = true; Tcl_MutexUnlock(&r->lock); } else { Tcl_MutexUnlock(&r->lock); Tcl_MutexFinalize(&r->lock); r->o->free(r->o, r); } } static int gensio_tcl_run(struct gensio_runner *r) { int rv = 0; Tcl_MutexLock(&r->lock); if (r->in_use) { rv = GE_INUSE; } else { Tcl_DoWhenIdle(gensio_tcl_idle_handler, r); r->in_use = true; } Tcl_MutexUnlock(&r->lock); return rv; } struct gensio_waiter { struct gensio_os_funcs *o; unsigned int count; }; static struct gensio_waiter * gensio_tcl_alloc_waiter(struct gensio_os_funcs *o) { struct gensio_waiter *w; w = o->zalloc(o, sizeof(*w)); if (!w) return NULL; w->o = o; return w; } static void gensio_tcl_free_waiter(struct gensio_waiter *w) { w->o->free(w->o, w); } struct dummy_timeout_data { bool did_something; Tcl_TimerToken timer; }; static void dummy_timeout_handler(ClientData data) { struct dummy_timeout_data *td = data; td->did_something = false; } static void dummy_idle_handler(ClientData data) { struct dummy_timeout_data *td = data; td->did_something = false; } struct timeout_info { gensio_time *timeout; /* Times below are in microseconds. */ int64_t start; int64_t now; int64_t end; }; static int64_t fetch_us_time(void) { Tcl_Time now; Tcl_GetTime(&now); return (now.sec * 1000000ULL) + now.usec; } static void setup_timeout(struct timeout_info *t) { if (t->timeout) { t->start = t->now = fetch_us_time(); t->end = t->now + gensio_time_to_us(t->timeout); } else { t->start = 0; t->now = 0; t->end = 0; } } static bool timed_out(struct timeout_info *t) { return t->timeout && t->now >= t->end; } static bool timeout_wait(struct timeout_info *t) { struct dummy_timeout_data td = { .did_something = true, .timer = NULL }; if (t->timeout) { unsigned int timeout = us_time_to_ms(t->end - t->now); if (timeout) { td.timer = Tcl_CreateTimerHandler(timeout, dummy_timeout_handler, &td); Tcl_DoOneEvent(0); Tcl_DeleteTimerHandler(td.timer); } else { Tcl_DoWhenIdle(dummy_idle_handler, &td); Tcl_DoOneEvent(0); if (!td.did_something) Tcl_CancelIdleCall(dummy_idle_handler, &td); } if (td.timer) Tcl_DeleteTimerHandler(td.timer); } else { Tcl_DoOneEvent(0); } return td.did_something; } static void timeout_end(struct timeout_info *t) { if (t->timeout) { int64_t diff = t->end - t->now; if (diff > 0) { us_time_to_gensio(diff, t->timeout); } else { t->timeout->secs = 0; t->timeout->nsecs = 0; } } } static int gensio_tcl_wait_intr_sigmask(struct gensio_waiter *w, unsigned int count, gensio_time *timeout, struct gensio_os_proc_data *proc_data) { struct timeout_info ti = { .timeout = timeout }; int rv = 0; sigset_t origmask; if (proc_data) { pthread_sigmask(SIG_SETMASK, gensio_os_proc_unix_get_wait_sigset(proc_data), &origmask); } setup_timeout(&ti); while (count > w->count && !timed_out(&ti)) { timeout_wait(&ti); ti.now = fetch_us_time(); } if (count > w->count) rv = GE_TIMEDOUT; else w->count -= count; timeout_end(&ti); if (proc_data) { pthread_sigmask(SIG_SETMASK, &origmask, NULL); gensio_os_proc_check_handlers(proc_data); } return rv; } static int gensio_tcl_wait(struct gensio_waiter *w, unsigned int count, gensio_time *timeout) { struct gensio_data *d = w->o->user_data; int rv = GE_INTERRUPTED; while (rv == GE_INTERRUPTED) rv = gensio_tcl_wait_intr_sigmask(w, count, timeout, d->pdata); return rv; } static int gensio_tcl_wait_intr(struct gensio_waiter *w, unsigned int count, gensio_time *timeout) { struct gensio_data *d = w->o->user_data; return gensio_tcl_wait_intr_sigmask(w, count, timeout, d->pdata); } static void gensio_tcl_wake(struct gensio_waiter *w) { w->count += 1; } static int gensio_tcl_add_iod(struct gensio_os_funcs *o, enum gensio_iod_type type, intptr_t ofd, struct gensio_iod **riod, ...) { struct gensio_iod_tcl *iod = NULL; bool closefd = false; int err = GE_NOMEM, fd = ofd, sfd = -1; if (type == GENSIO_IOD_CONSOLE) { if (fd == 0) fd = open("/dev/tty", O_RDONLY); else if (fd == 1) fd = open("/dev/tty", O_WRONLY); else return GE_INVAL; if (fd == -1) return gensio_os_err_to_err(o, errno); closefd = true; } else if (type == GENSIO_IOD_PTY) { err = gensio_unix_pty_alloc(o, &fd, &sfd); if (err) return err; closefd = true; } iod = o->zalloc(o, sizeof(*iod)); if (!iod) { err = GE_NOMEM; goto out_err; } iod->r.f = o; iod->fd = fd; iod->sfd = sfd; iod->orig_fd = ofd; if (type == GENSIO_IOD_STDIO) { struct stat statb; iod->is_stdio = true; err = fstat(fd, &statb); if (err == -1) { err = gensio_os_err_to_err(o, errno); goto out_err; } switch (statb.st_mode & S_IFMT) { case S_IFREG: type = GENSIO_IOD_FILE; break; case S_IFCHR: type = GENSIO_IOD_DEV; break; case S_IFIFO: type = GENSIO_IOD_PIPE; break; case S_IFSOCK: type = GENSIO_IOD_SOCKET; break; default: err = GE_INVAL; goto out_err; } } else if (type == GENSIO_IOD_PTY) { iod->pid = -1; } iod->type = type; if (type == GENSIO_IOD_FILE) { iod->runner = o->alloc_runner(o, file_runner, iod); if (!iod->runner) goto out_err; } *riod = &iod->r; return 0; out_err: if (iod) o->free(o, iod); else if (closefd) { close(fd); if (sfd != -1) close(sfd); } return err; } static void gensio_tcl_release_iod(struct gensio_iod *iiod) { struct gensio_os_funcs *o = iiod->f; struct gensio_iod_tcl *iod = i_to_tcl(iiod); assert(!iod->handlers_set); Tcl_MutexFinalize(&iod->lock); if (iod->type == GENSIO_IOD_FILE) o->free_runner(iod->runner); if (iod->type == GENSIO_IOD_PTY) { if (iod->argv) gensio_argv_free(o, iod->argv); if (iod->env) gensio_argv_free(o, iod->env); } o->free(o, iod); } static int gensio_tcl_iod_get_type(struct gensio_iod *iiod) { struct gensio_iod_tcl *iod = i_to_tcl(iiod); return iod->type; } static int gensio_tcl_iod_get_fd(struct gensio_iod *iiod) { struct gensio_iod_tcl *iod = i_to_tcl(iiod); return iod->fd; } static int gensio_tcl_pty_control(struct gensio_iod_tcl *iod, int op, bool get, intptr_t val) { struct gensio_os_funcs *o = iod->r.f; int err = 0; const char **nargv; if (get) { if (op == GENSIO_IOD_CONTROL_PID) { if (iod->pid == -1) return GE_NOTREADY; *((intptr_t *) val) = iod->pid; return 0; } return GE_NOTSUP; } switch (op) { case GENSIO_IOD_CONTROL_ARGV: err = gensio_argv_copy(o, (const char **) val, NULL, &nargv); if (err) return err; if (iod->argv) gensio_argv_free(o, iod->argv); iod->argv = nargv; return 0; case GENSIO_IOD_CONTROL_ENV: err = gensio_argv_copy(o, (const char **) val, NULL, &nargv); if (err) return err; if (iod->env) gensio_argv_free(o, iod->env); iod->env = nargv; return 0; case GENSIO_IOD_CONTROL_START: return gensio_unix_pty_start(o, iod->fd, &iod->sfd, iod->argv, iod->env, iod->start_dir, &iod->pid); case GENSIO_IOD_CONTROL_STOP: if (iod->fd != -1) { close(iod->fd); iod->fd = -1; } return 0; case GENSIO_IOD_CONTROL_WIN_SIZE: { struct winsize win; struct gensio_winsize *gwin = (struct gensio_winsize *) val; win.ws_row = gwin->ws_row; win.ws_col = gwin->ws_col; win.ws_xpixel = gwin->ws_xpixel; win.ws_ypixel = gwin->ws_ypixel; if (ioctl(iod->fd, TIOCSWINSZ, &win) == -1) err = gensio_os_err_to_err(o, errno); return err; } case GENSIO_IOD_CONTROL_START_DIR: { char *dir = (char *) val; if (dir) { dir = gensio_strdup(o, dir); if (!dir) return GE_NOMEM; } if (iod->start_dir) o->free(o, iod->start_dir); iod->start_dir = dir; return 0; } default: return GE_NOTSUP; } } static int gensio_tcl_iod_control(struct gensio_iod *iiod, int op, bool get, intptr_t val) { struct gensio_iod_tcl *iod = i_to_tcl(iiod); if (iod->type == GENSIO_IOD_SOCKET) { if (op != GENSIO_IOD_CONTROL_SOCKINFO) return GE_NOTSUP; if (get) *((void **) val) = iod->sockinfo; else iod->sockinfo = (void *) val; return 0; } if (iod->type == GENSIO_IOD_PTY) return gensio_tcl_pty_control(iod, op, get, val); if (iod->type != GENSIO_IOD_DEV) return GE_NOTSUP; return gensio_unix_termios_control(iiod->f, op, get, val, &iod->termios, iod->fd); } static int gensio_tcl_set_non_blocking(struct gensio_iod *iiod) { struct gensio_iod_tcl *iod = i_to_tcl(iiod); int rv = 0; if (iod->type == GENSIO_IOD_FILE) return 0; rv = gensio_unix_do_nonblock(iiod->f, iod->fd, &iod->mode); return rv; } static int gensio_tcl_close(struct gensio_iod **iodp) { struct gensio_iod *iiod = *iodp; struct gensio_iod_tcl *iod = i_to_tcl(iiod); struct gensio_os_funcs *o = iiod->f; int err = 0; assert(iodp); assert(!iod->handlers_set); if (iod->type != GENSIO_IOD_FILE) { gensio_unix_cleanup_termios(o, &iod->termios, iod->fd); gensio_unix_do_cleanup_nonblock(o, iod->fd, &iod->mode); } if (iod->type == GENSIO_IOD_SOCKET) { if (iod->close_state == CL_DONE) { err = 0; } else { err = o->close_socket(iiod, iod->close_state == CL_CALLED, false); if (err == GE_INPROGRESS) iod->close_state = CL_CALLED; else iod->close_state = CL_DONE; } } else if (!iod->is_stdio) { if (iod->fd != -1) { err = close(iod->fd); if (err == -1) err = gensio_os_err_to_err(o, errno); #ifdef ENABLE_INTERNAL_TRACE /* Close should never fail, but don't crash in production builds. */ assert(err == 0); #endif if (iod->sfd != -1) { close(iod->sfd); iod->sfd = -1; } } } o->release_iod(iiod); *iodp = NULL; return err; } #define ERRHANDLE() \ do { \ int err = 0; \ if (rv < 0) { \ if (errno == EINTR) \ goto retry; \ if (errno == EWOULDBLOCK || errno == EAGAIN) \ rv = 0; /* Handle like a zero-byte write. */ \ else { \ err = errno; \ assert(err); \ } \ } else if (rv == 0) { \ err = EPIPE; \ } \ if (!err && rcount) \ *rcount = rv; \ rv = gensio_os_err_to_err(o, err); \ } while(0) static int gensio_tcl_write(struct gensio_iod *iiod, const struct gensio_sg *sg, gensiods sglen, gensiods *rcount) { struct gensio_iod_tcl *iod = i_to_tcl(iiod); struct gensio_os_funcs *o = iiod->f; ssize_t rv; if (sglen == 0) { if (rcount) *rcount = 0; return 0; } retry: rv = writev(iod->fd, (struct iovec *) sg, sglen); ERRHANDLE(); return rv; } static int gensio_tcl_read(struct gensio_iod *iiod, void *buf, gensiods buflen, gensiods *rcount) { struct gensio_iod_tcl *iod = i_to_tcl(iiod); struct gensio_os_funcs *o = iiod->f; ssize_t rv; if (buflen == 0) { if (rcount) *rcount = 0; return 0; } retry: rv = read(iod->fd, buf, buflen); ERRHANDLE(); return rv; } static bool gensio_tcl_is_regfile(struct gensio_os_funcs *o, intptr_t fd) { int err; struct stat statb; err = fstat(fd, &statb); if (err == -1) return false; return (statb.st_mode & S_IFMT) == S_IFREG; } static int gensio_tcl_bufcount(struct gensio_iod *iiod, int whichbuf, gensiods *count) { struct gensio_iod_tcl *iod = i_to_tcl(iiod); return gensio_unix_get_bufcount(iiod->f, iod->fd, whichbuf, count); } static void gensio_tcl_flush(struct gensio_iod *iiod, int whichbuf) { struct gensio_iod_tcl *iod = i_to_tcl(iiod); gensio_unix_do_flush(iiod->f, iod->fd, whichbuf); } static int gensio_tcl_makeraw(struct gensio_iod *iiod) { struct gensio_iod_tcl *iod = i_to_tcl(iiod); if (iod->orig_fd == 1 || iod->orig_fd == 2 || iod->type == GENSIO_IOD_FILE) /* Only set this for stdin or other files. */ return 0; return gensio_unix_setup_termios(iiod->f, iod->fd, &iod->termios); } static int gensio_tcl_open_dev(struct gensio_os_funcs *o, const char *iname, int options, struct gensio_iod **riod) { int flags, fd, err; flags = O_NONBLOCK | O_NOCTTY; if (options & (GENSIO_OPEN_OPTION_READABLE | GENSIO_OPEN_OPTION_WRITEABLE)) flags |= O_RDWR; else if (options & GENSIO_OPEN_OPTION_READABLE) flags |= O_RDONLY; else if (options & GENSIO_OPEN_OPTION_WRITEABLE) flags |= O_WRONLY; fd = open(iname, flags); if (fd == -1) return gensio_os_err_to_err(o, errno); err = o->add_iod(o, GENSIO_IOD_DEV, fd, riod); if (err) close(fd); return err; } static void generic_close(intptr_t fd) { close(fd); } static int gensio_tcl_exec_subprog(struct gensio_os_funcs *o, const char *argv[], const char **env, const char *start_dir, unsigned int flags, intptr_t *rpid, struct gensio_iod **rstdin, struct gensio_iod **rstdout, struct gensio_iod **rstderr) { int err; struct gensio_iod *stdiniod = NULL, *stdoutiod = NULL, *stderriod = NULL; intptr_t infd = -1, outfd = -1, errfd = -1; intptr_t pid = -1; int uinfd = -1, uoutfd = -1, uerrfd = -1; int upid = -1; err = gensio_unix_do_exec(o, argv, env, start_dir, flags, &upid, &uinfd, &uoutfd, rstderr ? &uerrfd : NULL); if (err) return err; infd = uinfd; outfd = uoutfd; errfd = uerrfd; pid = upid; err = o->add_iod(o, GENSIO_IOD_PIPE, infd, &stdiniod); if (err) goto out_err; infd = -1; err = o->add_iod(o, GENSIO_IOD_PIPE, outfd, &stdoutiod); if (err) goto out_err; outfd = -1; err = o->set_non_blocking(stdiniod); if (err) goto out_err; err = o->set_non_blocking(stdoutiod); if (err) goto out_err; if (rstderr) { err = o->add_iod(o, GENSIO_IOD_PIPE, errfd, &stderriod); if (err) goto out_err; errfd = -1; err = o->set_non_blocking(stderriod); if (err) goto out_err; } *rpid = pid; *rstdin = stdiniod; *rstdout = stdoutiod; if (rstderr) *rstderr = stderriod; return 0; out_err: if (stderriod) o->close(&stderriod); else if (errfd != -1) generic_close(errfd); if (stdiniod) o->close(&stdiniod); else if (infd != -1) generic_close(infd); if (stdoutiod) o->close(&stdoutiod); else if (outfd != -1) generic_close(outfd); return err; } static int gensio_tcl_kill_subprog(struct gensio_os_funcs *o, intptr_t pid, bool force) { int rv; rv = kill(pid, force ? SIGKILL : SIGTERM); if (rv < 0) return gensio_os_err_to_err(o, errno); return 0; } static int gensio_tcl_wait_subprog(struct gensio_os_funcs *o, intptr_t pid, int *retcode) { pid_t rv; rv = waitpid(pid, retcode, WNOHANG); if (rv < 0) return gensio_os_err_to_err(o, errno); if (rv == 0) return GE_INPROGRESS; return 0; } static int gensio_tcl_service(struct gensio_os_funcs *o, gensio_time *timeout) { struct timeout_info ti = { .timeout = timeout }; int rv = GE_TIMEDOUT; setup_timeout(&ti); if (timeout_wait(&ti)) rv = 0; ti.now = fetch_us_time(); timeout_end(&ti); return rv; } static struct gensio_os_funcs * gensio_tcl_get_funcs(struct gensio_os_funcs *f) { struct gensio_data *d = f->user_data; d->refcount++; return f; } static void gensio_tcl_free_funcs(struct gensio_os_funcs *f) { struct gensio_data *d = f->user_data; assert(d->refcount > 0); if (d->refcount > 1) { d->refcount--; return; } gensio_memtrack_cleanup(d->mtrack); free(d); free(f); } static void gensio_tcl_get_monotonic_time(struct gensio_os_funcs *f, gensio_time *time) { Tcl_Time ttime; Tcl_GetTime(&ttime); time->secs = ttime.sec; time->nsecs = ttime.usec * 1000; } static int gensio_tcl_handle_fork(struct gensio_os_funcs *f) { return 0; } static int gensio_tcl_get_random(struct gensio_os_funcs *o, void *data, unsigned int len) { int fd; int rv; fd = open("/dev/urandom", O_RDONLY); if (fd == -1) return gensio_os_err_to_err(o, errno); while (len > 0) { rv = read(fd, data, len); if (rv < 0) { rv = errno; goto out; } len -= rv; data += rv; } rv = 0; out: close(fd); return gensio_os_err_to_err(o, rv); } static int gensio_tcl_control(struct gensio_os_funcs *o, int func, void *data, gensiods *datalen) { struct gensio_data *d = o->user_data; switch (func) { case GENSIO_CONTROL_SET_PROC_DATA: d->pdata = data; return 0; default: return GE_NOTSUP; } } int gensio_tcl_funcs_alloc(struct gensio_os_funcs **ro) { struct gensio_data *d; struct gensio_os_funcs *o; Tcl_Interp *interp; int err; /* * TCL won't work until after you create an intepreter. So do * that here to avoid crashes in the TCL library. */ interp = Tcl_CreateInterp(); Tcl_DeleteInterp(interp); o = malloc(sizeof(*o)); if (!o) return GE_NOMEM; memset(o, 0, sizeof(*o)); d = malloc(sizeof(*d)); if (!d) { free(o); return GE_NOMEM; } memset(d, 0, sizeof(*d)); d->refcount = 1; o->user_data = d; d->mtrack = gensio_memtrack_alloc(); o->zalloc = gensio_tcl_zalloc; o->free = gensio_tcl_free; o->alloc_lock = gensio_tcl_alloc_lock; o->free_lock = gensio_tcl_free_lock; o->lock = gensio_tcl_lock; o->unlock = gensio_tcl_unlock; o->set_fd_handlers = gensio_tcl_set_fd_handlers; o->clear_fd_handlers = gensio_tcl_clear_fd_handlers; o->clear_fd_handlers_norpt = gensio_tcl_clear_fd_handlers_norpt; o->set_read_handler = gensio_tcl_set_read_handler; o->set_write_handler = gensio_tcl_set_write_handler; o->set_except_handler = gensio_tcl_set_except_handler; o->alloc_timer = gensio_tcl_alloc_timer; o->free_timer = gensio_tcl_free_timer; o->start_timer = gensio_tcl_start_timer; o->start_timer_abs = gensio_tcl_start_timer_abs; o->stop_timer = gensio_tcl_stop_timer; o->stop_timer_with_done = gensio_tcl_stop_timer_with_done; o->alloc_runner = gensio_tcl_alloc_runner; o->free_runner = gensio_tcl_free_runner; o->run = gensio_tcl_run; o->alloc_waiter = gensio_tcl_alloc_waiter; o->free_waiter = gensio_tcl_free_waiter; o->wait = gensio_tcl_wait; o->wait_intr = gensio_tcl_wait_intr; o->wait_intr_sigmask = gensio_tcl_wait_intr_sigmask; o->wake = gensio_tcl_wake; o->service = gensio_tcl_service; o->get_funcs = gensio_tcl_get_funcs; o->free_funcs = gensio_tcl_free_funcs; o->call_once = gensio_call_once; o->get_monotonic_time = gensio_tcl_get_monotonic_time; o->handle_fork = gensio_tcl_handle_fork; o->add_iod = gensio_tcl_add_iod; o->release_iod = gensio_tcl_release_iod; o->iod_get_type = gensio_tcl_iod_get_type; o->iod_get_fd = gensio_tcl_iod_get_fd; o->set_non_blocking = gensio_tcl_set_non_blocking; o->close = gensio_tcl_close; o->graceful_close = gensio_tcl_close; o->write = gensio_tcl_write; o->read = gensio_tcl_read; o->is_regfile = gensio_tcl_is_regfile; o->bufcount = gensio_tcl_bufcount; o->flush = gensio_tcl_flush; o->makeraw = gensio_tcl_makeraw; o->open_dev = gensio_tcl_open_dev; o->exec_subprog = gensio_tcl_exec_subprog; o->kill_subprog = gensio_tcl_kill_subprog; o->wait_subprog = gensio_tcl_wait_subprog; o->get_random = gensio_tcl_get_random; o->iod_control = gensio_tcl_iod_control; o->control = gensio_tcl_control; gensio_addr_addrinfo_set_os_funcs(o); err = gensio_stdsock_set_os_funcs(o); if (err) { free(o); free(d); return err; } *ro = o; return 0; } gensio-3.0.0/tcl/include/0000775000175000017500000000000015061121735010747 5gensio-3.0.0/tcl/include/Makefile.in0000664000175000017500000005454015061121660012741 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = tcl/include ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = gensio all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tcl/include/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tcl/include/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/tcl/include/Makefile.am0000664000175000017500000000002214664224267012731 SUBDIRS = gensio gensio-3.0.0/tcl/include/gensio/0000775000175000017500000000000015061121735012233 5gensio-3.0.0/tcl/include/gensio/Makefile.in0000664000175000017500000005075215061121660014226 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = tcl/include/gensio ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(pkginclude_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkgincludedir)" HEADERS = $(pkginclude_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkginclude_HEADERS = gensio_tcl.h gensio_tcl_dllvisibility.h all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tcl/include/gensio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tcl/include/gensio/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkgincludeHEADERS: $(pkginclude_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ done uninstall-pkgincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pkgincludeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkgincludeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool cscopelist-am ctags ctags-am distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkgincludeHEADERS install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-pkgincludeHEADERS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/tcl/include/gensio/gensio_tcl.h0000664000175000017500000000076014664224267014471 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #ifndef GENSIO_TCL_H #define GENSIO_TCL_H #ifdef __cplusplus extern "C" { #endif #include #include /* * Allocate a tcl-based os funcs. */ GENSIOTCL_DLL_PUBLIC int gensio_tcl_funcs_alloc(struct gensio_os_funcs **o); #ifdef __cplusplus } #endif #endif /* GENSIO_TCL_H */ gensio-3.0.0/tcl/include/gensio/gensio_tcl_dllvisibility.h0000664000175000017500000000223114664224267017427 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #ifndef GENSIOTCL_DLLVISIBILITY #define GENSIOTCL_DLLVISIBILITY #if defined GENSIO_LINK_STATIC #define GENSIOTCL_DLL_PUBLIC #define GENSIOTCL_DLL_LOCAL #elif defined _WIN32 || defined __CYGWIN__ #ifdef BUILDING_GENSIOTCL_DLL #ifdef __GNUC__ #define GENSIOTCL_DLL_PUBLIC __attribute__ ((dllexport)) #else #define GENSIOTCL_DLL_PUBLIC __declspec(dllexport) // Note: actually gcc seems to also supports this syntax. #endif #else #ifdef __GNUC__ #define GENSIOTCL_DLL_PUBLIC __attribute__ ((dllimport)) #else #define GENSIOTCL_DLL_PUBLIC __declspec(dllimport) // Note: actually gcc seems to also supports this syntax. #endif #endif #define GENSIOTCL_DLL_LOCAL #else #if __GNUC__ >= 4 #define GENSIOTCL_DLL_PUBLIC __attribute__ ((visibility ("default"))) #define GENSIOTCL_DLL_LOCAL __attribute__ ((visibility ("hidden"))) #else #define GENSIOTCL_DLL_PUBLIC #define GENSIOTCL_DLL_LOCAL #endif #endif #endif /* GENSIOTCL_DLLVISIBILITY */ gensio-3.0.0/tcl/include/gensio/Makefile.am0000664000175000017500000000007614664224267014226 pkginclude_HEADERS = gensio_tcl.h gensio_tcl_dllvisibility.h gensio-3.0.0/install-sh0000755000175000017500000003577614556763366010532 #!/bin/sh # install - install a program, script, or datafile scriptversion=2020-11-14.01; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # 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 # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 # Create dirs (including intermediate dirs) using mode 755. # This is like GNU 'install' as of coreutils 8.32 (2020). mkdir_umask=22 backupsuffix= chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -p pass -p to $cpprog. -s $stripprog installed files. -S SUFFIX attempt to back up existing files, with suffix SUFFIX. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG By default, rm is invoked with -f; when overridden with RMPROG, it's up to you to specify -f if you want it. If -S is not specified, no backups are attempted. Email bug reports to bug-automake@gnu.org. Automake home page: https://www.gnu.org/software/automake/ " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -p) cpprog="$cpprog -p";; -s) stripcmd=$stripprog;; -S) backupsuffix="$2" shift;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? # Don't chown directories that already exist. if test $dstdir_status = 0; then chowncmd="" fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dstbase=`basename "$src"` case $dst in */) dst=$dst$dstbase;; *) dst=$dst/$dstbase;; esac dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi case $dstdir in */) dstdirslash=$dstdir;; *) dstdirslash=$dstdir/;; esac obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false # The $RANDOM variable is not portable (e.g., dash). Use it # here however when possible just to lower collision chance. tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap ' ret=$? rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null exit $ret ' 0 # Because "mkdir -p" follows existing symlinks and we likely work # directly in world-writeable /tmp, make sure that the '$tmpdir' # directory is successfully created first before we actually test # 'mkdir -p'. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=${dstdirslash}_inst.$$_ rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && { test -z "$stripcmd" || { # Create $dsttmp read-write so that cp doesn't create it read-only, # which would cause strip to fail. if test -z "$doit"; then : >"$dsttmp" # No need to fork-exec 'touch'. else $doit touch "$dsttmp" fi } } && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # If $backupsuffix is set, and the file being installed # already exists, attempt a backup. Don't worry if it fails, # e.g., if mv doesn't support -f. if test -n "$backupsuffix" && test -f "$dst"; then $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null fi # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: gensio-3.0.0/COPYING0000664000175000017500000004325414664224267007541 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. gensio-3.0.0/m4/0000775000175000017500000000000015061121734007061 5gensio-3.0.0/m4/ax_config_feature.m40000644000175000017500000001237213402532746012724 # =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_config_feature.html # =========================================================================== # # SYNOPSIS # # AX_CONFIG_FEATURE(FEATURE-NAME, FEATURE-DESCRIPTION, DEFINE, DEFINE-DESCRIPTION, [ACTION-IF-ENABLED [, ACTION-IF-NOT-ENABLED]]) # # DESCRIPTION # # AX_CONFIG_FEATURE is a simple wrapper for AC_ARG_ENABLE, it enables the # feature FEATURE-NAME and AC_DEFINEs the passed DEFINE, depending on the # user choice. DESCRIPTION will be used for AC_DEFINEs. ACTION-IF-ENABLED # and ACTION-IF-NOT-ENABLED are the actions that will be run. A feature is # enabled by default, in order to change this behaviour use the # AX_CONFIG_FEATURE_DEFAULT_ENABLED and AX_CONFIG_FEATURE_DEFAULT_DISABLED # macros. # # A simple example: # # AX_CONFIG_FEATURE_DEFAULT_ENABLED # AX_CONFIG_FEATURE(feature_xxxxx, [turns on/off XXXXX support], # HAVE_XXXXX, [Define if you want XXXXX support]) # # ... # # AX_CONFIG_FEATURE_DEFAULT_DISABLED # AX_CONFIG_FEATURE(feature_yyyyy, [turns on/off YYYYY support], # HAVE_YYYYY, [Define if you want YYYYY support], # [enable_yyyyy="yes"], [enable_yyyyy="no"]) # AM_CONDITIONAL(YYYYY, [test "$enable_yyyyy" = "yes"]) # # AX_CONFIG_FEATURE_DEFAULT_ENABLED # AX_CONFIG_FEATURE(...) # # ... # # If you have lot of features and you want a verbose dumping of each user # selection use AX_CONFIG_FEATURE_VERBOSE. Use AX_CONFIG_FEATURE_SILENT in # order to remove a previously AX_CONFIG_FEATURE_VERBOSE. By default # features are silent. # # Use AX_CONFIG_FEATURE_ENABLE or AX_CONFIG_FEATURE_DISABLE in order to # enable or disable a specific feature. # # Another simple example: # # AS_IF([some_test_here],[AX_CONFIG_FEATURE_ENABLE(feature_xxxxx)],[]) # # AX_CONFIG_FEATURE(feature_xxxxx, [turns on/off XXXXX support], # HAVE_XXXXX, [Define if you want XXXXX support]) # AX_CONFIG_FEATURE(feature_yyyyy, [turns on/off YYYYY support], # HAVE_YYYYY, [Define if you want YYYYY support], # [enable_yyyyy="yes"], [enable_yyyyy="no"]) # # ... # # NOTE: AX_CONFIG_FEATURE_ENABLE() must be placed first of the relative # AX_CONFIG_FEATURE() macro ... # # LICENSE # # Copyright (c) 2008 Francesco Salvestrini # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 10 AC_DEFUN([AX_CONFIG_FEATURE],[ dnl m4_pushdef([FEATURE], patsubst([$1], -, _))dnl AC_ARG_ENABLE([$1],AS_HELP_STRING([--enable-$1],[$2]),[ case "${enableval}" in yes) ax_config_feature_[]FEATURE[]="yes" ;; no) ax_config_feature_[]FEATURE[]="no" ;; *) AC_MSG_ERROR([bad value ${enableval} for feature --$1]) ;; esac ]) AS_IF([test "$ax_config_feature_[]FEATURE[]" = yes],[ dnl AC_DEFINE([$3]) $5 AS_IF([test "$ax_config_feature_verbose" = yes],[ dnl AC_MSG_NOTICE([Feature $1 is enabled]) ]) ],[ dnl $6 AS_IF([test "$ax_config_feature_verbose" = yes],[ dnl AC_MSG_NOTICE([Feature $1 is disabled]) ]) ]) AH_TEMPLATE([$3],[$4]) m4_popdef([FEATURE])dnl ]) dnl Feature global AC_DEFUN([AX_CONFIG_FEATURE_VERBOSE],[ dnl ax_config_feature_verbose=yes ]) dnl Feature global AC_DEFUN([AX_CONFIG_FEATURE_SILENT],[ dnl ax_config_feature_verbose=no ]) dnl Feature specific AC_DEFUN([AX_CONFIG_FEATURE_DEFAULT_ENABLED], [ ax_config_feature_[]FEATURE[]_default=yes ]) dnl Feature specific AC_DEFUN([AX_CONFIG_FEATURE_DEFAULT_DISABLED], [ ax_config_feature_[]FEATURE[]_default=no ]) dnl Feature specific AC_DEFUN([AX_CONFIG_FEATURE_ENABLE],[ dnl ax_config_feature_[]patsubst([$1], -, _)[]=yes ]) dnl Feature specific AC_DEFUN([AX_CONFIG_FEATURE_DISABLE],[ dnl ax_config_feature_[]patsubst([$1], -, _)[]=no ]) gensio-3.0.0/m4/ax_cxx_compile_stdcxx.m40000664000175000017500000005207314664224267013666 # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html # =========================================================================== # # SYNOPSIS # # AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) # # DESCRIPTION # # Check for baseline language coverage in the compiler for the specified # version of the C++ standard. If necessary, add switches to CXX and # CXXCPP to enable support. VERSION may be '11', '14', '17', or '20' for # the respective C++ standard version. # # The second argument, if specified, indicates whether you insist on an # extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. # -std=c++11). If neither is specified, you get whatever works, with # preference for no added switch, and then for an extended mode. # # The third argument, if specified 'mandatory' or if left unspecified, # indicates that baseline support for the specified C++ standard is # required and that the macro should error out if no mode with that # support is found. If specified 'optional', then configuration proceeds # regardless, after defining HAVE_CXX${VERSION} if and only if a # supporting mode is found. # # LICENSE # # Copyright (c) 2008 Benjamin Kosnik # Copyright (c) 2012 Zack Weinberg # Copyright (c) 2013 Roy Stogner # Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov # Copyright (c) 2015 Paul Norman # Copyright (c) 2015 Moritz Klammler # Copyright (c) 2016, 2018 Krzesimir Nowak # Copyright (c) 2019 Enji Cooper # Copyright (c) 2020 Jason Merrill # Copyright (c) 2021 Jörn Heusipp # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 18 dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro dnl (serial version number 13). AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], [$1], [14], [ax_cxx_compile_alternatives="14 1y"], [$1], [17], [ax_cxx_compile_alternatives="17 1z"], [$1], [20], [ax_cxx_compile_alternatives="20"], [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$2], [], [], [$2], [ext], [], [$2], [noext], [], [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], [$3], [optional], [ax_cxx_compile_cxx$1_required=false], [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) AC_LANG_PUSH([C++])dnl ac_success=no m4_if([$2], [], [dnl AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, ax_cv_cxx_compile_cxx$1, [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [ax_cv_cxx_compile_cxx$1=yes], [ax_cv_cxx_compile_cxx$1=no])]) if test x$ax_cv_cxx_compile_cxx$1 = xyes; then ac_success=yes fi]) m4_if([$2], [noext], [], [dnl if test x$ac_success = xno; then for alternative in ${ax_cxx_compile_alternatives}; do switch="-std=gnu++${alternative}" cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, [ac_save_CXX="$CXX" CXX="$CXX $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [eval $cachevar=yes], [eval $cachevar=no]) CXX="$ac_save_CXX"]) if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done fi]) m4_if([$2], [ext], [], [dnl if test x$ac_success = xno; then dnl HP's aCC needs +std=c++11 according to: dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf dnl Cray's crayCC needs "-h std=c++11" dnl MSVC needs -std:c++NN for C++17 and later (default is C++14) for alternative in ${ax_cxx_compile_alternatives}; do for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}" MSVC; do if test x"$switch" = xMSVC; then dnl AS_TR_SH maps both `:` and `=` to `_` so -std:c++17 would collide dnl with -std=c++17. We suffix the cache variable name with _MSVC to dnl avoid this. switch=-std:c++${alternative} cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_${switch}_MSVC]) else cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) fi AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, [ac_save_CXX="$CXX" CXX="$CXX $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [eval $cachevar=yes], [eval $cachevar=no]) CXX="$ac_save_CXX"]) if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done if test x$ac_success = xyes; then break fi done fi]) AC_LANG_POP([C++]) if test x$ax_cxx_compile_cxx$1_required = xtrue; then if test x$ac_success = xno; then AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) fi fi if test x$ac_success = xno; then HAVE_CXX$1=0 AC_MSG_NOTICE([No compiler with C++$1 support was found]) else HAVE_CXX$1=1 AC_DEFINE(HAVE_CXX$1,1, [define if the compiler supports basic C++$1 syntax]) fi AC_SUBST(HAVE_CXX$1) ]) dnl Test body for checking C++11 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 ) dnl Test body for checking C++14 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 ) dnl Test body for checking C++17 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 ) dnl Test body for checking C++20 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 _AX_CXX_COMPILE_STDCXX_testbody_new_in_20 ) dnl Tests for new features in C++11 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" // MSVC always sets __cplusplus to 199711L in older versions; newer versions // only set it correctly if /Zc:__cplusplus is specified as well as a // /std:c++NN switch: // https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ #elif __cplusplus < 201103L && !defined _MSC_VER #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { virtual ~Derived() override {} virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L ]]) dnl Tests for new features in C++14 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ // If the compiler admits that it is not ready for C++14, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201402L && !defined _MSC_VER #error "This is not a C++14 compiler" #else namespace cxx14 { namespace test_polymorphic_lambdas { int test() { const auto lambda = [](auto&&... args){ const auto istiny = [](auto x){ return (sizeof(x) == 1UL) ? 1 : 0; }; const int aretiny[] = { istiny(args)... }; return aretiny[0]; }; return lambda(1, 1L, 1.0f, '1'); } } namespace test_binary_literals { constexpr auto ivii = 0b0000000000101010; static_assert(ivii == 42, "wrong value"); } namespace test_generalized_constexpr { template < typename CharT > constexpr unsigned long strlen_c(const CharT *const s) noexcept { auto length = 0UL; for (auto p = s; *p; ++p) ++length; return length; } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("x") == 1UL, ""); static_assert(strlen_c("test") == 4UL, ""); static_assert(strlen_c("another\0test") == 7UL, ""); } namespace test_lambda_init_capture { int test() { auto x = 0; const auto lambda1 = [a = x](int b){ return a + b; }; const auto lambda2 = [a = lambda1(x)](){ return a; }; return lambda2(); } } namespace test_digit_separators { constexpr auto ten_million = 100'000'000; static_assert(ten_million == 100000000, ""); } namespace test_return_type_deduction { auto f(int& x) { return x; } decltype(auto) g(int& x) { return x; } template < typename T1, typename T2 > struct is_same { static constexpr auto value = false; }; template < typename T > struct is_same { static constexpr auto value = true; }; int test() { auto x = 0; static_assert(is_same::value, ""); static_assert(is_same::value, ""); return x; } } } // namespace cxx14 #endif // __cplusplus >= 201402L ]]) dnl Tests for new features in C++17 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ // If the compiler admits that it is not ready for C++17, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201703L && !defined _MSC_VER #error "This is not a C++17 compiler" #else #include #include #include namespace cxx17 { namespace test_constexpr_lambdas { constexpr int foo = [](){return 42;}(); } namespace test::nested_namespace::definitions { } namespace test_fold_expression { template int multiply(Args... args) { return (args * ... * 1); } template bool all(Args... args) { return (args && ...); } } namespace test_extended_static_assert { static_assert (true); } namespace test_auto_brace_init_list { auto foo = {5}; auto bar {5}; static_assert(std::is_same, decltype(foo)>::value); static_assert(std::is_same::value); } namespace test_typename_in_template_template_parameter { template typename X> struct D; } namespace test_fallthrough_nodiscard_maybe_unused_attributes { int f1() { return 42; } [[nodiscard]] int f2() { [[maybe_unused]] auto unused = f1(); switch (f1()) { case 17: f1(); [[fallthrough]]; case 42: f1(); } return f1(); } } namespace test_extended_aggregate_initialization { struct base1 { int b1, b2 = 42; }; struct base2 { base2() { b3 = 42; } int b3; }; struct derived : base1, base2 { int d; }; derived d1 {{1, 2}, {}, 4}; // full initialization derived d2 {{}, {}, 4}; // value-initialized bases } namespace test_general_range_based_for_loop { struct iter { int i; int& operator* () { return i; } const int& operator* () const { return i; } iter& operator++() { ++i; return *this; } }; struct sentinel { int i; }; bool operator== (const iter& i, const sentinel& s) { return i.i == s.i; } bool operator!= (const iter& i, const sentinel& s) { return !(i == s); } struct range { iter begin() const { return {0}; } sentinel end() const { return {5}; } }; void f() { range r {}; for (auto i : r) { [[maybe_unused]] auto v = i; } } } namespace test_lambda_capture_asterisk_this_by_value { struct t { int i; int foo() { return [*this]() { return i; }(); } }; } namespace test_enum_class_construction { enum class byte : unsigned char {}; byte foo {42}; } namespace test_constexpr_if { template int f () { if constexpr(cond) { return 13; } else { return 42; } } } namespace test_selection_statement_with_initializer { int f() { return 13; } int f2() { if (auto i = f(); i > 0) { return 3; } switch (auto i = f(); i + 4) { case 17: return 2; default: return 1; } } } namespace test_template_argument_deduction_for_class_templates { template struct pair { pair (T1 p1, T2 p2) : m1 {p1}, m2 {p2} {} T1 m1; T2 m2; }; void f() { [[maybe_unused]] auto p = pair{13, 42u}; } } namespace test_non_type_auto_template_parameters { template struct B {}; B<5> b1; B<'a'> b2; } namespace test_structured_bindings { int arr[2] = { 1, 2 }; std::pair pr = { 1, 2 }; auto f1() -> int(&)[2] { return arr; } auto f2() -> std::pair& { return pr; } struct S { int x1 : 2; volatile double y1; }; S f3() { return {}; } auto [ x1, y1 ] = f1(); auto& [ xr1, yr1 ] = f1(); auto [ x2, y2 ] = f2(); auto& [ xr2, yr2 ] = f2(); const auto [ x3, y3 ] = f3(); } namespace test_exception_spec_type_system { struct Good {}; struct Bad {}; void g1() noexcept; void g2(); template Bad f(T*, T*); template Good f(T1*, T2*); static_assert (std::is_same_v); } namespace test_inline_variables { template void f(T) {} template inline T g(T) { return T{}; } template<> inline void f<>(int) {} template<> int g<>(int) { return 5; } } } // namespace cxx17 #endif // __cplusplus < 201703L && !defined _MSC_VER ]]) dnl Tests for new features in C++20 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[ #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 202002L && !defined _MSC_VER #error "This is not a C++20 compiler" #else #include namespace cxx20 { // As C++20 supports feature test macros in the standard, there is no // immediate need to actually test for feature availability on the // Autoconf side. } // namespace cxx20 #endif // __cplusplus < 202002L && !defined _MSC_VER ]]) gensio-3.0.0/m4/ax_check_openssl.m40000664000175000017500000001164014666741453012575 # =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_check_openssl.html # =========================================================================== # # SYNOPSIS # # AX_CHECK_OPENSSL([action-if-found[, action-if-not-found]]) # # DESCRIPTION # # Look for OpenSSL in a number of default spots, or in a user-selected # spot (via --with-openssl). Sets # # OPENSSL_INCLUDES to the include directives required # OPENSSL_LIBS to the -l directives required # OPENSSL_LDFLAGS to the -L or -R flags required # # and calls ACTION-IF-FOUND or ACTION-IF-NOT-FOUND appropriately # # This macro sets OPENSSL_INCLUDES such that source files should use the # openssl/ directory in include directives: # # #include # # LICENSE # # Copyright (c) 2009,2010 Zmanda Inc. # Copyright (c) 2009,2010 Dustin J. Mitchell # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 8 AU_ALIAS([CHECK_SSL], [AX_CHECK_OPENSSL]) AC_DEFUN([AX_CHECK_OPENSSL], [ found=false tryopenssl=true ssldirs="" AC_ARG_WITH([openssl], [AS_HELP_STRING([--with-openssl[[=yes|no|PATH]]], [Look for OpenSSL, with optional root of the OpenSSL directory])], [ case "$withval" in "" | y | ye | yes) ;; n | no) tryopenssl=false ;; *) ssldirs="$withval" ;; esac ], []) if $tryopenssl; then if test x"$ssldirs" = x""; then # if pkg-config is installed and openssl has installed a .pc file, # then use that information and don't search ssldirs AC_PATH_PROG([PKG_CONFIG], [pkg-config]) if test x"$PKG_CONFIG" != x""; then OPENSSL_LDFLAGS=`$PKG_CONFIG openssl --libs-only-L 2>/dev/null` if test $? = 0; then OPENSSL_LIBS=`$PKG_CONFIG openssl --libs-only-l 2>/dev/null` OPENSSL_INCLUDES=`$PKG_CONFIG openssl --cflags-only-I 2>/dev/null` found=true fi fi # no such luck; use some default ssldirs if ! $found; then ssldirs="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr" # Defaults for some specific targets case $target_os in mingw*) case $target_cpu in i686) ssldirs="/mingw32 $ssldirs" ;; x86_64) case "$MSYSTEM" in UCRT64) ssldirs="/ucrt64 $ssldirs" ;; MINGW64) ssldirs="/mingw64 $ssldirs" ;; esac ;; esac ;; darwin*) ssldirs="$ssldirs /opt/homebrew" ;; esac fi fi # note that we #include , so the OpenSSL headers have to be in # an 'openssl' subdirectory if ! $found; then OPENSSL_INCLUDES= for ssldir in $ssldirs; do AC_MSG_CHECKING([for openssl/ssl.h in $ssldir]) if test -f "$ssldir/include/openssl/ssl.h"; then OPENSSL_INCLUDES="-I$ssldir/include" OPENSSL_LDFLAGS="-L$ssldir/lib" OPENSSL_LIBS="-lssl -lcrypto" found=true AC_MSG_RESULT([yes]) break else AC_MSG_RESULT([no]) fi done # if the file wasn't found, well, go ahead and try the link anyway -- maybe # it will just work! fi # try the preprocessor and linker with our new flags, # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS AC_MSG_CHECKING([whether compiling and linking against OpenSSL works]) echo "Trying link with OPENSSL_LDFLAGS=$OPENSSL_LDFLAGS;" \ "OPENSSL_LIBS=$OPENSSL_LIBS; OPENSSL_INCLUDES=$OPENSSL_INCLUDES" >&AS_MESSAGE_LOG_FD save_LIBS="$LIBS" save_LDFLAGS="$LDFLAGS" save_CPPFLAGS="$CPPFLAGS" LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS" LIBS="$OPENSSL_LIBS $LIBS" CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS" AC_LINK_IFELSE( [AC_LANG_PROGRAM([#include ], [SSL_new(NULL)])], [ AC_MSG_RESULT([yes]) $1 ], [ AC_MSG_RESULT([no]) $2 ]) CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" AC_SUBST([OPENSSL_INCLUDES]) AC_SUBST([OPENSSL_LIBS]) AC_SUBST([OPENSSL_LDFLAGS]) else AC_MSG_NOTICE([Skipping openssl check, openssl disabled]) $2 fi ]) gensio-3.0.0/m4/ax_have_epoll.m40000644000175000017500000000705513402532746012064 # =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_have_epoll.html # =========================================================================== # # SYNOPSIS # # AX_HAVE_EPOLL([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # AX_HAVE_EPOLL_PWAIT([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # # DESCRIPTION # # This macro determines whether the system supports the epoll I/O event # interface. A neat usage example would be: # # AX_HAVE_EPOLL( # [AX_CONFIG_FEATURE_ENABLE(epoll)], # [AX_CONFIG_FEATURE_DISABLE(epoll)]) # AX_CONFIG_FEATURE( # [epoll], [This platform supports epoll(7)], # [HAVE_EPOLL], [This platform supports epoll(7).]) # # The epoll interface was added to the Linux kernel in version 2.5.45, and # the macro verifies that a kernel newer than this is installed. This # check is somewhat unreliable if doesn't match the # running kernel, but it is necessary regardless, because glibc comes with # stubs for the epoll_create(), epoll_wait(), etc. that allow programs to # compile and link even if the kernel is too old; the problem would then # be detected only at runtime. # # Linux kernel version 2.6.19 adds the epoll_pwait() call in addition to # epoll_wait(). The availability of that function can be tested with the # second macro. Generally speaking, it is safe to assume that # AX_HAVE_EPOLL would succeed if AX_HAVE_EPOLL_PWAIT has, but not the # other way round. # # LICENSE # # Copyright (c) 2008 Peter Simons # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 10 AC_DEFUN([AX_HAVE_EPOLL], [dnl ax_have_epoll_cppflags="${CPPFLAGS}" AC_CHECK_HEADER([linux/version.h], [CPPFLAGS="${CPPFLAGS} -DHAVE_LINUX_VERSION_H"]) AC_MSG_CHECKING([for Linux epoll(7) interface]) AC_CACHE_VAL([ax_cv_have_epoll], [dnl AC_LINK_IFELSE([dnl AC_LANG_PROGRAM([dnl #include #ifdef HAVE_LINUX_VERSION_H # include # if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45) # error linux kernel version is too old to have epoll # endif #endif ], [dnl int fd, rc; struct epoll_event ev; fd = epoll_create(128); rc = epoll_wait(fd, &ev, 1, 0);])], [ax_cv_have_epoll=yes], [ax_cv_have_epoll=no])]) CPPFLAGS="${ax_have_epoll_cppflags}" AS_IF([test "${ax_cv_have_epoll}" = "yes"], [AC_MSG_RESULT([yes]) $1],[AC_MSG_RESULT([no]) $2]) ])dnl AC_DEFUN([AX_HAVE_EPOLL_PWAIT], [dnl ax_have_epoll_cppflags="${CPPFLAGS}" AC_CHECK_HEADER([linux/version.h], [CPPFLAGS="${CPPFLAGS} -DHAVE_LINUX_VERSION_H"]) AC_MSG_CHECKING([for Linux epoll(7) interface with signals extension]) AC_CACHE_VAL([ax_cv_have_epoll_pwait], [dnl AC_LINK_IFELSE([dnl AC_LANG_PROGRAM([dnl #ifdef HAVE_LINUX_VERSION_H # include # if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) # error linux kernel version is too old to have epoll_pwait # endif #endif #include #include ], [dnl int fd, rc; struct epoll_event ev; fd = epoll_create(128); rc = epoll_wait(fd, &ev, 1, 0); rc = epoll_pwait(fd, &ev, 1, 0, (sigset_t const *)(0));])], [ax_cv_have_epoll_pwait=yes], [ax_cv_have_epoll_pwait=no])]) CPPFLAGS="${ax_have_epoll_cppflags}" AS_IF([test "${ax_cv_have_epoll_pwait}" = "yes"], [AC_MSG_RESULT([yes]) $1],[AC_MSG_RESULT([no]) $2]) ])dnl gensio-3.0.0/m4/ltsugar.m40000644000175000017500000001045314605013133010721 # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2022 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) gensio-3.0.0/m4/ax_prog_python_version.m40000664000175000017500000000406614236753312014064 # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_prog_python_version.html # =========================================================================== # # SYNOPSIS # # AX_PROG_PYTHON_VERSION([VERSION],[ACTION-IF-TRUE],[ACTION-IF-FALSE]) # # DESCRIPTION # # Makes sure that python supports the version indicated. If true the shell # commands in ACTION-IF-TRUE are executed. If not the shell commands in # ACTION-IF-FALSE are run. Note if $PYTHON is not set (for example by # running AC_CHECK_PROG or AC_PATH_PROG) the macro will fail. # # Example: # # AC_PATH_PROG([PYTHON],[python]) # AX_PROG_PYTHON_VERSION([2.4.4],[ ... ],[ ... ]) # # This will check to make sure that the python you have supports at least # version 2.4.4. # # NOTE: This macro uses the $PYTHON variable to perform the check. # AX_WITH_PYTHON can be used to set that variable prior to running this # macro. The $PYTHON_VERSION variable will be valorized with the detected # version. # # LICENSE # # Copyright (c) 2009 Francesco Salvestrini # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 12 AC_DEFUN([AX_PROG_PYTHON_VERSION],[ AC_REQUIRE([AC_PROG_SED]) AC_REQUIRE([AC_PROG_GREP]) AS_IF([test -n "$PYTHON"],[ ax_python_version="$1" AC_MSG_CHECKING([for python version]) changequote(<<,>>) python_version=`$PYTHON -V 2>&1 | $GREP "^Python " | $SED -e 's/^.* \([0-9]*\.[0-9]*\.[0-9]*\)/\1/'` changequote([,]) AC_MSG_RESULT($python_version) AC_SUBST([PYTHON_VERSION],[$python_version]) AX_COMPARE_VERSION([$ax_python_version],[le],[$python_version],[ : $2 ],[ : $3 ]) ],[ AC_MSG_WARN([could not find the python interpreter]) $3 ]) ]) gensio-3.0.0/m4/ltversion.m40000644000175000017500000000131214605013133011257 # ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2019, 2021-2022 Free Software Foundation, # Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 4245 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.7]) m4_define([LT_PACKAGE_REVISION], [2.4.7]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.7' macro_revision='2.4.7' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) gensio-3.0.0/m4/ax_python_devel.m40000664000175000017500000003723714664224267012464 # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_python_devel.html # =========================================================================== # # SYNOPSIS # # AX_PYTHON_DEVEL([version[,optional]]) # # DESCRIPTION # # Note: Defines as a precious variable "PYTHON_VERSION". Don't override it # in your configure.ac. # # This macro checks for Python and tries to get the include path to # 'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LIBS) output # variables. It also exports $(PYTHON_EXTRA_LIBS) and # $(PYTHON_EXTRA_LDFLAGS) for embedding Python in your code. # # You can search for some particular version of Python by passing a # parameter to this macro, for example ">= '2.3.1'", or "== '2.4'". Please # note that you *have* to pass also an operator along with the version to # match, and pay special attention to the single quotes surrounding the # version number. Don't use "PYTHON_VERSION" for this: that environment # variable is declared as precious and thus reserved for the end-user. # # By default this will fail if it does not detect a development version of # python. If you want it to continue, set optional to true, like # AX_PYTHON_DEVEL([], [true]). The ax_python_devel_found variable will be # "no" if it fails. # # This macro should work for all versions of Python >= 2.1.0. As an end # user, you can disable the check for the python version by setting the # PYTHON_NOVERSIONCHECK environment variable to something else than the # empty string. # # If you need to use this macro for an older Python version, please # contact the authors. We're always open for feedback. # # LICENSE # # Copyright (c) 2009 Sebastian Huber # Copyright (c) 2009 Alan W. Irwin # Copyright (c) 2009 Rafael Laboissiere # Copyright (c) 2009 Andrew Collier # Copyright (c) 2009 Matteo Settenvini # Copyright (c) 2009 Horst Knorr # Copyright (c) 2013 Daniel Mullner # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 36 AU_ALIAS([AC_PYTHON_DEVEL], [AX_PYTHON_DEVEL]) AC_DEFUN([AX_PYTHON_DEVEL],[ # Get whether it's optional if test -z "$2"; then ax_python_devel_optional=false else ax_python_devel_optional=$2 fi ax_python_devel_found=yes # # Allow the use of a (user set) custom python version # AC_ARG_VAR([PYTHON_VERSION],[The installed Python version to use, for example '2.3'. This string will be appended to the Python interpreter canonical name.]) AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]]) if test -z "$PYTHON"; then AC_MSG_WARN([Cannot find python$PYTHON_VERSION in your system path]) if ! $ax_python_devel_optional; then AC_MSG_ERROR([Giving up, python development not available]) fi ax_python_devel_found=no PYTHON_VERSION="" fi if test $ax_python_devel_found = yes; then # # Check for a version of Python >= 2.1.0 # AC_MSG_CHECKING([for a version of Python >= '2.1.0']) ac_supports_python_ver=`$PYTHON -c "import sys; \ ver = sys.version.split ()[[0]]; \ print (ver >= '2.1.0')"` if test "$ac_supports_python_ver" != "True"; then if test -z "$PYTHON_NOVERSIONCHECK"; then AC_MSG_RESULT([no]) AC_MSG_WARN([ This version of the AC@&t@_PYTHON_DEVEL macro doesn't work properly with versions of Python before 2.1.0. You may need to re-run configure, setting the variables PYTHON_CPPFLAGS, PYTHON_LIBS, PYTHON_SITE_PKG, PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand. Moreover, to disable this check, set PYTHON_NOVERSIONCHECK to something else than an empty string. ]) if ! $ax_python_devel_optional; then AC_MSG_FAILURE([Giving up]) fi ax_python_devel_found=no PYTHON_VERSION="" else AC_MSG_RESULT([skip at user request]) fi else AC_MSG_RESULT([yes]) fi fi if test $ax_python_devel_found = yes; then # # If the macro parameter ``version'' is set, honour it. # A Python shim class, VPy, is used to implement correct version comparisons via # string expressions, since e.g. a naive textual ">= 2.7.3" won't work for # Python 2.7.10 (the ".1" being evaluated as less than ".3"). # if test -n "$1"; then AC_MSG_CHECKING([for a version of Python $1]) cat << EOF > ax_python_devel_vpy.py class VPy: def vtup(self, s): return tuple(map(int, s.strip().replace("rc", ".").split("."))) def __init__(self): import sys self.vpy = tuple(sys.version_info)[[:3]] def __eq__(self, s): return self.vpy == self.vtup(s) def __ne__(self, s): return self.vpy != self.vtup(s) def __lt__(self, s): return self.vpy < self.vtup(s) def __gt__(self, s): return self.vpy > self.vtup(s) def __le__(self, s): return self.vpy <= self.vtup(s) def __ge__(self, s): return self.vpy >= self.vtup(s) EOF ac_supports_python_ver=`$PYTHON -c "import ax_python_devel_vpy; \ ver = ax_python_devel_vpy.VPy(); \ print (ver $1)"` rm -rf ax_python_devel_vpy*.py* __pycache__/ax_python_devel_vpy*.py* if test "$ac_supports_python_ver" = "True"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) AC_MSG_WARN([this package requires Python $1. If you have it installed, but it isn't the default Python interpreter in your system path, please pass the PYTHON_VERSION variable to configure. See ``configure --help'' for reference. ]) if ! $ax_python_devel_optional; then AC_MSG_ERROR([Giving up]) fi ax_python_devel_found=no PYTHON_VERSION="" fi fi fi if test $ax_python_devel_found = yes; then # # Check if you have distutils, else fail # AC_MSG_CHECKING([for the sysconfig Python package]) ac_sysconfig_result=`$PYTHON -c "import sysconfig" 2>&1` if test $? -eq 0; then AC_MSG_RESULT([yes]) IMPORT_SYSCONFIG="import sysconfig" else AC_MSG_RESULT([no]) AC_MSG_CHECKING([for the distutils Python package]) ac_sysconfig_result=`$PYTHON -c "from distutils import sysconfig" 2>&1` if test $? -eq 0; then AC_MSG_RESULT([yes]) IMPORT_SYSCONFIG="from distutils import sysconfig" else AC_MSG_WARN([cannot import Python module "distutils". Please check your Python installation. The error was: $ac_sysconfig_result]) if ! $ax_python_devel_optional; then AC_MSG_ERROR([Giving up]) fi ax_python_devel_found=no PYTHON_VERSION="" fi fi fi if test $ax_python_devel_found = yes; then # # Check for Python include path # AC_MSG_CHECKING([for Python include path]) if test -z "$PYTHON_CPPFLAGS"; then if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then # sysconfig module has different functions python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \ print (sysconfig.get_path ('include'));"` plat_python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \ print (sysconfig.get_path ('platinclude'));"` else # old distutils way python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \ print (sysconfig.get_python_inc ());"` plat_python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \ print (sysconfig.get_python_inc (plat_specific=1));"` fi if test -n "${python_path}"; then if test "${plat_python_path}" != "${python_path}"; then python_path="-I$python_path -I$plat_python_path" else python_path="-I$python_path" fi fi PYTHON_CPPFLAGS=$python_path fi AC_MSG_RESULT([$PYTHON_CPPFLAGS]) AC_SUBST([PYTHON_CPPFLAGS]) # # Check for Python library path # AC_MSG_CHECKING([for Python library path]) if test -z "$PYTHON_LIBS"; then # (makes two attempts to ensure we've got a version number # from the interpreter) ac_python_version=`cat<]], [[Py_Initialize();]]) ],[pythonexists=yes],[pythonexists=no]) AC_LANG_POP([C]) # turn back to default flags CPPFLAGS="$ac_save_CPPFLAGS" LIBS="$ac_save_LIBS" LDFLAGS="$ac_save_LDFLAGS" AC_MSG_RESULT([$pythonexists]) if test ! "x$pythonexists" = "xyes"; then AC_MSG_WARN([ Could not link test program to Python. Maybe the main Python library has been installed in some non-standard library path. If so, pass it to configure, via the LIBS environment variable. Example: ./configure LIBS="-L/usr/non-standard-path/python/lib" ============================================================================ ERROR! You probably have to install the development version of the Python package for your distribution. The exact name of this package varies among them. ============================================================================ ]) if ! $ax_python_devel_optional; then AC_MSG_ERROR([Giving up]) fi ax_python_devel_found=no PYTHON_VERSION="" fi fi # # all done! # ]) gensio-3.0.0/m4/lt~obsolete.m40000644000175000017500000001400714605013133011611 # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2022 Free # Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) gensio-3.0.0/m4/libtool.m40000644000175000017500000113165214605013133010712 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996-2001, 2003-2019, 2021-2022 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ]) # serial 59 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_PREPARE_CC_BASENAME # ----------------------- m4_defun([_LT_PREPARE_CC_BASENAME], [ # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in @S|@*""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } ])# _LT_PREPARE_CC_BASENAME # _LT_CC_BASENAME(CC) # ------------------- # It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, # but that macro is also expanded into generated libtool script, which # arranges for $SED and $ECHO to be set by different means. m4_defun([_LT_CC_BASENAME], [m4_require([_LT_PREPARE_CC_BASENAME])dnl AC_REQUIRE([_LT_DECL_SED])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl func_cc_basename $1 cc_basename=$func_cc_basename_result ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_DECL_FILECMD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl m4_require([_LT_CMD_TRUNCATE])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC and # ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the 'libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to 'config.status' so that its # declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags='_LT_TAGS'dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into 'config.status', and then the shell code to quote escape them in # for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ '$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test 0 != $[#] do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try '$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 _LT_COPYING _LT_LIBTOOL_TAGS # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE _LT_PREPARE_MUNGE_PATH_LIST _LT_PREPARE_CC_BASENAME # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) case $MACOSX_DEPLOYMENT_TARGET,$host in 10.[[012]],*|,*powerpc*-darwin[[5-8]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; *) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test yes = "$lt_cv_ld_force_load"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" _LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script that will find a shell with a builtin # printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [m4_require([_LT_DECL_SED])dnl AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} _LT_DECL([], [AR], [1], [The archiver]) # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have # higher priority because thats what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} lt_ar_flags=$AR_FLAGS _LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)]) # Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override # by AR_FLAGS because that was never working and AR_FLAGS is about to die. _LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS ]) if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) ]) ]) ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links=nottested if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test no = "$hard_links"; then AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -z "$STRIP"; then AC_MSG_RESULT([no]) else if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else case $host_os in darwin*) # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) ;; freebsd*) if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_PREPARE_MUNGE_PATH_LIST # --------------------------- # Make sure func_munge_path_list() is defined correctly. m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], [[# func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x@S|@2 in x) ;; *:) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" ;; x:*) eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; *::*) eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" ;; *) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; esac } ]])# _LT_PREPARE_PATH_LIST # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown AC_ARG_VAR([LT_SYS_LIBRARY_PATH], [User-defined run-time library search path.]) case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a[(]lib.so.V[)]' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], [Detected run-time system search path for libraries]) _LT_DECL([], [configure_time_lt_sys_library_path], [2], [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$1"; then lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], [if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi]) rm -f conftest.i conftest2.i conftest.out]) ])# _LT_PATH_DD # _LT_CMD_TRUNCATE # ---------------- # find command to truncate a binary pipe m4_defun([_LT_CMD_TRUNCATE], [m4_require([_LT_PATH_DD]) AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], [printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) _LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], [Command to truncate a binary pipe]) ])# _LT_CMD_TRUNCATE # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_MAGIC_METHOD], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[[4-9]]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # _LT_DLL_DEF_P([FILE]) # --------------------- # True iff FILE is a Windows DLL '.def' file. # Keep in sync with func_dll_def_p in the libtool script AC_DEFUN([_LT_DLL_DEF_P], [dnl test DEF = "`$SED -n dnl -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl -e q dnl Only consider the first "real" line $1`" dnl ])# _LT_DLL_DEF_P # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([nm_interface], [lt_cv_nm_interface], [1], [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # flang / f18. f95 an alias for gfortran or flang on Debian flang* | f18* | f95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl* | icl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl* | icl*) # Native MSVC or ICC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC and ICC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly* | midnightbsd*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS=$save_LDFLAGS]) if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi _LT_TAGVAR(link_all_deplibs, $1)=no else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; osf3*) if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test yes = "$GCC"; then wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC=$lt_save_CC ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl* | ,icl* | no,icl*) # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(GCC, $1)=$GXX _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case @S|@2 in .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)=$prev$p else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$G77 _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_FILECMD # ---------------- # Check for a file(cmd) program that can be used to detect file type and magic m4_defun([_LT_DECL_FILECMD], [AC_CHECK_TOOL([FILECMD], [file], [:]) _LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types]) ])# _LD_DECL_FILECMD # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS gensio-3.0.0/m4/ax_pkg_swig.m40000664000175000017500000001545414664224267011573 # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html # =========================================================================== # # SYNOPSIS # # AX_PKG_SWIG([major.minor.micro], [action-if-found], [action-if-not-found]) # # DESCRIPTION # # This macro searches for a SWIG installation on your system. If found, # then SWIG is AC_SUBST'd; if not found, then $SWIG is empty. If SWIG is # found, then SWIG_LIB is set to the SWIG library path, and AC_SUBST'd. # # You can use the optional first argument to check if the version of the # available SWIG is greater than or equal to the value of the argument. It # should have the format: N[.N[.N]] (N is a number between 0 and 999. Only # the first N is mandatory.) If the version argument is given (e.g. # 1.3.17), AX_PKG_SWIG checks that the swig package is this version number # or higher. # # As usual, action-if-found is executed if SWIG is found, otherwise # action-if-not-found is executed. # # In configure.in, use as: # # AX_PKG_SWIG(1.3.17, [], [ AC_MSG_ERROR([SWIG is required to build..]) ]) # AX_SWIG_ENABLE_CXX # AX_SWIG_MULTI_MODULE_SUPPORT # AX_SWIG_PYTHON # # LICENSE # # Copyright (c) 2008 Sebastian Huber # Copyright (c) 2008 Alan W. Irwin # Copyright (c) 2008 Rafael Laboissiere # Copyright (c) 2008 Andrew Collier # Copyright (c) 2011 Murray Cumming # Copyright (c) 2018 Reini Urban # Copyright (c) 2021 Vincent Danjean # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 15 AC_DEFUN([AX_PKG_SWIG],[ # Find path to the "swig" executable. AC_PATH_PROGS([SWIG],[swig swig3.0 swig2.0]) if test -z "$SWIG" ; then m4_ifval([$3],[$3],[:]) elif test -z "$1" ; then m4_ifval([$2],[$2],[:]) else AC_MSG_CHECKING([SWIG version]) [swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`] AC_MSG_RESULT([$swig_version]) if test -n "$swig_version" ; then # Calculate the required version number components [required=$1] [required_major=`echo $required | sed 's/[^0-9].*//'`] if test -z "$required_major" ; then [required_major=0] fi [required=`echo $required. | sed 's/[0-9]*[^0-9]//'`] [required_minor=`echo $required | sed 's/[^0-9].*//'`] if test -z "$required_minor" ; then [required_minor=0] fi [required=`echo $required. | sed 's/[0-9]*[^0-9]//'`] [required_patch=`echo $required | sed 's/[^0-9].*//'`] if test -z "$required_patch" ; then [required_patch=0] fi # Calculate the available version number components [available=$swig_version] [available_major=`echo $available | sed 's/[^0-9].*//'`] if test -z "$available_major" ; then [available_major=0] fi [available=`echo $available | sed 's/[0-9]*[^0-9]//'`] [available_minor=`echo $available | sed 's/[^0-9].*//'`] if test -z "$available_minor" ; then [available_minor=0] fi [available=`echo $available | sed 's/[0-9]*[^0-9]//'`] [available_patch=`echo $available | sed 's/[^0-9].*//'`] if test -z "$available_patch" ; then [available_patch=0] fi # Convert the version tuple into a single number for easier comparison. # Using base 100 should be safe since SWIG internally uses BCD values # to encode its version number. required_swig_vernum=`expr $required_major \* 10000 \ \+ $required_minor \* 100 \+ $required_patch` available_swig_vernum=`expr $available_major \* 10000 \ \+ $available_minor \* 100 \+ $available_patch` if test $available_swig_vernum -lt $required_swig_vernum; then AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version.]) SWIG='' m4_ifval([$3],[$3],[]) else AC_MSG_CHECKING([for SWIG library]) SWIG_LIB=`$SWIG -swiglib | tr '\r\n' ' '` AC_MSG_RESULT([$SWIG_LIB]) m4_ifval([$2],[$2],[]) fi else AC_MSG_WARN([cannot determine SWIG version]) SWIG='' m4_ifval([$3],[$3],[]) fi fi AC_SUBST([SWIG_LIB]) ]) gensio-3.0.0/m4/ax_compare_version.m40000644000175000017500000001465313402532746013143 # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_compare_version.html # =========================================================================== # # SYNOPSIS # # AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) # # DESCRIPTION # # This macro compares two version strings. Due to the various number of # minor-version numbers that can exist, and the fact that string # comparisons are not compatible with numeric comparisons, this is not # necessarily trivial to do in a autoconf script. This macro makes doing # these comparisons easy. # # The six basic comparisons are available, as well as checking equality # limited to a certain number of minor-version levels. # # The operator OP determines what type of comparison to do, and can be one # of: # # eq - equal (test A == B) # ne - not equal (test A != B) # le - less than or equal (test A <= B) # ge - greater than or equal (test A >= B) # lt - less than (test A < B) # gt - greater than (test A > B) # # Additionally, the eq and ne operator can have a number after it to limit # the test to that number of minor versions. # # eq0 - equal up to the length of the shorter version # ne0 - not equal up to the length of the shorter version # eqN - equal up to N sub-version levels # neN - not equal up to N sub-version levels # # When the condition is true, shell commands ACTION-IF-TRUE are run, # otherwise shell commands ACTION-IF-FALSE are run. The environment # variable 'ax_compare_version' is always set to either 'true' or 'false' # as well. # # Examples: # # AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8]) # AX_COMPARE_VERSION([3.15],[lt],[3.15.8]) # # would both be true. # # AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8]) # AX_COMPARE_VERSION([3.15],[gt],[3.15.8]) # # would both be false. # # AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8]) # # would be true because it is only comparing two minor versions. # # AX_COMPARE_VERSION([3.15.7],[eq0],[3.15]) # # would be true because it is only comparing the lesser number of minor # versions of the two values. # # Note: The characters that separate the version numbers do not matter. An # empty string is the same as version 0. OP is evaluated by autoconf, not # configure, so must be a string, not a variable. # # The author would like to acknowledge Guido Draheim whose advice about # the m4_case and m4_ifvaln functions make this macro only include the # portions necessary to perform the specific comparison specified by the # OP argument in the final configure script. # # LICENSE # # Copyright (c) 2008 Tim Toolan # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 13 dnl ######################################################################### AC_DEFUN([AX_COMPARE_VERSION], [ AC_REQUIRE([AC_PROG_AWK]) # Used to indicate true or false condition ax_compare_version=false # Convert the two version strings to be compared into a format that # allows a simple string comparison. The end result is that a version # string of the form 1.12.5-r617 will be converted to the form # 0001001200050617. In other words, each number is zero padded to four # digits, and non digits are removed. AS_VAR_PUSHDEF([A],[ax_compare_version_A]) A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ -e 's/[[^0-9]]//g'` AS_VAR_PUSHDEF([B],[ax_compare_version_B]) B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ -e 's/[[^0-9]]//g'` dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary dnl # then the first line is used to determine if the condition is true. dnl # The sed right after the echo is to remove any indented white space. m4_case(m4_tolower($2), [lt],[ ax_compare_version=`echo "x$A x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"` ], [gt],[ ax_compare_version=`echo "x$A x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"` ], [le],[ ax_compare_version=`echo "x$A x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"` ], [ge],[ ax_compare_version=`echo "x$A x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"` ],[ dnl Split the operator from the subversion count if present. m4_bmatch(m4_substr($2,2), [0],[ # A count of zero means use the length of the shorter version. # Determine the number of characters in A and B. ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'` ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'` # Set A to no more than B's length and B to no more than A's length. A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"` B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"` ], [[0-9]+],[ # A count greater than zero means use only that many subversions A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` ], [.+],[ AC_WARNING( [invalid OP numeric parameter: $2]) ],[]) # Pad zeros at end of numbers to make same length. ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`" B="$B`echo $A | sed 's/./0/g'`" A="$ax_compare_version_tmp_A" # Check for equality or inequality as necessary. m4_case(m4_tolower(m4_substr($2,0,2)), [eq],[ test "x$A" = "x$B" && ax_compare_version=true ], [ne],[ test "x$A" != "x$B" && ax_compare_version=true ],[ AC_WARNING([invalid OP parameter: $2]) ]) ]) AS_VAR_POPDEF([A])dnl AS_VAR_POPDEF([B])dnl dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE. if test "$ax_compare_version" = "true" ; then m4_ifvaln([$4],[$4],[:])dnl m4_ifvaln([$5],[else $5])dnl fi ]) dnl AX_COMPARE_VERSION gensio-3.0.0/m4/ltoptions.m40000644000175000017500000003427514605013133011303 # Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2022 Free # Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --with-aix-soname flag, and support the `aix-soname=aix' # and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT # is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_WITH([aix-soname], [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) with_aix_soname=$lt_cv_with_aix_soname]) AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) gensio-3.0.0/m4/ax_pthread.m40000664000175000017500000005403414664224267011405 # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS # # AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro figures out how to build C programs using POSIX threads. It # sets the PTHREAD_LIBS output variable to the threads library and linker # flags, and the PTHREAD_CFLAGS output variable to any special C compiler # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # # Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is # needed for multi-threaded programs (defaults to the value of CC # respectively CXX otherwise). (This is necessary on e.g. AIX to use the # special cc_r/CC_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, # but also to link with them as well. For example, you might link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # # If you are only building threaded programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" # CXX="$PTHREAD_CXX" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant # has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to # that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with # PTHREAD_CFLAGS. # # ACTION-IF-FOUND is a list of shell commands to run if a threads library # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it # is not found. If ACTION-IF-FOUND is not specified, the default action # will define HAVE_PTHREAD. # # Please let the authors know if this macro fails on any platform, or if # you have any other suggestions or comments. This macro was based on work # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by # Alejandro Forero Cuervo to the autoconf macro repository. We are also # grateful for the helpful feedback of numerous users. # # Updated for Autoconf 2.68 by Daniel Richard G. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. # Copyright (c) 2019 Marc Stevens # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 31 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_PROG_SED]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on Tru64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then ax_pthread_save_CC="$CC" ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"]) CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) AC_MSG_RESULT([$ax_pthread_ok]) if test "x$ax_pthread_ok" = "xno"; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi CC="$ax_pthread_save_CC" CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items with a "," contain both # C compiler flags (before ",") and linker flags (after ","). Other items # starting with a "-" are C compiler flags, and remaining items are # library names, except for "none" which indicates that we try without # any flags at all, and "pthread-config" which is a program returning # the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 # (Note: HP C rejects this with "bad form for `-t' option") # -pthreads: Solaris/gcc (Note: HP C also rejects) # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads and # -D_REENTRANT too), HP C (must be checked before -lpthread, which # is present but should not be used directly; and before -mthreads, # because the compiler interprets this as "-mt" + "-hreads") # -mthreads: Mingw32/gcc, Lynx/gcc # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case $host_os in freebsd*) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) ax_pthread_flags="-kthread lthread $ax_pthread_flags" ;; hpux*) # From the cc(1) man page: "[-mt] Sets various -D flags to enable # multi-threading and also sets -lpthread." ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" ;; openedition*) # IBM z/OS requires a feature-test macro to be defined in order to # enable POSIX threads at all, so give the user a hint if this is # not set. (We don't define these ourselves, as they can affect # other portions of the system API in unpredictable ways.) AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], [ # if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) AX_PTHREAD_ZOS_MISSING # endif ], [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) ;; solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (N.B.: The stubs are missing # pthread_cleanup_push, or rather a function called by this macro, # so we could check for that, but who knows whether they'll stub # that too in a future libc.) So we'll check first for the # standard Solaris way of linking pthreads (-mt -lpthread). ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" ;; esac # Are we compiling with Clang? AC_CACHE_CHECK([whether $CC is Clang], [ax_cv_PTHREAD_CLANG], [ax_cv_PTHREAD_CLANG=no # Note that Autoconf sets GCC=yes for Clang as well as GCC if test "x$GCC" = "xyes"; then AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ # if defined(__clang__) && defined(__llvm__) AX_PTHREAD_CC_IS_CLANG # endif ], [ax_cv_PTHREAD_CLANG=yes]) fi ]) ax_pthread_clang="$ax_cv_PTHREAD_CLANG" # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) # Note that for GCC and Clang -pthread generally implies -lpthread, # except when -nostdlib is passed. # This is problematic using libtool to build C++ shared libraries with pthread: # [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 # [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 # [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 # To solve this, first try -pthread together with -lpthread for GCC AS_IF([test "x$GCC" = "xyes"], [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"]) # Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first AS_IF([test "x$ax_pthread_clang" = "xyes"], [ax_pthread_flags="-pthread,-lpthread -pthread"]) # The presence of a feature test macro requesting re-entrant function # definitions is, on some systems, a strong hint that pthreads support is # correctly enabled case $host_os in darwin* | hpux* | linux* | osf* | solaris*) ax_pthread_check_macro="_REENTRANT" ;; aix*) ax_pthread_check_macro="_THREAD_SAFE" ;; *) ax_pthread_check_macro="--" ;; esac AS_IF([test "x$ax_pthread_check_macro" = "x--"], [ax_pthread_check_cond=0], [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) if test "x$ax_pthread_ok" = "xno"; then for ax_pthread_try_flag in $ax_pthread_flags; do case $ax_pthread_try_flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; *,*) PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"]) ;; -*) AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) PTHREAD_CFLAGS="$ax_pthread_try_flag" ;; pthread-config) AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) PTHREAD_LIBS="-l$ax_pthread_try_flag" ;; esac ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_LINK_IFELSE([AC_LANG_PROGRAM([#include # if $ax_pthread_check_cond # error "$ax_pthread_check_macro must be defined" # endif static void *some_global = NULL; static void routine(void *a) { /* To avoid any unused-parameter or unused-but-set-parameter warning. */ some_global = a; } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], [ax_pthread_ok=yes], []) CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" AC_MSG_RESULT([$ax_pthread_ok]) AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Clang needs special handling, because older versions handle the -pthread # option in a rather... idiosyncratic way if test "x$ax_pthread_clang" = "xyes"; then # Clang takes -pthread; it has never supported any other flag # (Note 1: This will need to be revisited if a system that Clang # supports has POSIX threads in a separate library. This tends not # to be the way of modern systems, but it's conceivable.) # (Note 2: On some systems, notably Darwin, -pthread is not needed # to get POSIX threads support; the API is always present and # active. We could reasonably leave PTHREAD_CFLAGS empty. But # -pthread does define _REENTRANT, and while the Darwin headers # ignore this macro, third-party headers might not.) # However, older versions of Clang make a point of warning the user # that, in an invocation where only linking and no compilation is # taking place, the -pthread option has no effect ("argument unused # during compilation"). They expect -pthread to be passed in only # when source code is being compiled. # # Problem is, this is at odds with the way Automake and most other # C build frameworks function, which is that the same flags used in # compilation (CFLAGS) are also used in linking. Many systems # supported by AX_PTHREAD require exactly this for POSIX threads # support, and in fact it is often not straightforward to specify a # flag that is used only in the compilation phase and not in # linking. Such a scenario is extremely rare in practice. # # Even though use of the -pthread flag in linking would only print # a warning, this can be a nuisance for well-run software projects # that build with -Werror. So if the active version of Clang has # this misfeature, we search for an option to squash it. AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown # Create an alternate version of $ac_link that compiles and # links in two steps (.c -> .o, .o -> exe) instead of one # (.c -> exe), because the warning occurs only in the second # step ax_pthread_save_ac_link="$ac_link" ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"` ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" ax_pthread_save_CFLAGS="$CFLAGS" for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" ac_link="$ax_pthread_save_ac_link" AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], [ac_link="$ax_pthread_2step_ac_link" AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], [break]) ]) done ac_link="$ax_pthread_save_ac_link" CFLAGS="$ax_pthread_save_CFLAGS" AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" ]) case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in no | unknown) ;; *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; esac fi # $ax_pthread_clang = yes # Various other checks: if test "x$ax_pthread_ok" = "xyes"; then ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_CACHE_CHECK([for joinable pthread attribute], [ax_cv_PTHREAD_JOINABLE_ATTR], [ax_cv_PTHREAD_JOINABLE_ATTR=unknown for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [int attr = $ax_pthread_attr; return attr /* ; */])], [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], []) done ]) AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ test "x$ax_pthread_joinable_attr_defined" != "xyes"], [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$ax_cv_PTHREAD_JOINABLE_ATTR], [Define to necessary symbol if this constant uses a non-standard name on your system.]) ax_pthread_joinable_attr_defined=yes ]) AC_CACHE_CHECK([whether more special flags are required for pthreads], [ax_cv_PTHREAD_SPECIAL_FLAGS], [ax_cv_PTHREAD_SPECIAL_FLAGS=no case $host_os in solaris*) ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" ;; esac ]) AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ test "x$ax_pthread_special_flags_added" != "xyes"], [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" ax_pthread_special_flags_added=yes]) AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], [ax_cv_PTHREAD_PRIO_INHERIT], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT; return i;]])], [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ test "x$ax_pthread_prio_inherit_defined" != "xyes"], [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) ax_pthread_prio_inherit_defined=yes ]) CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" # More AIX lossage: compile with *_r variant if test "x$GCC" != "xyes"; then case $host_os in aix*) AS_CASE(["x/$CC"], [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], [#handle absolute path differently from PATH based program lookup AS_CASE(["x$CC"], [x/*], [ AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"]) AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])]) ], [ AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC]) AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])]) ] ) ]) ;; esac fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX" AC_SUBST([PTHREAD_LIBS]) AC_SUBST([PTHREAD_CFLAGS]) AC_SUBST([PTHREAD_CC]) AC_SUBST([PTHREAD_CXX]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test "x$ax_pthread_ok" = "xyes"; then ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) : else ax_pthread_ok=no $2 fi AC_LANG_POP ])dnl AX_PTHREAD gensio-3.0.0/README.rst0000664000175000017500000004062715054354042010163 =========================== gensio - General Stream I/O =========================== .. image:: https://www.bestpractices.dev/projects/9971/badge :target: https://www.bestpractices.dev/projects/9971 This is gensio (pronounced gen'-see-oh), a framework for giving a consistent view of various stream (and packet) I/O types. You create a gensio object (or a gensio), and you can use that gensio without having to know too much about what is going on underneath. You can stack gensio on top of another one to add protocol functionality. For instance, you can create a TCP gensio, stack SSL on top of that, and stack Telnet on top of that. It supports a number of network I/O and serial ports. It also supports sound interfaces. gensios that stack on other gensios are called filters. You can do the same thing with receiving ports. You can set up a gensio accepter to accept connections in a stack. So in our previous example, you can setup TCP to listen on a specific port and automatically stack SSL and Telnet on top when the connection comes in, and you are not informed until everything is ready. gensio works on Linux, BSDs, MacOS, and Windows. On Windows, it gives you a single-threaded capable (but also multi-thread capable) event-driven interface (with blocking interfaces available) to simplify programming with lots of I/Os. It goes a long way to making writing portable I/O driven code easy. A *very* important feature of gensio is that it makes establishing encrypted and authenticated connections much easier than without it. Beyond basic key management, it's really no harder than TCP or anything else. It offers extended flexibility for controlling the authentication process if needed. It's really easy to use. Note that the gensio(5) man page has more details on individual gensio types. For instructions on building this from source, see the "BUILDING" document. For info on how to use the library, see the "USING" document. gensio tools ============ A couple of tools are available that use gensios, both as an example and for trying things out. These are: gensiot A tool for making basic gensio connections. You can create any arbitrary gensio setup you like. See gensiot(1) for details. gtlsshd An sshd-like daemon that uses certauth, ssl, and SCTP or TCP gensios for making connections. It uses standard PAM authentication and uses ptys. See gtlsshd(8) for details. There is a item in FAQ.rst named "How to run gtlsshd on Windows", see that and the Building on Windows section in the BUILDING document for more details, as there are a few tricky things you have to handle. gtlssh An ssh-like program that can connect to gtlsshd. It can also be used with ser2net to make establishing encrypted and authenticated connections easier. See gtlssh(1) for details. gtlssh-keygen Used for handling keys for gtlssh and gtlsshd. See gtlssh-keygen(1) for details. gmdns Used to provide and query MDNS. See gmdns(1) for details. gsound Used to play or record sound. See gsound(1) for details. Available gensios ================= The following gensios are available in the library: sctp Normal SCTP communication. Streams and out of bound data are supported. End of message demarcation is not supported because it doesn't currently work on Linux. tcp Normal TCP communication. Out of bound data is supported. unix Unix stream domain socket. unixdgram Unix datagram domain socket. This is sort-of connection oriented. unixseq Unix seqpacket domain socket. Probably only works on Linux. udp Sort-of connection oriented UDP. stdio Access to either the calling program's stdio, or the ability to run a program and connect to its stdin, stdout, and stderr. NOTE: Do not use this for file I/O. Use the file gensio. file Used for accessing files. Allows both input and output file, and streams the data to/from the files. No accepter available. pty Run a program in a PTY and use the gensio to communicate with its tty. No accepter available. serialdev Connect to a device. You can use "sdev" as shorthand for "serialdev". It can hook to termios type devices, like ptys and /dev/tty, more than just serial ports. No accepter available. dev Connects to devices (like serialdev does) but does not do any serial port processing. It also has a write-only option for talking to printer ports or other write-only devices. It also has a rdonly option for talking to read-only devices. No accepter available. ipmisol Connect to a remote over IPMI SOL. Full serial port capabilities are available. No accepter available, unfortunately. dummy An accepter that doesn't do anything except look like an accepter to the user. Useful in some situations where an accepter is expected but you don't need to do anything. echo A gensio that echos everything that is sent to it. Useful for testing. No accepter available. telnet A filter gensio that implements the telnet protocol. It can do full serial support with RFC2217. ssl Implement SSL/TLS as a gensio filter. It supports client authentication, too. certauth A user authentication protocol implemented as a gensio filter. mux A channel multiplexer. You can create channels on top of it using open_channel(). Channels work as normal gensio, so you can have a number of gensios running on top of a single gensio. It also has end-of-message demarcation and obviously full flow-control capability individually on each channel. If you just need a gensio with end-of-message demarcation, you can use this as without creating channels. msgdelim Converts an unreliable stream interface into an unreliable packet interface. This is primarily so a reliable packet interface like relpkt can run over a serial port. It does not support streaming of data, so it's not very useful by itself. relpkt Converts an unreliable packet interface to a reliable packet interface (that also supports streaming). Made for running over msgdelim. It will run over UDP, but it's not ideal for that because it doesn't do all the internet-friendly flow control and such that SCTP and TCP do. trace A transparent gensio that allows the data read and/or written to be sent to a file, either as raw data or as human-readable hex data. It can also be used to block data flowing in one or both directions. perf A gensio that can send/receive data on top of a stack of gensios and measure the throughput on the channel. The received data from perf is information about the channel throughput. conacc A gensio accepter that takes a gensio stack string as a parameter. This lets you use a gensio as an accepter. When conacc is started, it opens the gensio, and when the gensio opens it reports a new child for the accepter. When the child closes it attempts to open the child again and go through the process again (unless accepts have been disabled on conacc). Why would you want to use this? Say in ser2net you wanted to connect one serial port to another. You could have a connection like: .. code-block:: yaml connection: &con0 accepter: conacc,serialdev,/dev/ttyS1,115200 connector: serialdev,/dev/ttyS2,115200 And it would connect /dev/ttyS1 to /dev/ttyS2. Without conacc, you could not use serialdev as an accepter. It would also let you use gtlsshd on a serial port if you wanted encrypted authenticated logins over a serial port. If you ran gtlsshd with the following: .. code-block:: bash gtlsshd --notcp --oneshot --nodaemon --other_acc 'conacc,relpkt(mode=server),msgdelim,serialdev,/dev/ttyUSB1,115200n81' You could connect with: .. code-block:: bash gtlssh --transport 'relpkt,msgdelim,serialdev,/dev/ttyUSB2,115200n81' USB2 This creates a reliable packet transport over a serial port. The mode=server is required to make relpkt run as the server, since it would normally run as a client since it is not being started as an accepter. The ssl gensio (which runs over the transport) requires reliable communication, so it won't run directly over a serial port. xlt This gensio allows character translations to be done on data flowing through this filter. It's primarily to convert carraige returns and line feeds. mdns This gensio uses mDNS to lookup a service (protocol type, network type, port, address) and then connect to that service. If you have a program like ser2net that advertise mDNS service, you don't have to worry about finding port numbers and such, it's all handled for you. keepopen This gensio presents an always open connection to the upper layer and keeps the lower layer connection open. If it closes, it re-opens it. script This gensio executes an external program with the external program's stdio connected to the child of this gensio. Once the external program terminates, this gensio will report that it is open and pass all the data through. This can be used to run scripts to set things up on a connection before hooking to the parent gensio. sound A gensio that provides access to sound devices and files. It's a little complicated, read the docs in gensio.5 afskmdm Yes, it looks like a jumble of letters. A filter gensio that sits on top of the sound gensio and does an Audio Frequency Shift Keying modem, like is used on AX.25 amateur radio. kiss An amateur radio protocol for talking to TNCs. This is used by AX25 in many cases. ax25 An amateur radio protocol for packet radio. To fully use this you would need to write code, since it uses channels and oob data for unnumbered information, but you can do basic things with just gensiot if all you need is one communication channel. For instance, if you wanted to chat with someone over the radio, and the kiss port is on 8001 on both machines, on the accepting machine you can run: .. code-block:: bash gensiot -i 'stdio(self)' -a \ 'ax25(laddr=AE5KM-1),kiss,conacc,tcp,localhost,8001' which will hook to the TNC and wait for a connection on address AE5KM-1. Then you could run: .. code-block:: bash gensiot -i 'stdio(self)' \ 'ax25(laddr=AE5KM-2,addr="0,AE5KM-1,AE5KM-2"),kiss,tcp,localhost,8001' on the other machine. This will connect to the other machine over TNC 0 with the given address. Then anything you type in one will appear on the other, a line at a time. Type "Ctrl-D" to exit. The 'stdio(self)' part turns off raw mode, so it's a line at a time and you get local echo. Otherwise every character you types would send a packet and you couldn't see what you were typing. To hook to the N5COR-11 AX.25 BBS system, you would do: .. code-block:: bash gensiot -i 'xlt(nlcr),stdio(self)' \ 'ax25(laddr=AE5KM-2,addr="0,N5COR-11,AE5KM-2"),kiss,tcp,localhost,8001' Most BBS systems use CR, not NL, for the new line, so the xlt gensio is used to translate incoming these characters. Of course, this being gensio, you can put any workable gensio underneath ax25 that you would like. So if you want to play around or test without a radio, you could do ax25 over UDP multicast. Here's the accepter side: .. code-block:: bash gensiot -i 'stdio(self)' -a \ 'ax25(laddr=AE5KM-1),conacc,'\ 'udp(mcast="ipv4,224.0.0.20",laddr="ipv4,1234",nocon),'\ 'ipv4,224.0.0.20,1234' and here's the connector side: .. code-block:: bash gensiot -i 'stdio(self)' \ 'ax25(laddr=AE5KM-2,addr="0,AE5KM-1,AE5KM-2"),'\ 'udp(mcast="ipv4,224.0.0.20",laddr="ipv4,1234",nocon),'\ 'ipv4,224.0.0.20,1234' kiss is not required because UDP is already a packet-oriented media. Or you can use the greflector program to create a simulated radio situation. On the machine "radiopi2", run: .. code-block:: bash greflector kiss,tcp,1234 which will create a program that will reflect all received input to all other connections. Then on the accepter side: .. code-block:: bash gensiot -i 'stdio(self)' -a \ 'ax25(laddr=AE5KM-1),kiss,conacc,tcp,radiopi2,1234' and the connecting side: .. code-block:: bash gensiot -i 'stdio(self)' \ 'ax25(laddr=AE5KM-2,addr="0,AE5KM-1,AE5KM-2"),kiss,tcp,radiopi2,1234' The test code uses the reflector for some testing, since it's so convenient to use. ratelimit Limit the data throughput for a gensio stack. cm108gpio Allow a GPIO on a CMedia CM108 or equivalent sound device to be controlled. Used with afskmdm for keying a transmitter. These are all documented in detail in gensio(5). Unless otherwise stated, these all are available as accepters or connecting gensios. Creating Your Own Gensios ========================= You can create your own gensios and register them with the library and stack them along with the other gensios. The easiest way to do this is to steal code from a gensio that does kind of what you want, then modify it to create your own gensio. There is, unfortunately, no good documentation on how to do this. The include file include/gensio/gensio_class.h has the interface between the main gensio library and the gensio. The gensio calls all come through a single function with numbers to identify the function being requested. You have to map all these to the actual operations. This is somewhat painful, but it makes forwards and backwards compatibility much easier. Creating your own gensio this way is fairly complex. The state machine for something like this can be surprisingly complex. Cleanup is the hardest part. You have to make sure you are out of all callbacks and no timers might be called back in a race condition at shutdown. Only the simplest gensios (echo, dummy), strange gensios (conadd, keepopen, stdio), and gensios that have channels (mux, ax25) directly implement the interface. Everything else uses include/gensio/gensio_base.h. gensio_base provides the basic state machine for a gensio. It has a filter portion (which is optional) and a low-level (ll) portion, which is not. The filter interface has data run through it for the processing. This is used for things like ssl, certauth, ratelimit, etc. Filter gensios would use this. These all use gensio_ll_gensio (for stacking a gensio on top of another gensio) for the ll. Terminal gensios each have their own ll and generally no filter. For lls based on a file descriptor (fd), gensio_ll_fd is used. There is also an ll for IPMI serial-over-lan (ipmisol) and for sound. Most of the terminal gensios (tcp, udp, sctp, serial port, pty) use the fd ll, obviously. Once you have a gensio, you can compile it as a module and stick it in $(moduleinstalldir)/. Then the gensio will just pick it up and use it. You can also link it in with your application and do the init function from your application. mDNS support ============ The mdns gensio has already been discussed, but the gensio library provides an easy to use mDNS interface. The include file for it is in gensio_mdns.h, and you can use the gensio_mdns(3) man page to get more information on it. To make an mdns connection using gensiot, say you have ser2net set up with mdns enabled like: .. code-block:: yaml connection: &my-port accepter: telnet(rfc2217),tcp,3001 connector: serialdev,/dev/ttyUSB1,115200N81 options: mdns: true then you can connection to it with gensiot: .. code-block:: bash gensiot 'mdns,my-port' gensiot will find the server, port, and whether telnet and rfc2217 are enabled and make the connection. In addition, there is an gmdns tool that lets you do queries and advertising, and gtlssh can do mDNS queries to find services. If you have secure authenticated logins for ser2net, and you enable mdns on ser2net, like: .. code-block:: yaml connection: &access-console accepter: telnet(rfc2217),mux,certauth(),ssl,tcp,3001 connector: serialdev,/dev/ttyUSBaccess,115200N81 options: mdns: true it makes the setup very convenient, as you can just do: .. code-block:: bash gtlssh -m access-console That's right, you can just directly use the connection name, no need to know the host, whether telnet or rfc2217 is enabled, or what the port is. You still have to set up the keys and such on the ser2net server, of course, per those instructions. gensio-3.0.0/lib/0000775000175000017500000000000015061121734007307 5gensio-3.0.0/lib/gensio_dummy.c0000664000175000017500000001423314664224267012112 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* This code creates a dummy gensio accepter that doesn't do anything. */ #include "config.h" #include #include #include #include struct dummyna_data; enum dummyna_state { DUMMY_DISABLED, DUMMY_ENABLED, DUMMY_IN_SHUTDOWN }; struct dummyna_data { struct gensio_os_funcs *o; struct gensio_lock *lock; struct gensio_accepter *acc; enum dummyna_state state; bool deferred_pending; struct gensio_runner *deferred_runner; gensio_acc_done shutdown_done; void *shutdown_data; gensio_acc_done enabled_done; void *enabled_data; unsigned int refcount; }; static void dummyna_lock(struct dummyna_data *nadata) { nadata->o->lock(nadata->lock); } static void dummyna_unlock(struct dummyna_data *nadata) { nadata->o->unlock(nadata->lock); } static void dummyna_finish_free(struct dummyna_data *nadata) { struct gensio_os_funcs *o = nadata->o; gensio_acc_data_free(nadata->acc); if (nadata->deferred_runner) o->free_runner(nadata->deferred_runner); if (nadata->lock) o->free_lock(nadata->lock); o->free(o, nadata); } void dummyna_ref(struct dummyna_data *nadata) { assert(nadata->refcount > 0); nadata->refcount++; } void dummyna_deref_and_unlock(struct dummyna_data *nadata) { assert(nadata->refcount > 0); nadata->refcount--; if (nadata->refcount == 0) { dummyna_unlock(nadata); dummyna_finish_free(nadata); } else { dummyna_unlock(nadata); } } static int dummyna_startup(struct gensio_accepter *accepter) { struct dummyna_data *nadata = gensio_acc_get_gensio_data(accepter); int rv = 0; dummyna_lock(nadata); if (nadata->state != DUMMY_DISABLED) rv = GE_INUSE; nadata->state = DUMMY_ENABLED; dummyna_unlock(nadata); return rv; } static void dummyna_do_deferred(struct gensio_runner *runner, void *cb_data) { struct dummyna_data *nadata = cb_data; dummyna_lock(nadata); nadata->deferred_pending = false; if (nadata->enabled_done) { gensio_acc_done enabled_done = nadata->enabled_done;; void *enabled_data = nadata->enabled_data;; nadata->enabled_done = NULL; dummyna_unlock(nadata); enabled_done(nadata->acc, enabled_data); dummyna_lock(nadata); } if (nadata->state == DUMMY_IN_SHUTDOWN) { gensio_acc_done shutdown_done = nadata->shutdown_done; void *shutdown_data = nadata->shutdown_data; nadata->state = DUMMY_DISABLED; if (shutdown_done) { dummyna_unlock(nadata); shutdown_done(nadata->acc, shutdown_data); dummyna_lock(nadata); } } dummyna_deref_and_unlock(nadata); } void dummyna_deferred_op(struct dummyna_data *nadata) { if (!nadata->deferred_pending) { dummyna_ref(nadata); nadata->o->run(nadata->deferred_runner); nadata->deferred_pending = true; } } static int dummyna_shutdown(struct gensio_accepter *accepter, gensio_acc_done shutdown_done, void *shutdown_data) { struct dummyna_data *nadata = gensio_acc_get_gensio_data(accepter); int rv = 0; dummyna_lock(nadata); if (nadata->state != DUMMY_ENABLED) { rv = GE_INUSE; } else { nadata->state = DUMMY_IN_SHUTDOWN; /* Run the shutdown response in a runner to avoid deadlocks. */ nadata->shutdown_done = shutdown_done; nadata->shutdown_data = shutdown_data; dummyna_deferred_op(nadata); } dummyna_unlock(nadata); return rv; } static int dummyna_set_accept_callback_enable(struct gensio_accepter *accepter, bool enabled, gensio_acc_done done, void *done_data) { struct dummyna_data *nadata = gensio_acc_get_gensio_data(accepter); int rv = 0; dummyna_lock(nadata); if (nadata->enabled_done) { rv = GE_INUSE; } else if (done) { /* Run the response in a runner to avoid deadlocks. */ nadata->enabled_done = done; nadata->enabled_data = done_data; dummyna_deferred_op(nadata); } dummyna_unlock(nadata); return rv; } static void dummyna_free(struct gensio_accepter *accepter) { struct dummyna_data *nadata = gensio_acc_get_gensio_data(accepter); dummyna_lock(nadata); dummyna_deref_and_unlock(nadata); } static int gensio_acc_dummy_func(struct gensio_accepter *acc, int func, int val, const char *addr, void *done, void *data, const void *data2, void *ret) { switch (func) { case GENSIO_ACC_FUNC_STARTUP: return dummyna_startup(acc); case GENSIO_ACC_FUNC_SHUTDOWN: return dummyna_shutdown(acc, done, data); case GENSIO_ACC_FUNC_SET_ACCEPT_CALLBACK: return dummyna_set_accept_callback_enable(acc, val, done, data); case GENSIO_ACC_FUNC_FREE: dummyna_free(acc); return 0; default: return GE_NOTSUP; } } static int dummy_gensio_accepter_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { struct dummyna_data *nadata; nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) return GE_NOMEM; nadata->o = o; nadata->refcount = 1; nadata->lock = o->alloc_lock(o); if (!nadata->lock) { dummyna_finish_free(nadata); return GE_NOMEM; } nadata->deferred_runner = o->alloc_runner(o, dummyna_do_deferred, nadata); if (!nadata->deferred_runner) { dummyna_finish_free(nadata); return GE_NOMEM; } nadata->acc = gensio_acc_data_alloc(o, cb, user_data, gensio_acc_dummy_func, NULL, "dummy", nadata); if (!nadata->acc) { dummyna_finish_free(nadata); return GE_NOMEM; } *accepter = nadata->acc; return 0; } static int str_to_dummy_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { return dummy_gensio_accepter_alloc(NULL, args, o, cb, user_data, acc); } int gensio_init_dummy(struct gensio_os_funcs *o) { int rv; rv = register_gensio_accepter(o, "dummy", str_to_dummy_gensio_accepter, dummy_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/gensio_file.c0000664000175000017500000004274314664224267011705 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* This code is for a gensio that reads/writes files. */ #include "config.h" #include #include #include #include #include #include #include #include #if !USE_FILE_STDIO #include #include #include #include #include #include #endif enum filen_state { FILEN_CLOSED, FILEN_IN_OPEN, FILEN_OPEN, FILEN_IN_OPEN_CLOSE, FILEN_IN_CLOSE, }; struct filen_data { struct gensio_os_funcs *o; struct gensio_lock *lock; unsigned int refcount; enum filen_state state; struct gensio *io; gensiods max_read_size; unsigned char *read_data; gensiods data_pending_len; int read_err; char *infile; char *outfile; bool create; bool append; bool trunc; bool binary; #if USE_FILE_STDIO int mode; FILE *inf; FILE *outf; #else mode_t mode; int inf; int outf; #endif bool read_enabled; bool xmit_enabled; bool read_close; gensio_done_err open_done; void *open_data; gensio_done close_done; void *close_data; /* * Used to run read callbacks from the selector to avoid running * it directly from user calls. */ bool deferred_op_pending; struct gensio_runner *deferred_op_runner; }; static void filen_start_deferred_op(struct filen_data *ndata); #if USE_FILE_STDIO #define f_ready(f) ((f) != NULL) #define f_set_not_ready(f) f = NULL typedef int mode_type; static int f_writev(struct gensio_os_funcs *o, FILE *f, const struct gensio_sg *sg, gensiods sglen, gensiods *written) { gensiods i, total = 0; size_t rv; for (i = 0; i < sglen; i++) { rv = fwrite(sg[i].buf, 1, sg[i].buflen, f); if (rv == 0) { if (total == 0) return GE_REMCLOSE; break; } total += rv; } *written = total; return 0; } static int f_read(struct gensio_os_funcs *o, FILE *f, void *buf, gensiods len, gensiods *nrread) { size_t rv; rv = fread(buf, 1, len, f); if (rv == 0) { rv = GE_REMCLOSE; } else { *nrread = rv; rv = 0; } return rv; } #define F_O_RDONLY (1 << 0) #define F_O_WRONLY (1 << 1) #define F_O_CREAT (1 << 2) #define F_O_APPEND (1 << 3) #define F_O_TRUNC (1 << 4) #define F_O_BINARY (1 << 5) static int f_open(struct gensio_os_funcs *o, const char *fn, int flags, int mode, FILE **rf) { char fmode[10]; FILE *f; bool seekstart = false; bool seekend = false; bool trunc = false; if (flags & F_O_RDONLY) { strcpy(fmode, "r"); } else if (flags & F_O_WRONLY) { if (flags & F_O_CREAT) { if (flags & F_O_TRUNC) { strcpy(fmode, "w"); } else if (flags & F_O_APPEND) { strcpy(fmode, "a"); } else { strcpy(fmode, "a"); seekstart = true; } } else { strcpy(fmode, "r+"); if (flags & F_O_TRUNC) trunc = true; if (flags & F_O_APPEND) seekend = true; } } else { return GE_INVAL; } if (flags & F_O_BINARY) strcat(fmode, "b"); f = fopen(fn, fmode); if (!f) return GE_NOTFOUND; if (trunc) { /* * Truncating an existing file is a wierd case here. There is * no way to do that that I can find with standard stream * files. So if we open the file with "r+" and it works, that * means the file exists and then we can open it with "w" to * truncate it. */ fclose(f); f = fopen(fn, "w"); if (!f) return GE_NOTFOUND; } if (seekstart) fseek(f, 0, SEEK_SET); if (seekend) fseek(f, 0, SEEK_END); *rf = f; return 0; } #define f_close(f) fclose(f) #else #define F_O_RDONLY O_RDONLY #define F_O_WRONLY O_WRONLY #define F_O_CREAT O_CREAT #define F_O_APPEND O_APPEND #define F_O_TRUNC O_TRUNC #define F_O_BINARY 0 /* Ignored for this. */ typedef mode_t mode_type; #define f_ready(f) ((f) != -1) #define f_set_not_ready(f) f = -1 static int f_writev(struct gensio_os_funcs *o, int fd, const struct gensio_sg *sg, gensiods sglen, gensiods *written) { int rv; rv = writev(fd, (const struct iovec *) sg, sglen); if (rv < 0) { rv = gensio_os_err_to_err(o, errno); } else if (rv == 0) { rv = GE_REMCLOSE; } else { *written = rv; rv = 0; } return rv; } static int f_read(struct gensio_os_funcs *o, int fd, void *buf, gensiods len, gensiods *nrread) { int rv; rv = read(fd, buf, len); if (rv < 0) { rv = gensio_os_err_to_err(o, errno); } else if (rv == 0) { rv = GE_REMCLOSE; } else { *nrread = rv; rv = 0; } return rv; } static int f_open(struct gensio_os_funcs *o, const char *fn, int flags, int mode, int *rfd) { int fd; int err = 0; fd = open(fn, flags, mode); if (fd == -1) err = gensio_os_err_to_err(o, errno); else *rfd = fd; return err; } #define f_close(f) close(f) #endif static void filen_finish_free(struct filen_data *ndata) { struct gensio_os_funcs *o = ndata->o; if (ndata->io) gensio_data_free(ndata->io); if (ndata->infile) o->free(ndata->o, ndata->infile); if (ndata->outfile) o->free(ndata->o, ndata->outfile); if (ndata->read_data) o->free(o, ndata->read_data); if (ndata->deferred_op_runner) o->free_runner(ndata->deferred_op_runner); if (ndata->lock) o->free_lock(ndata->lock); o->free(o, ndata); } static void filen_lock(struct filen_data *ndata) { ndata->o->lock(ndata->lock); } static void filen_unlock(struct filen_data *ndata) { ndata->o->unlock(ndata->lock); } static void filen_ref(struct filen_data *ndata) { assert(ndata->refcount > 0); ndata->refcount++; } static void filen_unlock_and_deref(struct filen_data *ndata) { assert(ndata->refcount > 0); if (ndata->refcount == 1) { filen_unlock(ndata); filen_finish_free(ndata); } else { ndata->refcount--; filen_unlock(ndata); } } static int filen_write(struct gensio *io, gensiods *count, const struct gensio_sg *sg, gensiods sglen) { struct filen_data *ndata = gensio_get_gensio_data(io); gensiods total_write = 0, i; gensiods wcount = 0; int err = 0; filen_lock(ndata); if (ndata->state != FILEN_OPEN) { err = GE_NOTREADY; } else if (!f_ready(ndata->outf)) { /* Just drop the data. */ for (total_write = 0, i = 0; i < sglen; i++) total_write += sg->buflen; } else { err = f_writev(ndata->o, ndata->outf, sg, sglen, &wcount); if (!err) total_write = wcount; } filen_unlock(ndata); if (count) *count = total_write; return err; } static void filen_deferred_op(struct gensio_runner *runner, void *cb_data) { struct filen_data *ndata = cb_data; int err = 0; filen_lock(ndata); ndata->deferred_op_pending = false; if (ndata->state == FILEN_IN_OPEN || ndata->state == FILEN_IN_OPEN_CLOSE) { if (ndata->state == FILEN_IN_OPEN_CLOSE) { ndata->state = FILEN_IN_CLOSE; err = GE_LOCALCLOSED; } else { ndata->state = FILEN_OPEN; } if (ndata->open_done) { filen_unlock(ndata); ndata->open_done(ndata->io, err, ndata->open_data); filen_lock(ndata); } } while (ndata->state == FILEN_OPEN && (f_ready(ndata->inf) || ndata->read_err) && ndata->read_enabled) { gensiods count = 0; if (ndata->data_pending_len == 0 && !ndata->read_err) { err = f_read(ndata->o, ndata->inf, ndata->read_data, ndata->max_read_size, &count); if (err) { ndata->read_enabled = false; ndata->read_err = err; } else { ndata->data_pending_len = count; } } count = ndata->data_pending_len; if (!ndata->read_close && ndata->read_err == GE_REMCLOSE) { /* Just don't report anything at the end of data. */ ndata->read_enabled = false; } else { filen_unlock(ndata); err = gensio_cb(ndata->io, GENSIO_EVENT_READ, ndata->read_err, ndata->read_data, &count, NULL); filen_lock(ndata); if (err) { ndata->read_enabled = false; ndata->read_err = err; break; } } if (count > 0) { if (count >= ndata->data_pending_len) { ndata->data_pending_len = 0; } else { memcpy(ndata->read_data, ndata->read_data + count, ndata->data_pending_len - count); ndata->data_pending_len -= count; } } } while (ndata->state == FILEN_OPEN && ndata->xmit_enabled) { filen_unlock(ndata); err = gensio_cb(ndata->io, GENSIO_EVENT_WRITE_READY, 0, NULL, NULL, NULL); filen_lock(ndata); if (err) { ndata->read_enabled = false; ndata->read_err = err; break; } } if (ndata->state == FILEN_IN_CLOSE) { ndata->state = FILEN_CLOSED; if (ndata->close_done) { filen_unlock(ndata); ndata->close_done(ndata->io, ndata->close_data); filen_lock(ndata); } } filen_unlock_and_deref(ndata); } static void filen_start_deferred_op(struct filen_data *ndata) { if (!ndata->deferred_op_pending) { /* Call the read from the selector to avoid lock nesting issues. */ ndata->deferred_op_pending = true; ndata->o->run(ndata->deferred_op_runner); filen_ref(ndata); } } static void filen_set_read_callback_enable(struct gensio *io, bool enabled) { struct filen_data *ndata = gensio_get_gensio_data(io); filen_lock(ndata); if (ndata->read_enabled != enabled) { ndata->read_enabled = enabled; if (enabled && ndata->state == FILEN_OPEN && f_ready(ndata->inf)) filen_start_deferred_op(ndata); } filen_unlock(ndata); } static void filen_set_write_callback_enable(struct gensio *io, bool enabled) { struct filen_data *ndata = gensio_get_gensio_data(io); filen_lock(ndata); if (ndata->xmit_enabled != enabled) { ndata->xmit_enabled = enabled; if (enabled && ndata->state == FILEN_OPEN) filen_start_deferred_op(ndata); } filen_unlock(ndata); } static int filen_open(struct gensio *io, gensio_done_err open_done, void *open_data) { struct filen_data *ndata = gensio_get_gensio_data(io); int err = 0; filen_lock(ndata); if (ndata->state != FILEN_CLOSED) { err = GE_NOTREADY; goto out_unlock; } if (ndata->infile) { err = f_open(ndata->o, ndata->infile, F_O_RDONLY, 0, &ndata->inf); if (err) goto out_unlock; } if (ndata->outfile) { int flags = F_O_WRONLY; if (ndata->create) flags |= F_O_CREAT; if (ndata->append) flags |= F_O_APPEND; if (ndata->trunc) flags |= F_O_TRUNC; if (ndata->binary) flags |= F_O_BINARY; err = f_open(ndata->o, ndata->outfile, flags, ndata->mode, &ndata->outf); if (err) goto out_unlock; } ndata->state = FILEN_IN_OPEN; ndata->open_done = open_done; ndata->open_data = open_data; filen_start_deferred_op(ndata); out_unlock: filen_unlock(ndata); return err; } static int filen_close(struct gensio *io, gensio_done close_done, void *close_data) { struct filen_data *ndata = gensio_get_gensio_data(io); int err = 0; filen_lock(ndata); if (ndata->state != FILEN_OPEN && ndata->state != FILEN_IN_OPEN) { err = GE_NOTREADY; goto out_unlock; } if (f_ready(ndata->inf)) { f_close(ndata->inf); f_set_not_ready(ndata->inf); } if (f_ready(ndata->outf)) { f_close(ndata->outf); f_set_not_ready(ndata->outf); } if (ndata->state == FILEN_IN_OPEN) ndata->state = FILEN_IN_OPEN_CLOSE; else ndata->state = FILEN_IN_CLOSE; ndata->close_done = close_done; ndata->close_data = close_data; filen_start_deferred_op(ndata); out_unlock: filen_unlock(ndata); return err; } static void filen_free(struct gensio *io) { struct filen_data *ndata = gensio_get_gensio_data(io); filen_lock(ndata); assert(ndata->refcount > 0); if (ndata->refcount == 1) ndata->state = FILEN_CLOSED; filen_unlock_and_deref(ndata); } static int filen_disable(struct gensio *io) { struct filen_data *ndata = gensio_get_gensio_data(io); filen_lock(ndata); ndata->state = FILEN_CLOSED; filen_unlock(ndata); return 0; } static int filen_control(struct gensio *io, bool get, int op, char *data, gensiods *datalen) { struct filen_data *ndata = gensio_get_gensio_data(io); if (op != GENSIO_CONTROL_RADDR) return GE_NOTSUP; if (!get) return GE_NOTSUP; if (strtoul(data, NULL, 0) > 0) return GE_NOTFOUND; *datalen = snprintf(data, *datalen, "file(%s%s%s%s%s)", ndata->infile ? "infile=" : "", ndata->infile ? ndata->infile : "", (ndata->infile && ndata->outfile) ? "," : "", ndata->outfile ? "outfile=" : "", ndata->outfile ? ndata->outfile : ""); return 0; } static int gensio_file_func(struct gensio *io, int func, gensiods *count, const void *cbuf, gensiods buflen, void *buf, const char *const *auxdata) { switch (func) { case GENSIO_FUNC_WRITE_SG: return filen_write(io, count, cbuf, buflen); case GENSIO_FUNC_OPEN: return filen_open(io, (void *) cbuf, buf); case GENSIO_FUNC_CLOSE: return filen_close(io, (void *) cbuf, buf); case GENSIO_FUNC_FREE: filen_free(io); return 0; case GENSIO_FUNC_SET_READ_CALLBACK: filen_set_read_callback_enable(io, buflen); return 0; case GENSIO_FUNC_SET_WRITE_CALLBACK: filen_set_write_callback_enable(io, buflen); return 0; case GENSIO_FUNC_DISABLE: return filen_disable(io); case GENSIO_FUNC_CONTROL: return filen_control(io, *((bool *) cbuf), buflen, buf, count); default: return GE_NOTSUP; } } struct file_ndata_data { gensiods max_read_size; const char *infile; const char *outfile; bool create; bool append; bool trunc; bool binary; bool read_close; mode_type mode; }; static int file_ndata_setup(struct gensio_os_funcs *o, struct file_ndata_data *data, struct filen_data **new_ndata) { struct filen_data *ndata; ndata = o->zalloc(o, sizeof(*ndata)); if (!ndata) return GE_NOMEM; ndata->o = o; ndata->refcount = 1; ndata->create = data->create; ndata->append = data->append; ndata->trunc = data->trunc; ndata->binary = data->binary; ndata->mode = data->mode; ndata->read_close = data->read_close; if (data->infile) { ndata->infile = gensio_strdup(o, data->infile); if (!ndata->infile) goto out_nomem; } if (data->outfile) { ndata->outfile = gensio_strdup(o, data->outfile); if (!ndata->outfile) goto out_nomem; } f_set_not_ready(ndata->inf); f_set_not_ready(ndata->outf); ndata->max_read_size = data->max_read_size; ndata->read_data = o->zalloc(o, data->max_read_size); if (!ndata->read_data) goto out_nomem; ndata->deferred_op_runner = o->alloc_runner(o, filen_deferred_op, ndata); if (!ndata->deferred_op_runner) goto out_nomem; ndata->lock = o->alloc_lock(o); if (!ndata->lock) goto out_nomem; *new_ndata = ndata; return 0; out_nomem: filen_finish_free(ndata); return GE_NOMEM; } static int process_file_args(struct gensio_pparm_info *p, const char * const args[], struct file_ndata_data *data) { #if !USE_FILE_STDIO unsigned int mode; #endif unsigned int umode = 6, gmode = 6, omode = 6, i; memset(data, 0, sizeof(*data)); data->read_close = true; data->max_read_size = GENSIO_DEFAULT_BUF_SIZE; for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(p, args[i], "readbuf", &data->max_read_size) > 0) continue; if (gensio_pparm_value(p, args[i], "infile", &data->infile) > 0) continue; if (gensio_pparm_value(p, args[i], "outfile", &data->outfile) > 0) continue; if (gensio_pparm_bool(p, args[i], "create", &data->create) > 0) continue; if (gensio_pparm_bool(p, args[i], "append", &data->append) > 0) continue; if (gensio_pparm_bool(p, args[i], "trunc", &data->trunc) > 0) continue; if (gensio_pparm_bool(p, args[i], "binary", &data->binary) > 0) continue; #if !USE_FILE_STDIO if (gensio_pparm_mode(p, args[i], "umode", &umode) > 0) continue; if (gensio_pparm_mode(p, args[i], "gmode", &gmode) > 0) continue; if (gensio_pparm_mode(p, args[i], "omode", &omode) > 0) continue; if (gensio_pparm_perm(p, args[i], "perm", &mode) > 0) { umode = mode >> 6 & 7; gmode = mode >> 3 & 7; omode = mode & 7; continue; } #endif if (gensio_pparm_bool(p, args[i], "read_close", &data->read_close) > 0) continue; gensio_pparm_unknown_parm(p, args[i]); return GE_INVAL; } data->mode = umode << 6 | gmode << 3 | omode; return 0; } static int file_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct filen_data *ndata = NULL; struct file_ndata_data data; GENSIO_DECLARE_PPGENSIO(p, o, cb, "file", user_data); err = process_file_args(&p, args, &data); if (err) return err; err = file_ndata_setup(o, &data, &ndata); if (err) return err; ndata->io = gensio_data_alloc(ndata->o, cb, user_data, gensio_file_func, NULL, "file", ndata); if (!ndata->io) goto out_nomem; gensio_set_is_client(ndata->io, true); gensio_set_is_reliable(ndata->io, true); *new_gensio = ndata->io; return 0; out_nomem: filen_finish_free(ndata); return GE_NOMEM; } static int str_to_file_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { return file_gensio_alloc(NULL, args, o, cb, user_data, new_gensio); } int gensio_init_file(struct gensio_os_funcs *o) { int rv; rv = register_gensio(o, "file", str_to_file_gensio, file_gensio_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/gensio_relpkt.c0000664000175000017500000011227614747451760012270 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018-2025 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include #if 0 #define DEBUG_MSG 1 #define ENABLE_PRBUF 1 #endif #if 0 #define DROP_NR 8 unsigned int curr_drop; #endif #include "utils.h" enum relpkt_msgs { /* * Request a connection be established. * * +----------------+----------------+----------------+ * | 1 |reserv|A| version | recv window | * +----------------+----------------+----------------+ * +----------------+----------------+ * | pktlen msb | pktlen lsb | * +----------------+----------------+ * A - response bit, 1 if a response, 0 if not. */ RELPKT_MSG_INIT = 1, /* * Send some data. If there is no data after the header, msg seq * is ignore and this is only an ack. * * +----------------+----------------+----------------+ * | 2 |reserv|A| next expected | msg seq | * +----------------+----------------+----------------+ * A - eom bit, if 1 end of message, if 0 not. */ RELPKT_MSG_DATA = 2, /* * Request resending data from starting at the first sequence * number up to and including the last sequence number. * Data after the header is more resend requests in pairs. * * +----------------+----------------+----------------+ * | 3 |reserved|first seq resend|last seq resend | * +----------------+----------------+----------------+ */ RELPKT_MSG_RESEND = 3, /* * Request that the connection be closed. * * +----------------+----------------+----------------+ * | 4 |reserved| error msb | error lsb | * +----------------+----------------+----------------+ */ RELPKT_MSG_CLOSE = 4 }; enum relpkt_state { /* * relpkt is not operational. * * init => * send close * * open() => * if (server) * state = RELPKT_WAITING_INIT * else * send init * state = RELPKT_WAITING_INIT_RSP * start timer */ RELPKT_CLOSED = 0, /* * relpkt is waiting to receive an init message. For the * server. * * init => * if (!response) * send init rsp * state = RELPKT_OPEN * start timer * * data => * data resend => * close => * timeout => * * close() => * state = RELPKT_CLOSED */ RELPKT_WAITING_INIT, /* * relpkt has sent an init and is waiting a response. client only. * * init => * if (response) * state = RELPKT_OPEN * * data => * data resend => * * close => * state = RELPKT_CLOSED * * timeout => * if (retries >= max_retries) * state = RELPKT_CLOSED * report open fail * else * resend init * * close() => * send close * state = RELPKT_CLOSED */ RELPKT_WAITING_INIT_RSP, /* * init => * if !response * send init rsp * reschedule any sent data * * data => * handle ack * reset autoclose timeout * deliver data to user * * data resend => * resend requested packet * * close => * state = RELPKT_REMCLOSED * send close * * timeout => * if (autoclose timeout exceeded) * send close * state = RELPKT_REMCLOSED * * close() => * if (data to send) * state = RELPKT_WAITING_CLOSE_CLEAR * else * send close * state = RELPKT_WAITING_CLOSE_RSP */ RELPKT_OPEN, /* * A local close has been requested, waiting for the transmit * queue to clear. * * init => * if !response * send init rsp * reschedule any sent data * * data => * handle ack * if last sent packet acked * send close * if close msg received * state = RELPKT_CLOSED * else * state = RELPKT_WAITING_CLOSE_RSP * reset autoclose timeout * * data resend => * resend requested packet(s) * * close => * state = RELPKT_CLOSED * report close done * * close() => * * timeout => * if (autoclose timeout exceeded) * send close * state = RELPKT_CLOSED * */ RELPKT_WAITING_CLOSE_CLEAR, /* * We sent a close, waiting for a close response. * * init => * send close * * data => * data resend => * close => * state = RELPKT_CLOSED * report close done * * close() => * * timeout => * if (autoclose timeout exceeded) * send close * state = RELPKT_CLOSED */ RELPKT_WAITING_CLOSE_RSP, /* * The remote side requested a close. * * init => * send close * * data => * data resend => * close => * * close() => * state = REMPKT_CLOSED * report close done */ RELPKT_REMCLOSED }; struct pkt { uint16_t len; uint16_t start; /* For partial acceptance by user */ bool sent; /* If true, packet does not need to be sent. */ bool ready; /* If true, packet is ready to deliver to the user. */ bool eom; /* If true, report end of message. */ unsigned char *data; }; struct relpkt_filter { struct gensio_filter *filter; struct gensio_os_funcs *o; struct gensio_lock *lock; gensio_filter_cb filter_cb; void *filter_cb_data; enum relpkt_state state; int err; bool server; /* True if server mode. */ gensiods max_pktsize; unsigned int max_pkt; /* Our set value. */ uint8_t next_expected_seq; /* Next seq we expect from the remote. */ uint8_t next_deliver_seq; /* Next seq we will deliver to the user. */ uint8_t deliver_recvpkt; /* Pos in recvpkts of next_deliver_seq. */ struct pkt *recvpkts; /* * The other end is supposed to send an ack or data at least once * a second, keep track of how long since we've seen one to know * if the other end went belly up. */ unsigned int timeouts_since_ack; bool send_since_timeout; unsigned int max_xmit_pktsize; unsigned int max_xmitpkt; /* Set from remote end by init packet. */ uint8_t next_acked_seq; /* Seq for next packet that is unacked. */ uint8_t next_send_seq; /* Seq for next packet we will send. */ uint8_t first_xmitpkt; /* Pos in xmitpkts of where next_ack_seq is. */ struct pkt *xmitpkts; unsigned int nr_waiting_xmitpkt; /* nr in xmitpkt unsent */ char init_pkt[5]; bool send_init_pkt; unsigned int init_retry_count; char close_pkt[3]; bool send_close_pkt; unsigned int close_retry_count; char ack_pkt[3]; bool send_ack_pkt; char resend_pkt[51]; bool send_resend_pkt; uint16_t resend_pkt_len; gensio_time timeout; unsigned int max_timeouts; uint8_t last_timeout_ack; /* next_acked_seq on the last timeout. */ unsigned int timeout_ack_count; /* nr timeouts last_timeout_ack same. */ }; #define filter_to_relpkt(v) ((struct relpkt_filter *) \ gensio_filter_get_user_data(v)) #define link_to_pkt(v) gensio_container_of(v, struct pkt, link); static int i_relpkt_filter_timeout(struct relpkt_filter *rfilter); static void relpkt_lock(struct relpkt_filter *rfilter) { rfilter->o->lock(rfilter->lock); } static void relpkt_unlock(struct relpkt_filter *rfilter) { rfilter->o->unlock(rfilter->lock); } /* * Returns true if seq >= first and seq < next, taking into account * wrapping. If first == next, this will always return false. */ static bool seq_inside(uint8_t seq, uint8_t first, uint8_t next) { if (first <= next) /* not wrapped */ return seq >= first && seq < next; else /* wrapped */ return seq >= first || seq < next; } static uint8_t recvpkt_pos(struct relpkt_filter *rfilter, uint8_t pos) { return (rfilter->deliver_recvpkt + pos) % rfilter->max_pkt; } static uint8_t xmitpkt_pos(struct relpkt_filter *rfilter, uint8_t pos) { return (rfilter->first_xmitpkt + pos) % rfilter->max_xmitpkt; } static void resend_packets(struct relpkt_filter *rfilter, uint8_t first, uint8_t last) { uint8_t seq; unsigned int i, pos; for (seq = first, i = first - rfilter->next_acked_seq; seq != last; i++) { pos = xmitpkt_pos(rfilter, i); if (rfilter->xmitpkts[pos].sent) { rfilter->xmitpkts[pos].sent = false; rfilter->nr_waiting_xmitpkt++; } seq++; } } static struct pkt * first_xmitpkt_to_send(struct relpkt_filter *rfilter) { uint8_t seq = rfilter->next_acked_seq; unsigned int i, pos; for (i = 0; seq != rfilter->next_send_seq; i++, seq++) { pos = xmitpkt_pos(rfilter, i); if (!rfilter->xmitpkts[pos].sent) return &(rfilter->xmitpkts[pos]); } assert(0); return NULL; } static void send_init(struct relpkt_filter *rfilter, bool response) { rfilter->init_pkt[0] = (RELPKT_MSG_INIT << 4) | (uint8_t) response; rfilter->init_pkt[1] = 0; /* version */ rfilter->init_pkt[2] = rfilter->max_pkt; rfilter->init_pkt[3] = rfilter->max_pktsize >> 8; rfilter->init_pkt[4] = rfilter->max_pktsize & 0xff; rfilter->send_init_pkt = true; } static void send_close(struct relpkt_filter *rfilter) { rfilter->close_pkt[0] = RELPKT_MSG_CLOSE << 4; rfilter->close_pkt[1] = 0; rfilter->close_pkt[2] = 0; rfilter->send_close_pkt = true; } static void send_ack(struct relpkt_filter *rfilter) { rfilter->ack_pkt[0] = RELPKT_MSG_DATA << 4; /* seq will be filled in at send time. */ rfilter->ack_pkt[2] = 0; rfilter->send_ack_pkt = true; } static void request_resend(struct relpkt_filter *rfilter, uint8_t first, uint8_t last) { if (!rfilter->send_resend_pkt) { rfilter->resend_pkt_len = 1; rfilter->resend_pkt[0] = RELPKT_MSG_RESEND << 4; rfilter->send_resend_pkt = true; } if (rfilter->resend_pkt_len + 1U >= sizeof(rfilter->resend_pkt)) return; /* No space left, let transmit timeout get it. */ rfilter->resend_pkt[rfilter->resend_pkt_len++] = first; rfilter->resend_pkt[rfilter->resend_pkt_len++] = last; rfilter->timeout_ack_count = 0; } /* Returns true on a protocol error. */ static bool handle_ack(struct relpkt_filter *rfilter, uint8_t seq) { unsigned int pos; /* * The last received message on the other end is in seq, but we * keep the next thing that should be acked, thus the +1. */ if (!seq_inside(seq, rfilter->next_acked_seq, rfilter->next_send_seq + 1)) return true; while (rfilter->next_acked_seq != seq) { pos = rfilter->first_xmitpkt; if (!rfilter->xmitpkts[pos].sent) { /* * Packets wasn't sent yet, but we got an ack. Could * happen on a retransmit or some other error. Just act * like it was transmitted. */ rfilter->xmitpkts[pos].sent = true; assert(rfilter->nr_waiting_xmitpkt > 0); rfilter->nr_waiting_xmitpkt--; } rfilter->first_xmitpkt = xmitpkt_pos(rfilter, 1); rfilter->next_acked_seq++; } rfilter->timeouts_since_ack = 0; return false; } static void relpkt_filter_start_timer(struct relpkt_filter *rfilter) { rfilter->filter_cb(rfilter->filter_cb_data, GENSIO_FILTER_CB_START_TIMER, &rfilter->timeout); } static void relpkt_set_callbacks(struct relpkt_filter *rfilter, gensio_filter_cb cb, void *cb_data) { rfilter->filter_cb = cb; rfilter->filter_cb_data = cb_data; } static bool relpkt_ul_read_pending(struct relpkt_filter *rfilter) { struct pkt *p = &(rfilter->recvpkts[rfilter->deliver_recvpkt]); return p->ready; } static bool relpkt_ll_write_pending(struct relpkt_filter *rfilter) { return rfilter->nr_waiting_xmitpkt || rfilter->send_init_pkt || rfilter->send_close_pkt || rfilter->send_resend_pkt || rfilter->send_ack_pkt; } static bool relpkt_ul_can_write(struct relpkt_filter *rfilter, bool *rv) { unsigned int nrqueued = rfilter->next_send_seq - rfilter->next_acked_seq; *rv = nrqueued < rfilter->max_xmitpkt; return 0; } static bool relpkt_ll_write_queued(struct relpkt_filter *rfilter, bool *rv) { unsigned int nrqueued = rfilter->next_send_seq - rfilter->next_acked_seq; *rv = nrqueued > 0; return 0; } static bool relpkt_ll_read_needed(struct relpkt_filter *rfilter) { /* We can always take data. Flow control should keep us from overrunning */ return true; } static int relpkt_check_open_done(struct relpkt_filter *rfilter, struct gensio *io) { gensio_set_is_packet(io, true); gensio_set_is_message(io, true); gensio_set_is_reliable(io, true); return 0; } static int relpkt_try_connect(struct relpkt_filter *rfilter, gensio_time *timeout, bool was_timeout) { int rv = 0; relpkt_lock(rfilter); switch (rfilter->state) { case RELPKT_WAITING_INIT_RSP: if (was_timeout) { rfilter->init_retry_count++; if (rfilter->init_retry_count > 5) { rv = GE_TIMEDOUT; } else { send_init(rfilter, false); timeout->secs = 1; timeout->nsecs = 0; rv = GE_RETRY; } } else { rv = GE_INPROGRESS; } break; case RELPKT_CLOSED: if (rfilter->server) { rfilter->state = RELPKT_WAITING_INIT; rv = GE_INPROGRESS; } else { rfilter->state = RELPKT_WAITING_INIT_RSP; send_init(rfilter, false); timeout->secs = 1; timeout->nsecs = 0; rv = GE_RETRY; } break; case RELPKT_WAITING_INIT: rv = GE_INPROGRESS; break; case RELPKT_REMCLOSED: rv = GE_REMCLOSE; break; case RELPKT_OPEN: break; case RELPKT_WAITING_CLOSE_CLEAR: case RELPKT_WAITING_CLOSE_RSP: rv = GE_NOTREADY; break; default: assert(0); } relpkt_unlock(rfilter); return rv; } static int relpkt_try_disconnect(struct relpkt_filter *rfilter, gensio_time *timeout, bool was_timeout) { int rv = 0; relpkt_lock(rfilter); switch (rfilter->state) { case RELPKT_WAITING_INIT: break; case RELPKT_CLOSED: case RELPKT_REMCLOSED: if (!rfilter->send_close_pkt) /* Close packet has been sent. */ break; if (was_timeout) { i_relpkt_filter_timeout(rfilter); timeout->secs = 1; timeout->nsecs = 0; rv = GE_RETRY; } else { rv = GE_INPROGRESS; } break; case RELPKT_OPEN: if (rfilter->next_acked_seq == rfilter->next_send_seq) { /* Nothing left to send, start the close process. */ rfilter->state = RELPKT_WAITING_CLOSE_RSP; send_close(rfilter); } else { /* Wait for output to clear. */ rfilter->state = RELPKT_WAITING_CLOSE_CLEAR; } timeout->secs = 1; timeout->nsecs = 0; rv = GE_RETRY; break; case RELPKT_WAITING_CLOSE_CLEAR: /* * Normal timeouts will no longer happen, make sure to continue * timing here. */ if (rfilter->err) { rv = rfilter->err; } else { if (rfilter->next_acked_seq == rfilter->next_send_seq) { rfilter->state = RELPKT_WAITING_CLOSE_RSP; send_close(rfilter); } if (was_timeout) { i_relpkt_filter_timeout(rfilter); timeout->secs = 1; timeout->nsecs = 0; rv = GE_RETRY; } else { rv = GE_INPROGRESS; } } break; case RELPKT_WAITING_CLOSE_RSP: if (was_timeout) { rfilter->close_retry_count++; if (rfilter->close_retry_count > 5) { rv = GE_TIMEDOUT; } else { timeout->secs = 1; timeout->nsecs = 0; rv = GE_RETRY; } } else { rv = GE_INPROGRESS; } break; case RELPKT_WAITING_INIT_RSP: /* Should not happen. */ default: assert(0); } relpkt_unlock(rfilter); return rv; } static int relpkt_ul_write(struct relpkt_filter *rfilter, gensio_ul_filter_data_handler handler, void *cb_data, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { struct gensio_sg rsg = { NULL, 0 }; struct pkt *p = NULL; unsigned int nrqueued; int err = 0; bool *endbool = NULL; bool finish_close = false; relpkt_lock(rfilter); nrqueued = rfilter->next_send_seq - rfilter->next_acked_seq; if (sglen == 0 || nrqueued >= rfilter->max_xmitpkt) { if (rcount) *rcount = 0; } else { gensiods i, writelen = 0; bool trunc = false; unsigned int pos = xmitpkt_pos(rfilter, nrqueued); p = &(rfilter->xmitpkts[pos]); /* FIXME - if previous packet is not full and not eom, can append */ p->len = 0; for (i = 0; i < sglen; i++) { gensiods inlen = sg[i].buflen; const unsigned char *buf = sg[i].buf; if (inlen + p->len > rfilter->max_xmit_pktsize) { inlen = rfilter->max_xmit_pktsize - p->len; trunc = true; } memcpy(p->data + p->len + 3, buf, inlen); writelen += inlen; p->len += inlen; if (p->len == rfilter->max_xmit_pktsize) break; } if (rcount) *rcount = writelen; if (writelen > 0) { if (!trunc && gensio_str_in_auxdata(auxdata, "eom")) p->eom = true; p->data[0] = (RELPKT_MSG_DATA << 4) | (uint8_t) p->eom; /* Ack (byte 1) will be filled in on transmit. */ p->data[2] = rfilter->next_send_seq; rfilter->next_send_seq++; p->sent = false; p->len += 3; /* For the header. */ rfilter->nr_waiting_xmitpkt++; } } p = NULL; if (rfilter->send_init_pkt) { rsg.buf = rfilter->init_pkt; rsg.buflen = 5; endbool = &rfilter->send_init_pkt; } else if (rfilter->nr_waiting_xmitpkt) { p = first_xmitpkt_to_send(rfilter); rsg.buf = p->data; rsg.buflen = p->len; p->data[1] = rfilter->next_deliver_seq; /* Add the ack */ rfilter->send_ack_pkt = false; } else if (rfilter->send_resend_pkt) { rsg.buf = rfilter->resend_pkt; rsg.buflen = rfilter->resend_pkt_len; endbool = &rfilter->send_resend_pkt; } else if (rfilter->send_ack_pkt) { rfilter->ack_pkt[1] = rfilter->next_deliver_seq; rsg.buf = rfilter->ack_pkt; rsg.buflen = 3; endbool = &rfilter->send_ack_pkt; } else if (rfilter->send_close_pkt) { rsg.buf = rfilter->close_pkt; rsg.buflen = 3; endbool = &rfilter->send_close_pkt; if (rfilter->state == RELPKT_REMCLOSED) finish_close = true; } if (rsg.buflen) { gensiods count; #ifdef DEBUG_MSG printf("Writing(%p):", rfilter); prbuf(rsg.buf, rsg.buflen); #endif #ifdef DROP_NR if (p && curr_drop % DROP_NR == 0) { err = 0; count = rsg.buflen; } else #endif err = handler(cb_data, &count, &rsg, 1, NULL); #ifdef DROP_NR if (p) curr_drop++; #endif if (!err) { if (count != 0 && count != rsg.buflen) { /* * Is this right? Lower layer should take whole packets * or nothing. */ err = GE_TOOBIG; } else if (count != 0) { if (p) { p->sent = true; assert(rfilter->nr_waiting_xmitpkt); rfilter->nr_waiting_xmitpkt--; rfilter->send_since_timeout = true; } else { if (endbool) *endbool = false; if (finish_close) { rfilter->err = GE_REMCLOSE; err = GE_REMCLOSE; } } } } } relpkt_unlock(rfilter); return err; } static int relpkt_ll_write(struct relpkt_filter *rfilter, gensio_ll_filter_data_handler handler, void *cb_data, gensiods *rcount, unsigned char *buf, gensiods buflen, const char *const *auxdata) { int err = 0; static const char *eomaux[2] = { "eom", NULL }; bool response; uint8_t seq, endseq, pos, ppos; unsigned int i; struct pkt *p; const char *proto_err_str = NULL; #ifdef DEBUG_MSG if (buflen) { printf("Read(%p):", rfilter); prbuf(buf, buflen); } #endif relpkt_lock(rfilter); if (rfilter->err) { err = rfilter->err; goto out_unlock; } if (buflen == 0) { if (rcount) *rcount = 0; goto deliver_recv; } if (buflen < 3) { proto_err_str = "buflen < 3"; goto protocol_err; } if (rcount) *rcount = buflen; switch (buf[0] >> 4) { case RELPKT_MSG_INIT: if (buflen < 5) { proto_err_str = "buflen < 5"; goto protocol_err; } response = buf[0] & 1; switch (rfilter->state) { case RELPKT_CLOSED: case RELPKT_WAITING_CLOSE_RSP: case RELPKT_REMCLOSED: send_close(rfilter); break; case RELPKT_WAITING_INIT: if (!response) { rfilter->max_xmitpkt = buf[2]; if (rfilter->max_xmitpkt == 0) { proto_err_str = "rfilter->max_xmitpkt == 0"; goto protocol_err; } if (rfilter->max_xmitpkt > rfilter->max_pkt) rfilter->max_xmitpkt = rfilter->max_pkt; rfilter->max_xmit_pktsize = buf[3] << 8 | buf[4]; if (rfilter->max_xmit_pktsize > rfilter->max_pktsize) rfilter->max_xmit_pktsize = rfilter->max_pktsize; send_init(rfilter, true); rfilter->state = RELPKT_OPEN; relpkt_filter_start_timer(rfilter); } break; case RELPKT_WAITING_INIT_RSP: if (response) { rfilter->max_xmitpkt = buf[2]; if (rfilter->max_xmitpkt > rfilter->max_pkt) rfilter->max_xmitpkt = rfilter->max_pkt; rfilter->max_xmit_pktsize = buf[3] << 8 | buf[4]; if (rfilter->max_xmit_pktsize > rfilter->max_pktsize) rfilter->max_xmit_pktsize = rfilter->max_pktsize; rfilter->state = RELPKT_OPEN; relpkt_filter_start_timer(rfilter); } break; case RELPKT_OPEN: case RELPKT_WAITING_CLOSE_CLEAR: if (!response) { send_init(rfilter, true); resend_packets(rfilter, rfilter->next_acked_seq, rfilter->next_send_seq); } break; default: assert(0); } break; case RELPKT_MSG_DATA: switch (rfilter->state) { case RELPKT_CLOSED: case RELPKT_WAITING_INIT: case RELPKT_WAITING_INIT_RSP: case RELPKT_WAITING_CLOSE_RSP: case RELPKT_REMCLOSED: break; case RELPKT_OPEN: case RELPKT_WAITING_CLOSE_CLEAR: if (buflen > rfilter->max_pktsize + 3) { proto_err_str = "buflen > rfilter->max_pktsize + 3"; goto protocol_err; } if (handle_ack(rfilter, buf[1])) goto out_unlock; if (rfilter->state != RELPKT_OPEN) { /* Only deliver data in open state */ if (rfilter->next_acked_seq == rfilter->next_send_seq) { /* No more data, we can close. */ rfilter->state = RELPKT_WAITING_CLOSE_RSP; send_close(rfilter); } break; } if (buflen == 3) /* Just an ack */ break; seq = buf[2]; pos = seq - rfilter->next_deliver_seq; if ((uint8_t) (seq - rfilter->next_deliver_seq) > rfilter->max_pkt) break; /* Ignore it */ ppos = recvpkt_pos(rfilter, pos); if (seq == rfilter->next_expected_seq) { rfilter->next_expected_seq++; } else if (!seq_inside(seq, rfilter->next_deliver_seq, rfilter->next_expected_seq)) { request_resend(rfilter, rfilter->next_expected_seq, seq - 1); rfilter->next_expected_seq = seq + 1; } p = &(rfilter->recvpkts[ppos]); if (!p->ready) { memcpy(p->data, buf + 3, buflen - 3); p->len = buflen - 3; p->start = 0; p->ready = true; p->eom = buf[0] & 1; } break; default: assert(0); } break; case RELPKT_MSG_RESEND: switch (rfilter->state) { case RELPKT_CLOSED: case RELPKT_WAITING_INIT: case RELPKT_WAITING_INIT_RSP: case RELPKT_REMCLOSED: break; case RELPKT_OPEN: case RELPKT_WAITING_CLOSE_CLEAR: case RELPKT_WAITING_CLOSE_RSP: buf++; buflen--; if (buflen % 2 != 0) { /* Should be pairs of sequence numbers. */ proto_err_str = "buflen % 2 != 0"; goto protocol_err; } for (i = 0; i < buflen; i += 2) { seq = buf[i]; endseq = buf[i + 1]; if (!seq_inside(seq, rfilter->next_acked_seq, rfilter->next_send_seq)) { proto_err_str = "seq_inside A"; goto protocol_err; } if (!seq_inside(endseq, rfilter->next_acked_seq, rfilter->next_send_seq)) { proto_err_str = "seq_inside B"; goto protocol_err; } resend_packets(rfilter, seq, endseq + 1); } break; default: assert(0); } break; case RELPKT_MSG_CLOSE: switch (rfilter->state) { case RELPKT_CLOSED: case RELPKT_WAITING_INIT: case RELPKT_REMCLOSED: break; case RELPKT_WAITING_INIT_RSP: rfilter->state = RELPKT_CLOSED; break; case RELPKT_OPEN: case RELPKT_WAITING_CLOSE_CLEAR: rfilter->state = RELPKT_REMCLOSED; send_close(rfilter); break; case RELPKT_WAITING_CLOSE_RSP: rfilter->state = RELPKT_CLOSED; break; default: assert(0); } break; default: proto_err_str = "pkttype"; goto protocol_err; } deliver_recv: p = &(rfilter->recvpkts[rfilter->deliver_recvpkt]); if (p->ready) { gensiods count = 0; relpkt_unlock(rfilter); err = handler(cb_data, &count, p->data + p->start, p->len - p->start, p->eom ? eomaux : NULL); relpkt_lock(rfilter); if (!err) { if (count >= (uint16_t) (p->len - p->start)) { p->ready = false; rfilter->deliver_recvpkt = recvpkt_pos(rfilter, 1); rfilter->next_deliver_seq++; send_ack(rfilter); } else { p->start += count; } } } out_unlock: relpkt_unlock(rfilter); return err; protocol_err: relpkt_unlock(rfilter); gensio_filter_log(rfilter->filter, GENSIO_LOG_ERR, "relpkt: protocol error: %s", proto_err_str); return GE_PROTOERR; } static int relpkt_setup(struct relpkt_filter *rfilter) { return 0; } static void relpkt_filter_cleanup(struct relpkt_filter *rfilter) { unsigned int i; rfilter->state = RELPKT_CLOSED; rfilter->err = 0; rfilter->next_expected_seq = 0; rfilter->next_deliver_seq = 0; rfilter->deliver_recvpkt = 0; rfilter->timeouts_since_ack = 0; rfilter->next_acked_seq = 0; rfilter->next_send_seq = 0; rfilter->first_xmitpkt = 0; rfilter->nr_waiting_xmitpkt = 0; rfilter->send_init_pkt = false; rfilter->init_retry_count = 0; rfilter->send_close_pkt = false; rfilter->close_retry_count = 0; rfilter->send_resend_pkt = false; rfilter->send_ack_pkt = false; for (i = 0; i < rfilter->max_pkt; i++) { struct pkt *p = &rfilter->recvpkts[i]; p->ready = false; } } static void relpkt_free(struct relpkt_filter *rfilter) { struct gensio_os_funcs *o = rfilter->o; gensiods i; if (rfilter->lock) o->free_lock(rfilter->lock); if (rfilter->recvpkts) { for (i = 0; i < rfilter->max_pkt; i++) { if (rfilter->recvpkts[i].data) o->free(o, rfilter->recvpkts[i].data); } o->free(o, rfilter->recvpkts); } if (rfilter->xmitpkts) { /* Yes, the below is max_pkt for xmit. That's the array size. */ for (i = 0; i < rfilter->max_pkt; i++) { if (rfilter->xmitpkts[i].data) o->free(o, rfilter->xmitpkts[i].data); } o->free(o, rfilter->xmitpkts); } if (rfilter->filter) gensio_filter_free_data(rfilter->filter); rfilter->o->free(rfilter->o, rfilter); } static int i_relpkt_filter_timeout(struct relpkt_filter *rfilter) { rfilter->timeouts_since_ack++; if (rfilter->timeouts_since_ack > rfilter->max_timeouts) { rfilter->err = GE_TIMEDOUT; return GE_TIMEDOUT; } if (rfilter->send_since_timeout) rfilter->send_since_timeout = false; else send_ack(rfilter); if (rfilter->next_acked_seq != rfilter->next_send_seq) { if (rfilter->next_acked_seq == rfilter->last_timeout_ack) { rfilter->timeout_ack_count++; if (rfilter->timeout_ack_count > 1) { /* * We haven't received an ack for something we sent. * The packet must have been dropped. Resend. */ resend_packets(rfilter, rfilter->next_acked_seq, rfilter->next_send_seq); rfilter->timeout_ack_count = 0; } } else { rfilter->timeout_ack_count = 0; rfilter->last_timeout_ack = rfilter->next_acked_seq; } } relpkt_filter_start_timer(rfilter); return 0; } static int relpkt_filter_timeout(struct relpkt_filter *rfilter) { int err; relpkt_lock(rfilter); err = i_relpkt_filter_timeout(rfilter); relpkt_unlock(rfilter); return err; } static int gensio_relpkt_filter_func(struct gensio_filter *filter, int op, void *func, void *data, gensiods *count, void *buf, const void *cbuf, gensiods buflen, const char *const *auxdata) { struct relpkt_filter *rfilter = filter_to_relpkt(filter); switch (op) { case GENSIO_FILTER_FUNC_SET_CALLBACK: relpkt_set_callbacks(rfilter, func, data); return 0; case GENSIO_FILTER_FUNC_UL_READ_PENDING: return relpkt_ul_read_pending(rfilter); case GENSIO_FILTER_FUNC_LL_WRITE_PENDING: return relpkt_ll_write_pending(rfilter); case GENSIO_FILTER_FUNC_UL_CAN_WRITE: return relpkt_ul_can_write(rfilter, data); case GENSIO_FILTER_FUNC_LL_WRITE_QUEUED: return relpkt_ll_write_queued(rfilter, data); case GENSIO_FILTER_FUNC_LL_READ_NEEDED: return relpkt_ll_read_needed(rfilter); case GENSIO_FILTER_FUNC_CHECK_OPEN_DONE: return relpkt_check_open_done(rfilter, data); case GENSIO_FILTER_FUNC_TRY_CONNECT: return relpkt_try_connect(rfilter, data, buflen); case GENSIO_FILTER_FUNC_TRY_DISCONNECT: return relpkt_try_disconnect(rfilter, data, buflen); case GENSIO_FILTER_FUNC_UL_WRITE_SG: return relpkt_ul_write(rfilter, func, data, count, cbuf, buflen, auxdata); case GENSIO_FILTER_FUNC_LL_WRITE: return relpkt_ll_write(rfilter, func, data, count, buf, buflen, auxdata); case GENSIO_FILTER_FUNC_SETUP: return relpkt_setup(rfilter); case GENSIO_FILTER_FUNC_CLEANUP: relpkt_filter_cleanup(rfilter); return 0; case GENSIO_FILTER_FUNC_FREE: relpkt_free(rfilter); return 0; case GENSIO_FILTER_FUNC_TIMEOUT: return relpkt_filter_timeout(rfilter); default: return GE_NOTSUP; } } static struct gensio_filter * gensio_relpkt_filter_raw_alloc(struct gensio_os_funcs *o, gensiods max_pktsize, gensiods max_packets, bool server, gensio_time *timeout, unsigned int max_timeouts) { struct relpkt_filter *rfilter; gensiods i; rfilter = o->zalloc(o, sizeof(*rfilter)); if (!rfilter) return NULL; rfilter->o = o; rfilter->server = server; rfilter->lock = o->alloc_lock(o); if (!rfilter->lock) goto out_nomem; rfilter->max_pkt = max_packets; rfilter->max_pktsize = max_pktsize; rfilter->timeout = *timeout; rfilter->max_timeouts = max_timeouts; rfilter->recvpkts = o->zalloc(o, sizeof(struct pkt) * max_packets); if (!rfilter->recvpkts) goto out_nomem; for (i = 0; i < max_packets; i++) { rfilter->recvpkts[i].data = o->zalloc(o, max_pktsize); if (!rfilter->recvpkts[i].data) goto out_nomem; } rfilter->xmitpkts = o->zalloc(o, sizeof(struct pkt) * max_packets); if (!rfilter->xmitpkts) goto out_nomem; for (i = 0; i < max_packets; i++) { rfilter->xmitpkts[i].data = o->zalloc(o, max_pktsize + 3); if (!rfilter->xmitpkts[i].data) goto out_nomem; } rfilter->filter = gensio_filter_alloc_data(o, gensio_relpkt_filter_func, rfilter); if (!rfilter->filter) goto out_nomem; return rfilter->filter; out_nomem: relpkt_free(rfilter); return NULL; } static int gensio_relpkt_filter_alloc(struct gensio_pparm_info *p, struct gensio_os_funcs *o, const char * const args[], bool server, struct gensio_filter **rfilter) { struct gensio_filter *filter; unsigned int i; gensiods max_pktsize = 123; /* FIXME - magic number. */ gensiods max_packets = 16; gensio_time timeout = { 1, 0 }; unsigned int max_timeouts = 5; char *str = NULL; int rv; rv = gensio_get_default(o, "relpkt", "mode", false, GENSIO_DEFAULT_STR, &str, NULL); if (rv) { gensio_log(o, GENSIO_LOG_ERR, "Failed getting relpkt mode: %s", gensio_err_to_str(rv)); return rv; } if (str) { if (strcasecmp(str, "client") == 0) server = true; else if (strcasecmp(str, "server") == 0) server = false; else { gensio_log(o, GENSIO_LOG_ERR, "Unknown default relpkt mode (%s), ignoring", str); } o->free(o, str); } for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(p, args[i], "max_pktsize", &max_pktsize) > 0) continue; if (gensio_pparm_ds(p, args[i], "max_packets", &max_packets) > 0) continue; if (gensio_pparm_boolv(p, args[i], "mode", "server", "client", &server) > 0) continue; if (gensio_pparm_time(p, args[i], "timeout", 's', &timeout) > 0) continue; if (gensio_pparm_uint(p, args[i], "max_timeouts", &max_timeouts) > 0) continue; gensio_pparm_unknown_parm(p, args[i]); return GE_INVAL; } filter = gensio_relpkt_filter_raw_alloc(o, max_pktsize, max_packets, server, &timeout, max_timeouts); if (!filter) return GE_NOMEM; *rfilter = filter; return 0; } static int relpkt_gensio_alloc(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **net) { int err; struct gensio_filter *filter; struct gensio_ll *ll; struct gensio *io; GENSIO_DECLARE_PPGENSIO(p, o, cb, "relpkt", user_data); err = gensio_relpkt_filter_alloc(&p, o, args, false, &filter); if (err) return err; ll = gensio_gensio_ll_alloc(o, child); if (!ll) { gensio_filter_free(filter); return GE_NOMEM; } gensio_ref(child); /* So gensio_ll_free doesn't free the child if fail */ io = base_gensio_alloc(o, ll, filter, child, "relpkt", cb, user_data); if (!io) { gensio_ll_free(ll); gensio_filter_free(filter); return GE_NOMEM; } gensio_set_is_packet(io, true); gensio_set_is_message(io, true); gensio_set_is_reliable(io, true); gensio_free(child); /* Lose the ref we acquired. */ *net = io; return 0; } static int str_to_relpkt_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct gensio *io2; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio(str, o, cb, user_data, &io2); if (err) return err; err = relpkt_gensio_alloc(io2, args, o, cb, user_data, new_gensio); if (err) gensio_free(io2); return err; } struct relpktna_data { struct gensio_accepter *acc; const char **args; struct gensio_os_funcs *o; gensio_accepter_event cb; void *user_data; }; static void relpktna_free(void *acc_data) { struct relpktna_data *nadata = acc_data; if (nadata->args) gensio_argv_free(nadata->o, nadata->args); nadata->o->free(nadata->o, nadata); } static int relpktna_alloc_gensio(void *acc_data, const char * const *iargs, struct gensio *child, struct gensio **rio) { struct relpktna_data *nadata = acc_data; return relpkt_gensio_alloc(child, iargs, nadata->o, NULL, NULL, rio); } static int relpktna_new_child(void *acc_data, void **finish_data, struct gensio_filter **filter) { struct relpktna_data *nadata = acc_data; GENSIO_DECLARE_PPACCEPTER(p, nadata->o, nadata->cb, "relpkt", nadata->user_data); return gensio_relpkt_filter_alloc(&p, nadata->o, nadata->args, true, filter); } static int relpktna_finish_parent(void *acc_data, void *finish_data, struct gensio *io) { gensio_set_is_packet(io, true); gensio_set_is_reliable(io, true); return 0; } static int gensio_gensio_acc_relpkt_cb(void *acc_data, int op, void *data1, void *data2, void *data3, const void *data4) { switch (op) { case GENSIO_GENSIO_ACC_ALLOC_GENSIO: return relpktna_alloc_gensio(acc_data, data4, data1, data2); case GENSIO_GENSIO_ACC_NEW_CHILD: return relpktna_new_child(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FINISH_PARENT: return relpktna_finish_parent(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FREE: relpktna_free(acc_data); return 0; default: return GE_NOTSUP; } } static int relpkt_gensio_accepter_alloc(struct gensio_accepter *child, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { struct relpktna_data *nadata; int err; if (!gensio_acc_is_packet(child)) return GE_INVAL; nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) return GE_NOMEM; err = gensio_argv_copy(o, args, NULL, &nadata->args); if (err) { o->free(o, nadata); return err; } nadata->o = o; nadata->cb = cb; nadata->user_data = user_data; err = gensio_gensio_accepter_alloc(child, o, "relpkt", cb, user_data, gensio_gensio_acc_relpkt_cb, nadata, &nadata->acc); if (err) goto out_err; gensio_acc_set_is_packet(nadata->acc, true); gensio_acc_set_is_reliable(nadata->acc, true); *accepter = nadata->acc; return 0; out_err: relpktna_free(nadata); return err; } static int str_to_relpkt_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { int err; struct gensio_accepter *acc2 = NULL; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio_accepter(str, o, cb, user_data, &acc2); if (!err) { err = relpkt_gensio_accepter_alloc(acc2, args, o, cb, user_data, acc); if (err) gensio_acc_free(acc2); } return err; } int gensio_init_relpkt(struct gensio_os_funcs *o) { int rv; rv = register_filter_gensio(o, "relpkt", str_to_relpkt_gensio, relpkt_gensio_alloc); if (rv) return rv; rv = register_filter_gensio_accepter(o, "relpkt", str_to_relpkt_gensio_accepter, relpkt_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/gensio_dgram.c0000664000175000017500000016466715007164240012054 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* This code handles UDP network I/O. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #ifdef ENABLE_INTERNAL_TRACE #define DEBUG_STATE #endif #if HAVE_UNIX #include #include #include #include #include #include #include #include #include /* * This section is duplicated in gensio_net.c. If you fix something * here, fix it there, too. */ #define SIZEOF_SOCKADDR_UN_HEADER \ (sizeof(struct sockaddr_un) - \ sizeof(((struct sockaddr_un *) 0)->sun_path)) #define MAX_UNIX_ADDR_PATH (sizeof(((struct sockaddr_un *) 0)->sun_path) + 1) static void get_unix_addr_path(struct gensio_addr *addr, char *path) { struct sockaddr_storage taddr; struct sockaddr_un *sun = (struct sockaddr_un *) &taddr; gensiods len = sizeof(taddr); /* Remove the socket if it already exists. */ gensio_addr_getaddr(addr, sun, &len); len -= SIZEOF_SOCKADDR_UN_HEADER; /* * Make sure the path is nil terminated. See discussions * in the unix(7) man page on Linux for details. */ memcpy(path, sun->sun_path, len); path[len] = '\0'; } #endif static void netna_rm_unix_socket(struct gensio_addr *addr) { #if HAVE_UNIX char path[MAX_UNIX_ADDR_PATH]; /* Remove the socket if it already exists. */ get_unix_addr_path(addr, path); unlink(path); #endif } /* * Maximum UDP packet size, this avoids partial packet reads. Probably * not a good idea to override this. */ #define GENSIO_DEFAULT_UDP_BUF_SIZE 65536 struct udpna_data; enum udpn_state { UDPN_CLOSED = 0, UDPN_IN_OPEN, UDPN_OPEN, UDPN_IN_CLOSE }; struct udpn_data { struct gensio *io; struct udpna_data *nadata; struct gensio_os_funcs *o; /* iod the original request came in on, for sending. */ struct gensio_iod *myiod; bool read_enabled; /* Read callbacks are enabled. */ bool write_enabled; /* Write callbacks are enabled. */ bool in_read; /* Currently in a read callback. */ bool deferred_read; bool in_write; /* Currently in a write callback. */ bool write_pending; /* Need to redo the write callback. */ bool in_open_cb; /* Currently in an open callback. */ bool in_close_cb; /* Currently in a close callback. */ bool extrainfo; /* Deliver extrainfo to user? */ enum udpn_state state; bool freed; /* Freed during the close process. */ gensio_done_err open_done; void *open_data; gensio_done close_done; void *close_data; bool deferred_op_pending; struct gensio_runner *deferred_op_runner; /* NULL if not a client. */ struct gensio_addr *raddr; /* Points to remote, for convenience. */ struct gensio_link link; }; #define gensio_link_to_ndata(l) \ gensio_container_of(l, struct udpn_data, link); struct udpna_data; #ifdef DEBUG_STATE struct udp_state_trace { enum udpn_state old_state; enum udpn_state new_state; int line; bool readdisable; }; #define STATE_TRACE_LEN 256 #else #define i_udp_add_trace(nadata, ndata, new_state, line) #endif struct udpna_data { struct gensio_accepter *acc; struct gensio_list udpns; unsigned int udpn_count; unsigned int refcount; struct gensio_os_funcs *o; struct gensio_lock *lock; gensiods max_read_size; unsigned char *read_data; bool readhandler_read_disabled; gensiods data_pending_len; gensiods data_pos; struct udpn_data *pending_data_owner; struct gensio_list closed_udpns; int protocol; const char *typestr; struct gensio_addr *laddr; #if HAVE_UNIX mode_t mode; bool mode_set; char *owner; char *group; #endif /* * Used to run read callbacks from the selector to avoid running * it directly from user calls. */ bool deferred_op_pending; struct gensio_runner *deferred_op_runner; bool in_new_connection; struct gensio_runner *enable_done_runner; gensio_acc_done enable_done; void *enable_done_data; bool is_dummy; /* Am I a dummy udpna? */ bool enabled; bool closed; bool in_shutdown; bool disabled; bool freed; bool finished_free; gensio_acc_done shutdown_done; void *shutdown_data; struct gensio_addr *ai; /* The address list for the portname. */ struct gensio_opensocks *fds; /* The file descriptor used for the UDP ports. */ unsigned int nr_fds; unsigned int opensock_flags; unsigned int extrainfo; /* Is extrainfo enabled or disabled in the iod? */ bool nocon; /* Disable connection-oriented handling. */ struct gensio_addr *curr_recvaddr; /* Address of current received packet */ bool in_write; unsigned int read_disable_count; bool read_disabled; unsigned int write_enable_count; #ifdef DEBUG_STATE struct udp_state_trace state_trace[STATE_TRACE_LEN]; unsigned int state_trace_pos; #endif }; static void udpna_do_free(struct udpna_data *nadata); static void i_udpna_lock(struct udpna_data *nadata) { nadata->o->lock(nadata->lock); } static void i_udpna_unlock(struct udpna_data *nadata) { nadata->o->unlock(nadata->lock); } static void i_udpna_ref(struct udpna_data *nadata) { assert(nadata->refcount > 0); nadata->refcount++; } static void i_udpna_deref(struct udpna_data *nadata) { assert(nadata->refcount > 1); nadata->refcount--; } static void i_udpna_lock_and_ref(struct udpna_data *nadata) { i_udpna_lock(nadata); i_udpna_ref(nadata); } static void i_udpna_deref_and_unlock(struct udpna_data *nadata) { assert(nadata->refcount > 0); nadata->refcount--; if (nadata->refcount == 0) { i_udpna_unlock(nadata); udpna_do_free(nadata); } else { i_udpna_unlock(nadata); } } #ifdef DEBUG_STATE static void i_udp_add_trace(struct udpna_data *nadata, struct udpn_data *ndata, enum udpn_state new_state, int line) { if (ndata) nadata->state_trace[nadata->state_trace_pos].old_state = ndata->state; else nadata->state_trace[nadata->state_trace_pos].old_state = 99; nadata->state_trace[nadata->state_trace_pos].new_state = new_state; nadata->state_trace[nadata->state_trace_pos].line = line; nadata->state_trace[nadata->state_trace_pos].readdisable = nadata->read_disabled; if (nadata->state_trace_pos == STATE_TRACE_LEN - 1) nadata->state_trace_pos = 0; else nadata->state_trace_pos++; } #define udpna_lock(nadata) do { \ i_udpna_lock(nadata); \ i_udp_add_trace(nadata, NULL, 1001, __LINE__); \ } while(0) #define udpna_unlock(nadata) do { \ i_udp_add_trace(nadata, NULL, 1002, __LINE__); \ i_udpna_unlock(nadata); \ } while(0) #define udpna_ref(nadata) do { \ i_udpna_ref(nadata); \ i_udp_add_trace(nadata, NULL, 2000 + nadata->refcount, __LINE__); \ } while(0) #define udpna_deref(nadata) do { \ i_udp_add_trace(nadata, NULL, 3000 + nadata->refcount, __LINE__); \ i_udpna_deref(nadata); \ } while(0) #define udpna_lock_and_ref(nadata) do { \ i_udpna_lock_and_ref(nadata); \ i_udp_add_trace(nadata, NULL, 2000 + nadata->refcount, __LINE__); \ } while(0) #define udpna_deref_and_unlock(nadata) do { \ i_udp_add_trace(nadata, NULL, 3000 + nadata->refcount, __LINE__); \ i_udpna_deref_and_unlock(nadata); \ } while(0) static void i_udpn_set_state(struct udpn_data *ndata, enum udpn_state state, int line) { i_udp_add_trace(ndata->nadata, ndata, state, line); ndata->state = state; } #define udpn_set_state(ndata, state) \ i_udpn_set_state(ndata, state, __LINE__) #else #define udpna_lock i_udpna_lock #define udpna_unlock i_udpna_unlock #define udpna_ref i_udpna_ref #define udpna_deref i_udpna_deref #define udpna_lock_and_ref i_udpna_lock_and_ref #define udpna_deref_and_unlock i_udpna_deref_and_unlock static void udpn_set_state(struct udpn_data *ndata, enum udpn_state state) { ndata->state = state; } #endif static void udpna_start_deferred_op(struct udpna_data *nadata) { if (!nadata->deferred_op_pending) { udpna_ref(nadata); nadata->deferred_op_pending = true; nadata->o->run(nadata->deferred_op_runner); } } static void udpn_remove_from_list(struct gensio_list *list, struct udpn_data *ndata) { gensio_list_rm(list, &ndata->link); } static struct udpn_data * udpn_find(struct gensio_list *list, struct gensio_addr *addr) { struct gensio_link *l; gensio_list_for_each(list, l) { struct udpn_data *ndata = gensio_link_to_ndata(l); if (gensio_addr_equal(ndata->raddr, addr, true, false)) return ndata; } return NULL; } static void udpn_add_to_list(struct gensio_list *list, struct udpn_data *ndata) { gensio_list_add_tail(list, &ndata->link); } static void udpna_enable_read(struct udpna_data *nadata) { unsigned int i; nadata->read_disabled = false; for (i = 0; i < nadata->nr_fds; i++) nadata->o->set_read_handler(nadata->fds[i].iod, true); } static void udpna_disable_read(struct udpna_data *nadata) { unsigned int i; nadata->read_disabled = true; for (i = 0; i < nadata->nr_fds; i++) nadata->o->set_read_handler(nadata->fds[i].iod, false); } static void udpna_check_read_state(struct udpna_data *nadata) { if (nadata->read_disabled && nadata->read_disable_count == 0) udpna_enable_read(nadata); else if (!nadata->read_disabled && nadata->read_disable_count > 0) udpna_disable_read(nadata); } static void i_udpna_fd_read_enable(struct udpna_data *nadata, int line) { assert(nadata->read_disable_count > 0); nadata->read_disable_count--; i_udp_add_trace(nadata, NULL, 5100 + nadata->read_disable_count, line); udpna_check_read_state(nadata); } #define udpna_fd_read_enable(nadata) i_udpna_fd_read_enable(nadata, __LINE__) static void i_udpna_fd_read_disable(struct udpna_data *nadata, int line) { nadata->read_disable_count++; i_udp_add_trace(nadata, NULL, 5200 + nadata->read_disable_count, line); udpna_check_read_state(nadata); } #define udpna_fd_read_disable(nadata) i_udpna_fd_read_disable(nadata, __LINE__) static void udpna_disable_write(struct udpna_data *nadata) { unsigned int i; for (i = 0; i < nadata->nr_fds; i++) nadata->o->set_write_handler(nadata->fds[i].iod, false); } static void udpna_fd_write_disable(struct udpna_data *nadata) { assert(nadata->write_enable_count > 0); nadata->write_enable_count--; if (nadata->write_enable_count == 0 && !nadata->in_write) udpna_disable_write(nadata); } static void udpna_enable_write(struct udpna_data *nadata) { unsigned int i; for (i = 0; i < nadata->nr_fds; i++) nadata->o->set_write_handler(nadata->fds[i].iod, true); } static void udpna_fd_write_enable(struct udpna_data *nadata) { if (nadata->write_enable_count == 0 && !nadata->in_write) udpna_enable_write(nadata); nadata->write_enable_count++; } static void udpna_do_free(struct udpna_data *nadata) { unsigned int i; for (i = 0; i < nadata->nr_fds; i++) { if (nadata->fds && nadata->fds[i].iod) nadata->o->close(&nadata->fds[i].iod); } if (nadata->deferred_op_runner) nadata->o->free_runner(nadata->deferred_op_runner); if (nadata->enable_done_runner) nadata->o->free_runner(nadata->enable_done_runner); if (nadata->ai) gensio_addr_free(nadata->ai); if (nadata->laddr) gensio_addr_free(nadata->laddr); #if HAVE_UNIX if (nadata->owner) nadata->o->free(nadata->o, nadata->owner); if (nadata->group) nadata->o->free(nadata->o, nadata->group); #endif if (nadata->fds) nadata->o->free(nadata->o, nadata->fds); if (nadata->curr_recvaddr) gensio_addr_free(nadata->curr_recvaddr); if (nadata->read_data) nadata->o->free(nadata->o, nadata->read_data); if (nadata->lock) nadata->o->free_lock(nadata->lock); if (nadata->acc) gensio_acc_data_free(nadata->acc); nadata->o->free(nadata->o, nadata); } static void udpna_fd_cleared(struct gensio_iod *iod, void *cbdata) { struct udpna_data *nadata = cbdata; udpna_lock(nadata); udpna_deref_and_unlock(nadata); } static void udpna_check_finish_free(struct udpna_data *nadata) { unsigned int i; if (!nadata->closed || nadata->in_new_connection || nadata->udpn_count || nadata->in_shutdown || !nadata->freed) return; if (nadata->finished_free) return; nadata->finished_free = true; udpna_deref(nadata); for (i = 0; i < nadata->nr_fds; i++) { udpna_ref(nadata); nadata->o->clear_fd_handlers(nadata->fds[i].iod); } if (nadata->protocol != GENSIO_NET_PROTOCOL_UDP) { /* Remove the sockets. */ if (nadata->ai) netna_rm_unix_socket(nadata->ai); if (nadata->laddr) netna_rm_unix_socket(nadata->laddr); } } static void udpn_do_free(struct udpn_data *ndata) { if (ndata->io) gensio_data_free(ndata->io); if (ndata->deferred_op_runner) ndata->o->free_runner(ndata->deferred_op_runner); if (ndata->raddr) gensio_addr_free(ndata->raddr); ndata->o->free(ndata->o, ndata); } static void udpn_finish_free(struct udpn_data *ndata) { struct udpna_data *nadata = ndata->nadata; udpn_remove_from_list(&nadata->closed_udpns, ndata); assert(nadata->udpn_count > 0); nadata->udpn_count--; udpn_do_free(ndata); udpna_check_finish_free(nadata); } static int udpn_write(struct gensio *io, gensiods *count, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { struct udpn_data *ndata = gensio_get_gensio_data(io); struct gensio_addr *addr = NULL; unsigned int i; bool free_addr = false; int err; for (i = 0; auxdata && auxdata[i]; i++) { if (strncmp(auxdata[i], "addr:", 5) == 0) { if (addr) gensio_addr_free(addr); err = gensio_os_scan_netaddr(ndata->o, auxdata[i] + 5, false, ndata->nadata->protocol, &addr); if (err) return err; free_addr = true; } else { return GE_INVAL; } } if (!addr) addr = ndata->raddr; err = ndata->o->sendto(ndata->myiod, sg, sglen, count, 0, addr); if (free_addr) gensio_addr_free(addr); return err; } static void udpn_finish_close(struct udpna_data *nadata, struct udpn_data *ndata) { if (ndata->in_read || ndata->in_write || ndata->in_open_cb) return; udpn_set_state(ndata, UDPN_CLOSED); if (ndata->close_done) { void (*close_done)(struct gensio *io, void *close_data) = ndata->close_done; void *close_data = ndata->close_data; ndata->close_done = NULL; ndata->in_close_cb = true; udpna_unlock(nadata); close_done(ndata->io, close_data); udpna_lock(nadata); ndata->in_close_cb = false; } if (nadata->pending_data_owner == ndata) { nadata->pending_data_owner = NULL; nadata->data_pending_len = 0; } if (ndata->freed && !ndata->deferred_op_pending) udpn_finish_free(ndata); } static void udpn_finish_read(struct udpn_data *ndata) { struct udpna_data *nadata = ndata->nadata; struct gensio *io = ndata->io; gensiods count; char raddrdata[200]; char daddrdata[200]; char ifidx[20]; unsigned int auxi = 0; const char *auxmem[4] = { NULL, NULL, NULL, NULL }; const char *const *auxdata = NULL; int err; gensiods pos; retry: udpna_unlock(nadata); count = nadata->data_pending_len; strcpy(raddrdata, "addr:"); pos = 5; err = gensio_addr_to_str(nadata->curr_recvaddr, raddrdata, &pos, sizeof(raddrdata)); if (err) { strcpy(raddrdata, "err:addr:"); strncpy(raddrdata + 9, gensio_err_to_str(err), sizeof(raddrdata) - 9); raddrdata[sizeof(raddrdata) - 1] = '\0'; auxmem[auxi++] = raddrdata; } else if (strcmp(raddrdata, "addr:unix,") == 0) { /* * We get this if the other end is a unix datagram socket that * is not bound to an address. Deliver it with no address. */ } else { /* It's a good address. */ auxmem[auxi++] = raddrdata; } if (ndata->extrainfo) { /* Get the ifidx */ if (gensio_addr_next(nadata->curr_recvaddr)) { pos = 0; err = gensio_addr_to_str(nadata->curr_recvaddr, ifidx, &pos, sizeof(ifidx)); if (!err) auxmem[auxi++] = ifidx; } /* Get the destination address */ if (gensio_addr_next(nadata->curr_recvaddr)) { strncpy(daddrdata, "daddr:", sizeof(daddrdata)); pos = 6; err = gensio_addr_to_str(nadata->curr_recvaddr, daddrdata, &pos, sizeof(daddrdata)); if (!err) { /* Chop off the ,0 at the end. */ pos -= 2; if (daddrdata[pos] == ',' && daddrdata[pos + 1] == '0') daddrdata[pos] = '\0'; auxmem[auxi++] = daddrdata; } } } if (auxi > 0) auxdata = auxmem; err = gensio_cb(io, GENSIO_EVENT_READ, 0, nadata->read_data, &count, auxdata); udpna_lock(nadata); if (err) goto out; if (ndata->state == UDPN_IN_CLOSE) { udpn_finish_close(nadata, ndata); goto out; } if (count < nadata->data_pending_len) { /* The user didn't comsume all the data */ nadata->data_pending_len -= count; nadata->data_pos += count; if (ndata->state == UDPN_OPEN && ndata->read_enabled) goto retry; } else { nadata->pending_data_owner = NULL; nadata->data_pending_len = 0; } out: ndata->in_read = false; udpna_check_read_state(nadata); } static void udpna_deferred_op(struct gensio_runner *runner, void *cbdata) { struct udpna_data *nadata = cbdata; udpna_lock(nadata); nadata->deferred_op_pending = false; if (nadata->pending_data_owner) { struct udpn_data *ndata = nadata->pending_data_owner; if (ndata->deferred_read) { ndata->deferred_read = false; if (ndata->read_enabled) { udpn_finish_read(ndata); } else { /* We started to read, but didn't get to do it. */ ndata->in_read = false; } } } if (nadata->in_shutdown && !nadata->in_new_connection) { struct gensio_accepter *accepter = nadata->acc; nadata->in_shutdown = false; if (nadata->shutdown_done) { udpna_unlock(nadata); nadata->shutdown_done(accepter, nadata->shutdown_data); udpna_lock(nadata); } udpna_check_finish_free(nadata); } if (!nadata->freed || !nadata->closed) udpna_check_read_state(nadata); udpna_deref_and_unlock(nadata); } static void udpn_deferred_op(struct gensio_runner *runner, void *cbdata) { struct udpn_data *ndata = cbdata; struct udpna_data *nadata = ndata->nadata; udpna_lock(nadata); ndata->deferred_op_pending = false; if (ndata->state == UDPN_IN_OPEN) { udpn_set_state(ndata, UDPN_OPEN); if (ndata->open_done) { ndata->in_open_cb = true; udpna_unlock(nadata); ndata->open_done(ndata->io, 0, ndata->open_data); udpna_lock(nadata); ndata->in_open_cb = false; } udpna_check_read_state(nadata); } if (ndata->state == UDPN_IN_CLOSE) udpn_finish_close(nadata, ndata); else if (ndata->freed && !ndata->in_close_cb && !nadata->deferred_op_pending) udpn_finish_free(ndata); udpna_deref_and_unlock(nadata); } static void udpn_start_deferred_op(struct udpn_data *ndata) { if (!ndata->deferred_op_pending) { udpna_ref(ndata->nadata); ndata->deferred_op_pending = true; ndata->o->run(ndata->deferred_op_runner); } } static int udpn_open(struct gensio *io, gensio_done_err open_done, void *open_data) { struct udpn_data *ndata = gensio_get_gensio_data(io); struct udpna_data *nadata = ndata->nadata; int err = GE_INUSE; udpna_lock(nadata); if (!gensio_is_client(ndata->io)) { err = GE_NOTSUP; } else if (ndata->state == UDPN_CLOSED) { udpn_remove_from_list(&nadata->closed_udpns, ndata); udpn_add_to_list(&nadata->udpns, ndata); udpna_fd_read_disable(nadata); udpn_set_state(ndata, UDPN_IN_OPEN); ndata->open_done = open_done; ndata->open_data = open_data; udpn_start_deferred_op(ndata); err = 0; } udpna_unlock(nadata); return err; } static void udpn_start_close(struct udpn_data *ndata, gensio_done close_done, void *close_data) { struct udpna_data *nadata = ndata->nadata; if (nadata->pending_data_owner == ndata) { if (ndata->deferred_read) { /* * If there is a read pending on a deferred op, it won't * get called now that this is closed. So cancel it so * the close will finish */ ndata->deferred_read = false; ndata->in_read = false; } nadata->pending_data_owner = NULL; nadata->data_pending_len = 0; } ndata->close_done = close_done; ndata->close_data = close_data; if (ndata->read_enabled) ndata->read_enabled = false; else udpna_fd_read_enable(nadata); if (ndata->write_enabled) { ndata->write_enabled = false; udpna_fd_write_disable(nadata); } udpn_remove_from_list(&nadata->udpns, ndata); udpn_add_to_list(&nadata->closed_udpns, ndata); udpn_set_state(ndata, UDPN_IN_CLOSE); udpn_start_deferred_op(ndata); } static bool udpn_is_closed(struct udpn_data *ndata) { return (ndata->state == UDPN_CLOSED || ndata->state == UDPN_IN_CLOSE); } static int udpn_close(struct gensio *io, gensio_done close_done, void *close_data) { struct udpn_data *ndata = gensio_get_gensio_data(io); struct udpna_data *nadata = ndata->nadata; int err = GE_INUSE; udpna_lock(nadata); if (!udpn_is_closed(ndata)) { udpn_start_close(ndata, close_done, close_data); err = 0; } udpna_unlock(nadata); return err; } static void udpn_free(struct gensio *io) { struct udpn_data *ndata = gensio_get_gensio_data(io); struct udpna_data *nadata = ndata->nadata; udpna_lock_and_ref(nadata); ndata->freed = true; if (ndata->state == UDPN_IN_CLOSE) ndata->close_done = NULL; else if (ndata->state != UDPN_CLOSED) udpn_start_close(ndata, NULL, NULL); else if (!ndata->in_close_cb && !ndata->deferred_op_pending) udpn_finish_free(ndata); udpna_deref_and_unlock(nadata); } static void udpn_set_read_callback_enable(struct gensio *io, bool enabled) { struct udpn_data *ndata = gensio_get_gensio_data(io); struct udpna_data *nadata = ndata->nadata; bool my_data_pending; udpna_lock(nadata); if (udpn_is_closed(ndata) || ndata->read_enabled == enabled) goto out_unlock; if (enabled) { assert(nadata->read_disable_count > 0); nadata->read_disable_count--; i_udp_add_trace(nadata, NULL, 5300 + nadata->read_disable_count, __LINE__); } else { nadata->read_disable_count++; i_udp_add_trace(nadata, NULL, 5400 + nadata->read_disable_count, __LINE__); } ndata->read_enabled = enabled; my_data_pending = (nadata->data_pending_len && nadata->pending_data_owner == ndata); if (ndata->in_read || ndata->state == UDPN_IN_OPEN || (my_data_pending && !enabled)) { /* Nothing to do. */ } else if (enabled && my_data_pending) { ndata->in_read = true; ndata->deferred_read = true; /* Call the read from the selector to avoid lock nesting issues. */ udpna_start_deferred_op(nadata); } else { udpna_check_read_state(nadata); } out_unlock: udpna_unlock(nadata); } static void udpn_set_write_callback_enable(struct gensio *io, bool enabled) { struct udpn_data *ndata = gensio_get_gensio_data(io); struct udpna_data *nadata = ndata->nadata; udpna_lock(nadata); if (udpn_is_closed(ndata)) goto out_unlock; if (ndata->write_enabled != enabled) { ndata->write_enabled = enabled; if (ndata->state == UDPN_IN_OPEN) goto out_unlock; if (enabled) udpna_fd_write_enable(ndata->nadata); else udpna_fd_write_disable(ndata->nadata); } out_unlock: udpna_unlock(nadata); } static void udpn_disable(struct gensio *io) { struct udpn_data *ndata = gensio_get_gensio_data(io); struct udpna_data *nadata = ndata->nadata; if (ndata->read_enabled) { udpna_fd_read_disable(nadata); ndata->read_enabled = false; } if (ndata->write_enabled) { udpna_fd_write_disable(nadata); ndata->write_enabled = false; } ndata->close_done = NULL; udpn_remove_from_list(&nadata->udpns, ndata); udpn_add_to_list(&nadata->closed_udpns, ndata); udpn_set_state(ndata, UDPN_CLOSED); nadata->disabled = true; } static void udpn_handle_write_incoming(struct udpna_data *nadata, struct udpn_data *ndata) { struct gensio *io = ndata->io; int err; if (ndata->in_write) { /* Only one write callback at a time. */ ndata->write_pending = true; return; } ndata->in_write = true; retry: udpna_unlock(nadata); err = gensio_cb(io, GENSIO_EVENT_WRITE_READY, 0, NULL, NULL, NULL); udpna_lock(nadata); if (err) goto out; if (ndata->write_pending) { /* Another write came in while we were unlocked. Retry. */ ndata->write_pending = false; if (ndata->write_enabled) goto retry; } out: ndata->in_write = false; if (ndata->state == UDPN_IN_CLOSE) udpn_finish_close(nadata, ndata); } static void udpna_writehandler(struct gensio_iod *iod, void *cbdata) { struct udpna_data *nadata = cbdata; struct gensio_link *l; udpna_lock_and_ref(nadata); if (nadata->in_write) { udpna_disable_write(nadata); goto out_unlock; } gensio_list_for_each(&nadata->udpns, l) { struct udpn_data *ndata = gensio_link_to_ndata(l); if (ndata->write_enabled) { udpn_handle_write_incoming(nadata, ndata); /* * Only handle one per callback, the above call releases * the lock and can result in the list changing. */ break; } } if (nadata->write_enable_count > 0) udpna_enable_write(nadata); out_unlock: udpna_deref_and_unlock(nadata); } static int udpna_control_laddr(struct udpna_data *nadata, bool get, char *data, gensiods *datalen) { unsigned int i; struct gensio_addr *addr; gensiods pos = 0; int rv; if (!get) return GE_NOTSUP; if (!nadata->fds) return GE_NOTREADY; i = strtoul(data, NULL, 0); if (i >= nadata->nr_fds) return GE_NOTFOUND; rv = nadata->o->sock_control(nadata->fds[i].iod, GENSIO_SOCKCTL_GET_SOCKNAME, &addr, NULL); if (rv) return rv; rv = gensio_addr_to_str(addr, data, &pos, *datalen); gensio_addr_free(addr); if (rv) return rv; *datalen = pos; return 0; } static int udpna_control_raddr(struct udpn_data *ndata, bool get, char *data, gensiods *datalen) { unsigned int i; gensiods pos = 0; int rv; if (!get) return GE_NOTSUP; i = strtoul(data, NULL, 0); if (i > 0) return GE_NOTFOUND; rv = gensio_addr_to_str(ndata->raddr, data, &pos, *datalen); if (rv) return rv; *datalen = pos; return 0; } static int udpna_control_lport(struct udpna_data *nadata, bool get, char *data, gensiods *datalen) { int rv; unsigned int i; gensiods size; if (!get) return GE_NOTSUP; if (!nadata->fds) return GE_NOTREADY; i = strtoul(data, NULL, 0); if (i >= nadata->nr_fds) return GE_NOTFOUND; size = sizeof(unsigned int); rv = nadata->o->sock_control(nadata->fds[i].iod, GENSIO_SOCKCTL_GET_PORT, &i, &size); if (rv) return rv; *datalen = snprintf(data, *datalen, "%d", i); return 0; } static int udpn_control(struct gensio *io, bool get, int option, char *data, gensiods *datalen) { struct udpn_data *ndata = gensio_get_gensio_data(io); struct udpna_data *nadata = ndata->nadata; struct gensio_os_funcs *o = nadata->o; gensiods size; int err; switch(option) { case GENSIO_CONTROL_MAX_WRITE_PACKET: if (!get) return GE_NOTSUP; /* * This is the maximum size for a normal IPv4 UDP packet (per * wikipedia). IPv6 jumbo packets can go larger, but this should * be safe to advertise. */ *datalen = snprintf(data, *datalen, "%d", 65507); break; case GENSIO_CONTROL_LADDR: return udpna_control_laddr(nadata, get, data, datalen); case GENSIO_CONTROL_RADDR: return udpna_control_raddr(ndata, get, data, datalen); case GENSIO_CONTROL_RADDR_BIN: if (!get) return GE_NOTSUP; gensio_addr_getaddr(ndata->raddr, data, datalen); break; case GENSIO_CONTROL_LPORT: if (nadata->protocol != GENSIO_NET_PROTOCOL_UDP) return GE_NOTSUP; return udpna_control_lport(nadata, get, data, datalen); case GENSIO_CONTROL_ADD_MCAST: case GENSIO_CONTROL_DEL_MCAST: { struct gensio_addr *addr; if (nadata->protocol != GENSIO_NET_PROTOCOL_UDP) return GE_NOTSUP; err = gensio_scan_network_addr(nadata->o, data, GENSIO_NET_PROTOCOL_UDP, &addr); if (err) return err; if (option == GENSIO_CONTROL_ADD_MCAST) err = nadata->o->mcast_add(nadata->fds->iod, addr, 0, false); else err = nadata->o->mcast_del(nadata->fds->iod, addr, 0, false); gensio_addr_free(addr); return err; } case GENSIO_CONTROL_MCAST_LOOP: { bool mcast_loop; gensiods size = sizeof(mcast_loop); struct gensio_iod *iod = nadata->fds->iod; if (nadata->protocol != GENSIO_NET_PROTOCOL_UDP) return GE_NOTSUP; if (get) { err = o->sock_control(iod, GENSIO_SOCKCTL_GET_MCAST_LOOP, &mcast_loop, &size); if (err) return err; if (mcast_loop) *datalen = snprintf(data, *datalen, "true"); else *datalen = snprintf(data, *datalen, "false"); } else { if (strncasecmp(data, "true", *datalen)) mcast_loop = true; else if (strncasecmp(data, "false", *datalen)) mcast_loop = false; else return GE_INVAL; return o->sock_control(iod, GENSIO_SOCKCTL_SET_MCAST_LOOP, &mcast_loop, &size); } break; } case GENSIO_CONTROL_MCAST_TTL: { unsigned int ttl; gensiods size = sizeof(ttl); struct gensio_iod *iod = nadata->fds->iod; if (nadata->protocol != GENSIO_NET_PROTOCOL_UDP) return GE_NOTSUP; if (get) { err = o->sock_control(iod, GENSIO_SOCKCTL_SET_MCAST_TTL, &ttl, &size); if (err) return err; *datalen = snprintf(data, *datalen, "%u", ttl); } else { ttl = strtoul(data, NULL, 0); return o->sock_control(iod, GENSIO_SOCKCTL_SET_MCAST_TTL, &ttl, &size); } break; } case GENSIO_CONTROL_EXTRAINFO: { int val; gensiods size = sizeof(val); struct gensio_iod *iod = nadata->fds->iod; if (get) { err = o->sock_control(iod, GENSIO_SOCKCTL_GET_EXTRAINFO, &val, &size); if (err) return err; *datalen = snprintf(data, *datalen, "%u", val); } else { val = !!strtoul(data, NULL, 0); udpna_lock(nadata); if (ndata->extrainfo != val) { if ((val && nadata->extrainfo == 0) || (!val && nadata->extrainfo == 1)) { err = o->sock_control(iod, GENSIO_SOCKCTL_SET_EXTRAINFO, &val, &size); if (err) return err; ndata->extrainfo = val; if (val) nadata->extrainfo++; else nadata->extrainfo--; } } udpna_unlock(nadata); } break; } case GENSIO_CONTROL_DRAIN_COUNT: { struct gensio_iod *iod = nadata->fds->iod; if (!get) return GE_NOTSUP; err = o->bufcount(iod, GENSIO_OUT_BUF, &size); if (err) return err; *datalen = snprintf(data, *datalen, "%lu", (unsigned long) size); return 0; default: return GE_NOTSUP; } } return 0; } static int gensio_udp_func(struct gensio *io, int func, gensiods *count, const void *cbuf, gensiods buflen, void *buf, const char *const *auxdata) { switch (func) { case GENSIO_FUNC_WRITE_SG: return udpn_write(io, count, cbuf, buflen, auxdata); case GENSIO_FUNC_OPEN: return udpn_open(io, (void *) cbuf, buf); case GENSIO_FUNC_CLOSE: return udpn_close(io, (void *) cbuf, buf); case GENSIO_FUNC_FREE: udpn_free(io); return 0; case GENSIO_FUNC_SET_READ_CALLBACK: udpn_set_read_callback_enable(io, buflen); return 0; case GENSIO_FUNC_SET_WRITE_CALLBACK: udpn_set_write_callback_enable(io, buflen); return 0; case GENSIO_FUNC_DISABLE: udpn_disable(io); return 0; case GENSIO_FUNC_CONTROL: return udpn_control(io, *((bool *) cbuf), buflen, buf, count); default: return GE_NOTSUP; } } static struct udpn_data * udp_alloc_gensio(struct udpna_data *nadata, struct gensio_iod *iod, const struct gensio_addr *addr, gensio_event cb, void *user_data, struct gensio_list *starting_list) { struct udpn_data *ndata = nadata->o->zalloc(nadata->o, sizeof(*ndata)); if (!ndata) return NULL; ndata->o = nadata->o; ndata->nadata = nadata; ndata->deferred_op_runner = ndata->o->alloc_runner(ndata->o, udpn_deferred_op, ndata); if (!ndata->deferred_op_runner) { nadata->o->free(nadata->o, ndata); return NULL; } ndata->raddr = gensio_addr_dup(addr); if (!ndata->raddr) { ndata->o->free_runner(ndata->deferred_op_runner); nadata->o->free(nadata->o, ndata); return NULL; } ndata->io = gensio_data_alloc(nadata->o, cb, user_data, gensio_udp_func, NULL, nadata->typestr, ndata); if (!ndata->io) { gensio_addr_free(ndata->raddr); ndata->o->free_runner(ndata->deferred_op_runner); nadata->o->free(nadata->o, ndata); return NULL; } gensio_set_is_packet(ndata->io, true); ndata->myiod = iod; /* Stick it on the end of the list. */ udpn_add_to_list(starting_list, ndata); nadata->udpn_count++; return ndata; } static void udpna_readhandler(struct gensio_iod *iod, void *cbdata) { struct udpna_data *nadata = cbdata; struct udpn_data *ndata; gensiods datalen; int err; udpna_lock_and_ref(nadata); if (nadata->data_pending_len) { nadata->readhandler_read_disabled = true; udpna_fd_read_disable(nadata); goto out_unlock; } err = nadata->o->recvfrom(iod, nadata->read_data, nadata->max_read_size, &datalen, 0, nadata->curr_recvaddr); if (err) { if (!nadata->is_dummy) /* Don't log on dummy accepters. */ gensio_acc_log(nadata->acc, GENSIO_LOG_ERR, "Could not accept on UDP: %s", gensio_err_to_str(err)); goto out_unlock; } if (datalen == 0) goto out_unlock; nadata->data_pending_len = datalen; nadata->data_pos = 0; if (nadata->nocon) { if (gensio_list_empty(&nadata->udpns)) { ndata = NULL; } else { ndata = gensio_link_to_ndata(gensio_list_first(&nadata->udpns)); } } else { ndata = udpn_find(&nadata->udpns, nadata->curr_recvaddr); } if (ndata) { /* Data belongs to an existing connection. */ nadata->pending_data_owner = ndata; goto got_ndata; } if (nadata->closed || !nadata->enabled) { nadata->data_pending_len = 0; goto out_unlock_enable; } /* New connection. */ ndata = udp_alloc_gensio(nadata, iod, nadata->curr_recvaddr, NULL, NULL, &nadata->udpns); if (!ndata) goto out_nomem; udpn_set_state(ndata, UDPN_OPEN); nadata->read_disable_count++; i_udp_add_trace(nadata, NULL, 5500 + nadata->read_disable_count, __LINE__); nadata->pending_data_owner = ndata; nadata->in_new_connection = true; ndata->in_read = true; udpna_unlock(nadata); gensio_acc_cb(nadata->acc, GENSIO_ACC_EVENT_NEW_CONNECTION, ndata->io); udpna_lock(nadata); ndata->in_read = false; while (nadata->enable_done) { gensio_acc_done enable_done = nadata->enable_done; void *enable_done_data = nadata->enable_done_data; nadata->enable_done = NULL; udpna_unlock(nadata); enable_done(nadata->acc, enable_done_data); udpna_lock(nadata); } nadata->in_new_connection = false; if (ndata->state == UDPN_OPEN) { got_ndata: if (ndata->read_enabled && !ndata->in_read) { ndata->in_read = true; udpn_finish_read(ndata); } } else { nadata->data_pending_len = 0; } if (ndata->state == UDPN_IN_CLOSE) { udpn_finish_close(nadata, ndata); goto out_unlock_enable; } if (nadata->in_shutdown) { struct gensio_accepter *accepter = nadata->acc; nadata->in_shutdown = false; ndata->in_read = true; udpna_unlock(nadata); if (nadata->shutdown_done) nadata->shutdown_done(accepter, nadata->shutdown_data); udpna_lock(nadata); ndata->in_read = false; } udpna_check_finish_free(nadata); goto out_unlock_enable; out_nomem: nadata->data_pending_len = 0; gensio_acc_log(nadata->acc, GENSIO_LOG_ERR, "Out of memory allocating for udp port"); out_unlock_enable: if (nadata->readhandler_read_disabled) { nadata->readhandler_read_disabled = false; udpna_fd_read_enable(nadata); } out_unlock: udpna_deref_and_unlock(nadata); } #if HAVE_UNIX /* Duplicated in gensio_net.c, along with the next function */ static int netna_setup_unix_perms(struct gensio_os_funcs *o, struct gensio_addr *addr, bool mode_set, int mode, const char *owner, const char *group) { /* uid_t can be unsigned, do a cast to avoid warnings. */ #define GENSIO_UID_INVALID_VAL ((uid_t) -1) char pwbuf[16384]; uid_t ownerid = GENSIO_UID_INVALID_VAL; uid_t groupid = GENSIO_UID_INVALID_VAL; int err; char unpath[MAX_UNIX_ADDR_PATH]; get_unix_addr_path(addr, unpath); /* Set up perms for Unix domain sockets. */ if (mode_set) { err = chmod(unpath, mode); if (err) goto out_errno; } if (owner) { struct passwd pwdbuf, *pwd; err = getpwnam_r(owner, &pwdbuf, pwbuf, sizeof(pwbuf), &pwd); if (err) goto out_errno; if (!pwd) { err = ENOENT; goto out_err; } ownerid = pwd->pw_uid; } if (group) { struct group grpbuf, *grp; err = getgrnam_r(group, &grpbuf, pwbuf, sizeof(pwbuf), &grp); if (err) goto out_errno; if (!grp) { err = ENOENT; goto out_err; } groupid = grp->gr_gid; } if (ownerid != GENSIO_UID_INVALID_VAL || groupid != GENSIO_UID_INVALID_VAL) { err = chown(unpath, ownerid, groupid); if (err) goto out_errno; } return 0; out_errno: err = errno; out_err: return gensio_os_err_to_err(o, err); } #endif static int netna_b4_listen(struct gensio_iod *iod, void *data) { struct udpna_data *nadata = data; if (nadata->protocol == GENSIO_NET_PROTOCOL_UDP) return 0; #if HAVE_UNIX return netna_setup_unix_perms(nadata->o, nadata->ai, nadata->mode_set, nadata->mode, nadata->owner, nadata->group); #else return GE_NOTSUP; #endif } static int udpna_startup(struct gensio_accepter *accepter) { struct udpna_data *nadata = gensio_acc_get_gensio_data(accepter); int rv = 0; udpna_lock(nadata); if (!nadata->fds) { rv = gensio_os_open_listen_sockets(nadata->o, nadata->ai, udpna_readhandler, udpna_writehandler, udpna_fd_cleared, netna_b4_listen, nadata, nadata->opensock_flags, &nadata->fds, &nadata->nr_fds); if (rv) goto out_unlock; } nadata->enabled = true; udpna_enable_read(nadata); out_unlock: udpna_unlock(nadata); return rv; } static int udpna_shutdown(struct gensio_accepter *accepter, gensio_acc_done shutdown_done, void *shutdown_data) { struct udpna_data *nadata = gensio_acc_get_gensio_data(accepter); int rv = 0; udpna_lock(nadata); if (!nadata->in_shutdown && !nadata->closed) { nadata->enabled = false; nadata->in_shutdown = true; nadata->closed = true; nadata->shutdown_done = shutdown_done; nadata->shutdown_data = shutdown_data; if (!nadata->in_new_connection) udpna_start_deferred_op(nadata); } else { rv = GE_NOTREADY; } udpna_unlock(nadata); return rv; } static void udpna_enable_op(struct gensio_runner *runner, void *cb_data) { struct udpna_data *nadata = cb_data; udpna_lock(nadata); if (nadata->enable_done) { gensio_acc_done done = nadata->enable_done; void *done_data = nadata->enable_done_data; nadata->enable_done = NULL; udpna_unlock(nadata); done(nadata->acc, done_data); udpna_lock(nadata); } udpna_deref_and_unlock(nadata); } static int udpna_set_accept_callback_enable(struct gensio_accepter *accepter, bool enabled, gensio_acc_done done, void *done_data) { struct udpna_data *nadata = gensio_acc_get_gensio_data(accepter); int rv = 0; udpna_lock(nadata); if (nadata->enable_done) { rv = GE_INUSE; } else { nadata->enabled = enabled; nadata->enable_done = done; nadata->enable_done_data = done_data; if (!nadata->in_new_connection) { udpna_ref(nadata); nadata->o->run(nadata->enable_done_runner); } } udpna_unlock(nadata); return rv; } static void udpna_free(struct gensio_accepter *accepter) { struct udpna_data *nadata = gensio_acc_get_gensio_data(accepter); udpna_lock_and_ref(nadata); assert(!nadata->freed); nadata->enabled = false; nadata->closed = true; nadata->freed = true; if (!nadata->disabled) { udpna_check_finish_free(nadata); } else { if (nadata->udpn_count == 0) { unsigned int i; for (i = 0; i < nadata->nr_fds; i++) { if (nadata->fds[i].iod) nadata->o->clear_fd_handlers_norpt(nadata->fds[i].iod); } for (i = 0; i < nadata->nr_fds; i++) { if (nadata->fds[i].iod) nadata->o->close(&nadata->fds[i].iod); } } } udpna_deref_and_unlock(nadata); } static void udpna_disable(struct gensio_accepter *accepter) { struct udpna_data *nadata = gensio_acc_get_gensio_data(accepter); nadata->enabled = false; nadata->in_shutdown = false; nadata->shutdown_done = NULL; nadata->disabled = true; } static int udpna_str_to_gensio(struct gensio_accepter *accepter, const char *addrstr, gensio_event cb, void *user_data, struct gensio **new_net) { struct udpna_data *nadata = gensio_acc_get_gensio_data(accepter); struct udpn_data *ndata = NULL; struct gensio_addr *addr = NULL; unsigned int fdi; int err; const char **iargs; bool is_port_set; int protocol = 0; err = gensio_scan_network_port(nadata->o, addrstr, false, &addr, &protocol, &is_port_set, NULL, &iargs); if (err) return err; err = GE_INVAL; if (protocol != nadata->protocol) goto out_err; if (protocol == GENSIO_NET_PROTOCOL_UDP && !is_port_set) /* Don't accept any args, we can't set the readbuf size here. */ if (iargs && iargs[0]) goto out_err; /* Use the first address with the same family. */ for (fdi = 0; fdi < nadata->nr_fds; fdi++) { if (gensio_addr_family_supports(addr, nadata->fds[fdi].family, nadata->fds[fdi].flags)) goto found; } goto out_err; found: udpna_lock(nadata); ndata = udpn_find(&nadata->udpns, addr); if (!ndata) ndata = udpn_find(&nadata->closed_udpns, addr); if (ndata) { udpna_unlock(nadata); err = GE_EXISTS; goto out_err; } ndata = udp_alloc_gensio(nadata, nadata->fds[fdi].iod, addr, cb, user_data, &nadata->closed_udpns); if (!ndata) { udpna_unlock(nadata); err = GE_NOMEM; goto out_err; } gensio_set_is_client(ndata->io, true); udpn_start_deferred_op(ndata); udpna_unlock(nadata); *new_net = ndata->io; err = 0; out_err: if (addr) gensio_addr_free(addr); if (iargs) gensio_argv_free(nadata->o, iargs); return err; } static int udpna_control(struct gensio_accepter *acc, bool get, unsigned int option, char *data, gensiods *datalen) { struct udpna_data *nadata = gensio_acc_get_gensio_data(acc); switch (option) { case GENSIO_ACC_CONTROL_LADDR: return udpna_control_laddr(nadata, get, data, datalen); case GENSIO_ACC_CONTROL_LPORT: return udpna_control_lport(nadata, get, data, datalen); default: return GE_NOTSUP; } } static int gensio_acc_udp_func(struct gensio_accepter *acc, int func, int val, const char *addr, void *done, void *data, const void *data2, void *ret) { switch (func) { case GENSIO_ACC_FUNC_STARTUP: return udpna_startup(acc); case GENSIO_ACC_FUNC_SHUTDOWN: return udpna_shutdown(acc, done, data); case GENSIO_ACC_FUNC_SET_ACCEPT_CALLBACK: return udpna_set_accept_callback_enable(acc, val, done, data); case GENSIO_ACC_FUNC_FREE: udpna_free(acc); return 0; case GENSIO_ACC_FUNC_STR_TO_GENSIO: return udpna_str_to_gensio(acc, addr, done, data, ret); case GENSIO_ACC_FUNC_DISABLE: udpna_disable(acc); return 0; case GENSIO_ACC_FUNC_CONTROL: return udpna_control(acc, (bool) val, *((unsigned int *) done), (char *) data, (gensiods *) ret); default: return GE_NOTSUP; } } struct dgram_accepter_data { int protocol; const char *typestr; bool reuseaddr; gensiods max_read_size; #if HAVE_UNIX unsigned int mode; bool mode_set; const char *owner; const char *group; #endif }; static int i_dgram_gensio_accepter_alloc(const struct gensio_addr *iai, struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct dgram_accepter_data *d, struct gensio_accepter **accepter) { struct udpna_data *nadata; nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) return GE_NOMEM; nadata->o = o; gensio_list_init(&nadata->udpns); gensio_list_init(&nadata->closed_udpns); nadata->refcount = 1; nadata->protocol = d->protocol; nadata->typestr = d->typestr; #if HAVE_UNIX nadata->mode = d->mode; nadata->mode_set = d->mode_set; if (d->owner) { nadata->owner = gensio_strdup(o, d->owner); if (!nadata->owner) goto out_nomem; } if (d->group) { nadata->group = gensio_strdup(o, d->group); if (!nadata->group) goto out_nomem; } #endif if (d->reuseaddr) nadata->opensock_flags |= GENSIO_OPENSOCK_REUSEADDR; if (iai) nadata->ai = gensio_addr_dup(iai); if (!nadata->ai && iai) /* Allow a null ai if it was passed in. */ goto out_nomem; nadata->read_data = o->zalloc(o, d->max_read_size); if (!nadata->read_data) goto out_nomem; nadata->deferred_op_runner = o->alloc_runner(o, udpna_deferred_op, nadata); if (!nadata->deferred_op_runner) goto out_nomem; nadata->enable_done_runner = nadata->o->alloc_runner(nadata->o, udpna_enable_op, nadata); if (!nadata->enable_done_runner) goto out_nomem; nadata->lock = o->alloc_lock(o); if (!nadata->lock) goto out_nomem; nadata->curr_recvaddr = o->addr_alloc_recvfrom(o); if (!nadata->curr_recvaddr) goto out_nomem; nadata->acc = gensio_acc_data_alloc(o, cb, user_data, gensio_acc_udp_func, NULL, d->typestr, nadata); if (!nadata->acc) goto out_nomem; gensio_acc_set_is_packet(nadata->acc, true); nadata->max_read_size = d->max_read_size; *accepter = nadata->acc; return 0; out_nomem: udpna_do_free(nadata); return GE_NOMEM; } static int dgram_gensio_accepter_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, int protocol, const char *typestr, struct gensio_accepter **accepter) { const struct gensio_addr *iai = gdata; unsigned int i; int err, ival; bool isudp = protocol == GENSIO_NET_PROTOCOL_UDP; #if HAVE_UNIX unsigned int umode = 6, gmode = 6, omode = 6, mode; #endif struct dgram_accepter_data d; GENSIO_DECLARE_PPACCEPTER(p, o, cb, typestr, user_data); memset(&d, 0, sizeof(d)); d.max_read_size = GENSIO_DEFAULT_UDP_BUF_SIZE; d.protocol = protocol; d.typestr = typestr; if (isudp) { err = gensio_get_default(o, typestr, "reuseaddr", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (err) return err; d.reuseaddr = ival; } if (!isudp) { err = gensio_get_default(o, typestr, "delsock", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (err) return err; d.reuseaddr = ival; } for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(&p, args[i], "readbuf", &d.max_read_size) > 0) continue; if (isudp && gensio_pparm_bool(&p, args[i], "reuseaddr", &d.reuseaddr) > 0) continue; #if HAVE_UNIX if (!isudp && gensio_pparm_bool(&p, args[i], "delsock", &d.reuseaddr) > 0) continue; if (!isudp && gensio_pparm_mode(&p, args[i], "umode", &umode) > 0) { d.mode_set = true; continue; } if (!isudp && gensio_pparm_mode(&p, args[i], "gmode", &gmode) > 0) { d.mode_set = true; continue; } if (!isudp && gensio_pparm_mode(&p, args[i], "omode", &omode) > 0) { d.mode_set = true; continue; } if (!isudp && gensio_pparm_perm(&p, args[i], "perm", &mode) > 0) { d.mode_set = true; umode = mode >> 6 & 7; gmode = mode >> 3 & 7; omode = mode & 7; continue; } if (!isudp && gensio_pparm_value(&p, args[i], "owner", &d.owner)) continue; if (!isudp && gensio_pparm_value(&p, args[i], "group", &d.group)) continue; #endif gensio_pparm_unknown_parm(&p, args[i]); return GE_INVAL; } #if HAVE_UNIX d.mode = umode << 6 | gmode << 3 | omode; #endif return i_dgram_gensio_accepter_alloc(iai, o, cb, user_data, &d, accepter); } static int udp_gensio_accepter_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { return dgram_gensio_accepter_alloc(gdata, args, o, cb, user_data, GENSIO_NET_PROTOCOL_UDP, "udp", acc); } static int str_to_dgram_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, int protocol, const char *typestr, struct gensio_accepter **acc) { int err; struct gensio_addr *ai; err = gensio_os_scan_netaddr(o, str, true, protocol, &ai); if (err) return err; err = dgram_gensio_accepter_alloc(ai, args, o, cb, user_data, protocol, typestr, acc); gensio_addr_free(ai); return err; } static int str_to_udp_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { return str_to_dgram_gensio_accepter(str, args, o, cb, user_data, GENSIO_NET_PROTOCOL_UDP, "udp", acc); } static int unixdgram_gensio_accepter_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { #if HAVE_UNIX const struct gensio_addr *iai = gdata; return dgram_gensio_accepter_alloc(iai, args, o, cb, user_data, GENSIO_NET_PROTOCOL_UNIX_DGRAM, "unixdgram", accepter); #else return GE_NOTSUP; #endif } static int str_to_unixdgram_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { #if HAVE_UNIX return str_to_dgram_gensio_accepter(str, args, o, cb, user_data, GENSIO_NET_PROTOCOL_UNIX_DGRAM, "unixdgram", acc); #else return GE_NOTSUP; #endif } static int dgram_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, int protocol, const char *typestr, struct gensio **new_gensio) { const struct gensio_addr *addr = gdata; struct udpn_data *ndata = NULL; struct gensio_accepter *accepter; struct udpna_data *nadata = NULL; struct gensio_addr *laddr = NULL, *mcast = NULL, *tmpaddr, *tmpaddr2; int err, ival; struct gensio_iod *new_iod = NULL; struct dgram_accepter_data d; gensiods size; unsigned int i, setup; bool nocon = false, mcast_loop_set = false, mcast_loop = true; bool isudp = protocol == GENSIO_NET_PROTOCOL_UDP; unsigned int mttl; #if HAVE_UNIX unsigned int umode = 6, gmode = 6, omode = 6, mode; #endif GENSIO_DECLARE_PPGENSIO(p, o, cb, typestr, user_data); memset(&d, 0, sizeof(d)); d.max_read_size = GENSIO_DEFAULT_UDP_BUF_SIZE; d.protocol = protocol; d.typestr = typestr; err = gensio_get_defaultaddr(o, typestr, "laddr", false, protocol, true, false, &laddr); if (err && err != GE_NOTSUP) { gensio_log(o, GENSIO_LOG_ERR, "Invalid default dgram laddr: %s", gensio_err_to_str(err)); return err; } err = gensio_get_default(o, typestr, "reuseaddr", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (err) return err; d.reuseaddr = ival; err = gensio_get_default(o, typestr, "mttl", false, GENSIO_DEFAULT_INT, NULL, &ival); if (err) return err; mttl = ival; err = GE_INVAL; for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(&p, args[i], "readbuf", &d.max_read_size) > 0) continue; tmpaddr = NULL; if (gensio_pparm_addrs(&p, args[i], "laddr", protocol, true, false, &tmpaddr) > 0) { if (laddr) gensio_addr_free(laddr); laddr = tmpaddr; continue; } if (isudp && gensio_pparm_addrs_noport(&p, args[i], "mcast", GENSIO_NET_PROTOCOL_UDP, &tmpaddr) > 0) { if (mcast) { tmpaddr2 = gensio_addr_cat(mcast, tmpaddr); if (!tmpaddr2) { err = GE_NOMEM; goto parm_err; } gensio_addr_free(mcast); gensio_addr_free(tmpaddr); mcast = tmpaddr2; } else { mcast = tmpaddr; } continue; } if (gensio_pparm_bool(&p, args[i], "nocon", &nocon) > 0) continue; if (isudp && gensio_pparm_uint(&p, args[i], "mttl", &mttl) > 0) { if (mttl < 1 || mttl > 255) { err = GE_INVAL; goto parm_err; } continue; } if (isudp && gensio_pparm_bool(&p, args[i], "mloop", &mcast_loop) > 0) { mcast_loop_set = true; continue; } if (isudp && gensio_pparm_bool(&p, args[i], "reuseaddr", &d.reuseaddr) > 0) continue; #if HAVE_UNIX if (!isudp && gensio_pparm_mode(&p, args[i], "umode", &umode) > 0) { d.mode_set = true; continue; } if (!isudp && gensio_pparm_mode(&p, args[i], "gmode", &gmode) > 0) { d.mode_set = true; continue; } if (!isudp && gensio_pparm_mode(&p, args[i], "omode", &omode) > 0) { d.mode_set = true; continue; } if (!isudp && gensio_pparm_perm(&p, args[i], "perm", &mode) > 0) { d.mode_set = true; umode = mode >> 6 & 7; gmode = mode >> 3 & 7; omode = mode & 7; continue; } if (!isudp && gensio_pparm_value(&p, args[i], "owner", &d.owner)) continue; if (!isudp && gensio_pparm_value(&p, args[i], "group", &d.group)) continue; #endif gensio_pparm_unknown_parm(&p, args[i]); parm_err: if (laddr) gensio_addr_free(laddr); if (mcast) gensio_addr_free(mcast); return err; } #if HAVE_UNIX d.mode = umode << 6 | gmode << 3 | omode; #endif err = o->socket_open(o, addr, protocol, &new_iod); if (err) goto err_cleanup; #if HAVE_UNIX if (laddr && protocol != GENSIO_NET_PROTOCOL_UDP) { err = netna_setup_unix_perms(o, laddr, d.mode_set, d.mode, d.owner, d.group); if (err) goto err_cleanup; } #endif setup = GENSIO_SET_OPENSOCK_REUSEADDR; if (d.reuseaddr) setup |= GENSIO_OPENSOCK_REUSEADDR; err = o->socket_set_setup(new_iod, setup, laddr); if (err) goto err_cleanup; if (mcast) { err = o->mcast_add(new_iod, mcast, 0, false); if (err) goto err_cleanup; gensio_addr_free(mcast); mcast = NULL; } if (mcast_loop_set) { size = sizeof(mcast_loop); err = o->sock_control(new_iod, GENSIO_SOCKCTL_SET_MCAST_LOOP, &mcast_loop, &size); if (err) goto err_cleanup; } if (mttl > 1) { size = sizeof(mttl); err = o->sock_control(new_iod, GENSIO_SOCKCTL_SET_MCAST_TTL, &mttl, &size); if (err) goto err_cleanup; } /* Allocate a dummy network accepter. */ err = i_dgram_gensio_accepter_alloc(NULL, o, NULL, NULL, &d, &accepter); if (err) goto err_cleanup; nadata = gensio_acc_get_gensio_data(accepter); nadata->is_dummy = true; nadata->nocon = nocon; nadata->laddr = laddr; laddr = NULL; nadata->fds = o->zalloc(o, sizeof(*nadata->fds)); if (!nadata->fds) { err = GE_NOMEM; goto err_cleanup; } nadata->fds->family = gensio_addr_get_nettype(addr); nadata->fds->iod = new_iod; nadata->nr_fds = 1; /* fd belongs to udpn now, updn_do_free() will close it. */ nadata->closed = true; /* Free nadata when ndata is freed. */ nadata->freed = true; ndata = udp_alloc_gensio(nadata, new_iod, addr, cb, user_data, &nadata->closed_udpns); if (!ndata) { err = GE_NOMEM; } else { gensio_set_is_client(ndata->io, true); nadata->udpn_count = 1; err = o->set_fd_handlers(new_iod, nadata, udpna_readhandler, udpna_writehandler, NULL, udpna_fd_cleared); } if (err) { if (nadata->laddr && protocol != GENSIO_NET_PROTOCOL_UDP) netna_rm_unix_socket(laddr); if (ndata) udpn_do_free(ndata); udpna_do_free(nadata); } else { *new_gensio = ndata->io; } return err; err_cleanup: if (new_iod) { o->close(&new_iod); if (laddr && protocol != GENSIO_NET_PROTOCOL_UDP) netna_rm_unix_socket(laddr); } if (laddr) gensio_addr_free(laddr); if (mcast) gensio_addr_free(mcast); if (nadata) udpna_do_free(nadata); return err; } static int str_to_dgram_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, int protocol, const char *typestr, struct gensio **new_gensio) { struct gensio_addr *addr; int err; err = gensio_os_scan_netaddr(o, str, false, protocol, &addr); if (err) return err; err = dgram_gensio_alloc(addr, args, o, cb, user_data, protocol, typestr, new_gensio); gensio_addr_free(addr); return err; } static int udp_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { return dgram_gensio_alloc(gdata, args, o, cb, user_data, GENSIO_NET_PROTOCOL_UDP, "udp", new_gensio); } static int str_to_udp_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { return str_to_dgram_gensio(str, args, o, cb, user_data, GENSIO_NET_PROTOCOL_UDP, "udp", new_gensio); } static int unixdgram_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { #if HAVE_UNIX const struct gensio_addr *iai = gdata; return dgram_gensio_alloc(iai, args, o, cb, user_data, GENSIO_NET_PROTOCOL_UNIX_DGRAM, "unixdgram", new_gensio); #else return GE_NOTSUP; #endif } static int str_to_unixdgram_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { #if HAVE_UNIX return str_to_dgram_gensio(str, args, o, cb, user_data, GENSIO_NET_PROTOCOL_UNIX_DGRAM, "unixdgram", new_gensio); #else return GE_NOTSUP; #endif } int gensio_init_dgram(struct gensio_os_funcs *o) { int rv; rv = register_gensio(o, "udp", str_to_udp_gensio, udp_gensio_alloc); if (rv) return rv; rv = register_gensio_accepter(o, "udp", str_to_udp_gensio_accepter, udp_gensio_accepter_alloc); if (rv) return rv; rv = register_gensio(o, "unixdgram", str_to_unixdgram_gensio, unixdgram_gensio_alloc); if (rv) return rv; rv = register_gensio_accepter(o, "unixdgram", str_to_unixdgram_gensio_accepter, unixdgram_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/crc.h0000664000175000017500000000505514664224267010171 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2022 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* See rfc1549 */ static const unsigned short ccitt_table[256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; static void crc16_ccitt(const unsigned char *buf, unsigned int len, uint16_t *icrc) { unsigned int i; uint16_t crc = *icrc; for (i = 0; i < len; i++) crc = (crc >> 8) ^ ccitt_table[(crc ^ buf[i]) & 0xff]; *icrc = crc; } gensio-3.0.0/lib/gensio_sound_win.h0000664000175000017500000004667114747451760013006 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2022 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include #include #include struct win_sound_format_cnv { enum gensio_sound_fmt_type gformat; WAVEFORMATEX fmt; } win_sound_fmt_cnv[] = { { .gformat = GENSIO_SOUND_FMT_DOUBLE, .fmt = { .wFormatTag = WAVE_FORMAT_IEEE_FLOAT, .wBitsPerSample = 64 }, }, { .gformat = GENSIO_SOUND_FMT_FLOAT, .fmt = { .wFormatTag = WAVE_FORMAT_IEEE_FLOAT, .wBitsPerSample = 32 }, }, { .gformat = GENSIO_SOUND_FMT_S32, .fmt = { .wFormatTag = WAVE_FORMAT_PCM, .wBitsPerSample = 32 }, }, { .gformat = GENSIO_SOUND_FMT_S24, .fmt = { .wFormatTag = WAVE_FORMAT_PCM, .wBitsPerSample = 24 }, }, { .gformat = GENSIO_SOUND_FMT_S16, .fmt = { .wFormatTag = WAVE_FORMAT_PCM, .wBitsPerSample = 16 }, }, { .gformat = GENSIO_SOUND_FMT_S8, .fmt = { .wFormatTag = WAVE_FORMAT_PCM, .wBitsPerSample = 8 }, }, { .gformat = GENSIO_SOUND_FMT_UNKNOWN } }; static int i_gensio_mres_err_to_err(struct sound_info *si, MMRESULT mres, const char *caller, const char *file, unsigned int lineno) { struct gensio_os_funcs *o = si->soundll->o; int err; char errbuf[128]; switch (mres) { case MMSYSERR_ALLOCATED: err = GE_INUSE; break; case MMSYSERR_BADDEVICEID: case MMSYSERR_NODRIVER: err = GE_COMMERR; break; case MMSYSERR_NOMEM: err = GE_NOMEM; break; default: err = GE_OSERR; break; } if (err == GE_OSERR) { errbuf[0] = '\0'; if (si->is_input) waveInGetErrorText(mres, errbuf, sizeof(errbuf)); else waveOutGetErrorText(mres, errbuf, sizeof(errbuf)); gensio_log(o, GENSIO_LOG_INFO, "Unhandled eounr error in %s:%d: %s (%d)", caller, lineno, errbuf, mres); } return err; } #define gensio_mres_err_to_err(o, mres) \ i_gensio_mres_err_to_err(o, mres, __func__, __FILE__, __LINE__) static int gensio_sound_win_get_wavefmt(enum gensio_sound_fmt_type gformat, WAVEFORMATEX *fmt) { unsigned int i; for (i = 0; win_sound_fmt_cnv[i].gformat != GENSIO_SOUND_FMT_UNKNOWN; i++) { if (gformat == win_sound_fmt_cnv[i].gformat) break; } if (gformat != win_sound_fmt_cnv[i].gformat) return GE_INVAL; *fmt = win_sound_fmt_cnv[i].fmt; return 0; } struct win_bufhdr { struct sound_info *si; unsigned int bufnum; struct win_bufhdr *next; gensiods pos; /* Position in bytes. */ gensiods len; /* Total length of the buffer. */ WAVEHDR whdr; bool in_driver; /* Is the driver handling this buffer now? */ }; struct gensio_sound_win_close_info { CRITICAL_SECTION lock; struct sound_info *si; }; struct win_sound_info { union { HWAVEIN inh; HWAVEOUT outh; }; struct gensio_sound_win_close_info *ci; /* array of si->num_bufs, each points to part of si->cnv.buf */ bool started; /* * When starting, to avoid stutter at startup, wait until two * buffers are ready to go. This holds the waiting buffer. */ struct win_bufhdr *waiting_xmit_buf; unsigned int num_bufs_in_driver; struct win_bufhdr *hdrs; /* List of buffers ready to process. */ struct win_bufhdr *head; struct win_bufhdr *tail; }; static unsigned long gensio_sound_win_drain_count(struct sound_info *si) { struct win_sound_info *w = si->pinfo; unsigned long buffers_left = 0, i; /* Count the buffers still in the driver. */ for (i = 0; i < si->num_bufs; i++) { struct win_bufhdr *hdr = &w->hdrs[i]; if (hdr->in_driver) buffers_left++; } return buffers_left * si->bufsize; } static void gensio_sound_win_api_close_dev(struct sound_info *si) { struct gensio_os_funcs *o = si->soundll->o; struct win_sound_info *w = si->pinfo; unsigned int i; if (!w) return; if (si->is_input) { if (w->inh) { if (w->started) assert(waveInReset(w->inh) == MMSYSERR_NOERROR); for (i = 0; i < si->num_bufs; i++) waveInUnprepareHeader(w->inh, &w->hdrs[i].whdr, sizeof(WAVEHDR)); assert(waveInClose(w->inh) == MMSYSERR_NOERROR); w->inh = NULL; } } else { if (w->outh) { assert(waveOutReset(w->outh) == MMSYSERR_NOERROR); for (i = 0; i < si->num_bufs; i++) waveOutUnprepareHeader(w->outh, &w->hdrs[i].whdr, sizeof(WAVEHDR)); assert(waveOutClose(w->outh) == MMSYSERR_NOERROR); w->outh = NULL; } } w->started = false; if (w->ci) { o->free(o, w->ci); w->ci = NULL; } if (w->hdrs) { o->free(o, w->hdrs); w->hdrs = NULL; } w->waiting_xmit_buf = NULL; } static void gensio_sound_win_process_read_buffer(struct sound_info *si) { struct win_sound_info *w = si->pinfo; struct win_bufhdr *hdr; WAVEHDR *whdr; const unsigned char *ibuf; unsigned char *obuf; gensiods len; if (!w->head || si->ready) return; hdr = w->head; whdr = &hdr->whdr; len = whdr->dwBytesRecorded; /* In bytes. */ ibuf = (unsigned char *) whdr->lpData; ibuf += hdr->pos; obuf = si->buf + (si->len * si->framesize); if (si->cnv.enabled) { while (len > 0 && si->len < si->bufsize) { si->cnv.convin(&ibuf, &obuf, &si->cnv); si->len++; len -= si->cnv.psize; hdr->pos += si->cnv.psize; } whdr->dwBytesRecorded = len; } else { if (len > (si->bufsize - si->len) * si->framesize) len = (si->bufsize - si->len) * si->framesize; memcpy(obuf, ibuf, len); si->len += len / si->framesize; hdr->pos += len; whdr->dwBytesRecorded -= len; } if (si->len >= si->bufsize) { si->ready = true; gensio_sound_sched_deferred_op(si->soundll); } if (whdr->dwBytesRecorded == 0) { /* Send it back to the wave input processor for more data. */ if (hdr->next) { w->head = hdr->next; } else { w->head = NULL; w->tail = NULL; } hdr->pos = 0; whdr->dwFlags = 0; hdr->in_driver = true; w->num_bufs_in_driver++; gensio_sound_ll_unlock(si->soundll); /* Like write, this will deadlock if called with the lock held. */ assert(waveInUnprepareHeader(w->inh, whdr, sizeof(WAVEHDR)) == MMSYSERR_NOERROR); assert(waveInPrepareHeader(w->inh, whdr, sizeof(WAVEHDR)) == MMSYSERR_NOERROR); assert(waveInAddBuffer(w->inh, whdr, sizeof(WAVEHDR)) == MMSYSERR_NOERROR); gensio_sound_ll_lock(si->soundll); } } static void gensio_sound_win_api_set_read(struct sound_info *si, bool enable) { if (enable) { struct win_sound_info *w = si->pinfo; if (!w->started) { waveInStart(w->inh); w->started = true; EnterCriticalSection(&w->ci->lock); w->ci->si = si; LeaveCriticalSection(&w->ci->lock); } gensio_sound_win_process_read_buffer(si); } } static void gensio_sound_win_api_set_write(struct sound_info *si, bool enable) { /* Nothing to do here. */ } static void gensio_sound_win_start_buf_xmit(struct sound_ll *soundll, struct win_sound_info *w, struct win_bufhdr *hdr) { WAVEHDR *whdr = &hdr->whdr; whdr->dwBufferLength = hdr->pos; hdr->in_driver = true; w->num_bufs_in_driver++; gensio_sound_ll_unlock(soundll); /* * If you call write while locked, you will deadlock with * the out_handler code. */ assert(waveOutUnprepareHeader(w->outh, whdr, sizeof(WAVEHDR)) == MMSYSERR_NOERROR); whdr->dwFlags = 0; assert(waveOutPrepareHeader(w->outh, whdr, sizeof(WAVEHDR)) == MMSYSERR_NOERROR); assert(waveOutWrite(w->outh, whdr, sizeof(WAVEHDR)) == MMSYSERR_NOERROR); gensio_sound_ll_lock(soundll); } static unsigned int gensio_sound_win_api_start_close(struct sound_info *si) { struct win_sound_info *w = si->pinfo; unsigned int rv = 0, i; for (i = 0; i < si->num_bufs; i++) { struct win_bufhdr *hdr = &w->hdrs[i]; /* Wait until all the headers are out of the driver. */ if (hdr->in_driver) rv++; } /* Also buffers that are waiting to send. */ if (w->waiting_xmit_buf) { struct win_bufhdr *thdr = w->waiting_xmit_buf; w->waiting_xmit_buf = NULL; gensio_sound_win_start_buf_xmit(si->soundll, w, thdr); rv++; } if (w->head && w->head->pos > 0) { struct win_bufhdr *thdr = w->head; w->head = thdr->next; if (!w->head) w->tail = NULL; gensio_sound_win_start_buf_xmit(si->soundll, w, thdr); rv++; } return rv; } static int gensio_sound_win_api_write(struct sound_info *out, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen) { struct sound_ll *soundll = out->soundll; struct win_sound_info *w = out->pinfo; struct win_bufhdr *hdr; WAVEHDR *whdr; gensiods count = 0, i, obuflen; unsigned char *obuf; if (!w->head) goto out; hdr = w->head; whdr = &hdr->whdr; obuf = (unsigned char *) whdr->lpData; obuf += hdr->pos; obuflen = hdr->len - hdr->pos; for (i = 0; i < sglen; i++) { const unsigned char *ibuf = sg[i].buf; gensiods ibuflen = sg[i].buflen, j; while (ibuflen > 0) { if (out->cnv.enabled) { j = 0; while (ibuflen > 0 && obuflen > 0) { out->cnv.convout(&ibuf, &obuf, &out->cnv); obuflen -= out->cnv.psize; ibuflen -= out->cnv.usize; hdr->pos += out->cnv.psize; j += out->cnv.usize; } } else { if (ibuflen > obuflen) j = obuflen; else j = ibuflen; memcpy(obuf, ibuf, j); ibuf += j; ibuflen -= j; obuf += j; obuflen -= j; hdr->pos += j; } count += j; if (hdr->pos == hdr->len) { /* We have a full buffer to write to the driver. */ w->head = hdr->next; if (!w->head) w->tail = NULL; if (w->waiting_xmit_buf) { struct win_bufhdr *thdr = w->waiting_xmit_buf; w->waiting_xmit_buf = NULL; gensio_sound_win_start_buf_xmit(soundll, w, thdr); } if (w->num_bufs_in_driver == 0) w->waiting_xmit_buf = hdr; else gensio_sound_win_start_buf_xmit(soundll, w, hdr); if (!w->head) { out->ready = false; goto out; } hdr = w->head; whdr = &hdr->whdr; obuf = (unsigned char *) whdr->lpData; obuf += hdr->pos; obuflen = hdr->len - hdr->pos; } } } out: if (rcount) *rcount = count; return 0; } static void gensio_sound_win_api_next_read(struct sound_info *si) { gensio_sound_win_process_read_buffer(si); } static void gensio_sound_win_close_one(struct sound_info *si) { struct sound_ll *soundll = si->soundll; soundll->nr_waiting_close--; if (soundll->nr_waiting_close == 0) { soundll->do_close_now = true; gensio_sound_sched_deferred_op(soundll); } } static void gensio_sound_win_in_handler(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { struct sound_info *si; WAVEHDR *whdr; struct win_bufhdr *hdr; struct win_sound_info *w; if (uMsg != WIM_DATA) return; whdr = (WAVEHDR *) dwParam1; hdr = (struct win_bufhdr *) whdr->dwUser; si = hdr->si; w = si->pinfo; hdr->next = NULL; gensio_sound_ll_lock(si->soundll); hdr->in_driver = false; w->num_bufs_in_driver--; if (si->soundll->state == GENSIO_SOUND_LL_IN_CLOSE) { gensio_sound_win_close_one(si); goto out; } hdr->next = NULL; if (!w->head) { w->head = hdr; w->tail = hdr; } else { w->tail->next = hdr; w->tail = hdr; } gensio_sound_win_process_read_buffer(si); out: gensio_sound_ll_unlock(si->soundll); } static void gensio_sound_win_out_handler(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { struct sound_info *si; WAVEHDR *whdr; struct win_bufhdr *hdr; struct win_sound_info *w; if (uMsg != WOM_DONE) return; whdr = (WAVEHDR *) dwParam1; hdr = (struct win_bufhdr *) whdr->dwUser; si = hdr->si; w = si->pinfo; gensio_sound_ll_lock(si->soundll); hdr->in_driver = false; w->num_bufs_in_driver--; hdr->pos = 0; hdr->next = NULL; if (!w->head) { w->head = hdr; w->tail = hdr; } else { w->tail->next = hdr; w->tail = hdr; } if (si->soundll->state == GENSIO_SOUND_LL_IN_CLOSE) { gensio_sound_win_close_one(si); } else if (!si->ready) { si->ready = true; gensio_sound_sched_deferred_op(si->soundll); } /* * If we are transmitting the last queued buffer, and there is a * partial buffer left, go ahead and send the partial buffer. */ if (w->num_bufs_in_driver == 1 && w->head && w->head->pos > 0) { struct win_bufhdr *thdr = w->head; w->head = thdr->next; if (!w->head) w->tail = NULL; gensio_sound_win_start_buf_xmit(si->soundll, w, thdr); } gensio_sound_ll_unlock(si->soundll); } static int gensio_sound_win_api_open_dev(struct sound_info *si) { struct gensio_os_funcs *o = si->soundll->o; struct win_sound_info *w = si->pinfo; WAVEFORMATEX wfx; MMRESULT mres; UINT dev, ndevs; enum gensio_sound_fmt_type pfmt; char tmpstr[100]; unsigned int i; int err; if (si->cnv.pfmt != GENSIO_SOUND_FMT_UNKNOWN) pfmt = si->cnv.pfmt; else pfmt = si->cnv.ufmt; err = gensio_sound_win_get_wavefmt(pfmt, &wfx); if (err) return err; wfx.nChannels = si->chans; wfx.nSamplesPerSec = si->samplerate; wfx.nAvgBytesPerSec = si->cnv.pframesize * si->samplerate; wfx.nBlockAlign = si->cnv.pframesize; w->ci = o->zalloc(o, sizeof(struct gensio_sound_win_close_info)); if (!w->ci) return GE_NOMEM; InitializeCriticalSection(&w->ci->lock); w->ci->si = NULL; si->cnv.buf = o->zalloc(o, (si->num_bufs * si->bufsize * si->cnv.pframesize)); if (!si->cnv.buf) { gensio_sound_win_api_close_dev(si); return GE_NOMEM; } w->hdrs = o->zalloc(o, sizeof(struct win_bufhdr) * si->num_bufs); if (!w->hdrs) { gensio_sound_win_api_close_dev(si); return GE_NOMEM; } for (i = 0; i < si->num_bufs; i++) { w->hdrs[i].si = si; w->hdrs[i].bufnum = i; w->hdrs[i].len = si->bufsize * si->cnv.pframesize; w->hdrs[i].whdr.dwBufferLength = w->hdrs[i].len; w->hdrs[i].whdr.lpData = (char *) si->cnv.buf + (w->hdrs[i].len * i); w->hdrs[i].whdr.dwUser = (DWORD_PTR) &w->hdrs[i]; } if (si->is_input) { WAVEINCAPS icaps; ndevs = waveInGetNumDevs(); for (dev = 0; dev < ndevs; dev++) { mres = waveInGetDevCaps(dev, &icaps, sizeof(icaps)); if (mres != MMSYSERR_NOERROR) continue; snprintf(tmpstr, sizeof(tmpstr), "%d:%s", dev, icaps.szPname); if (strstr(tmpstr, si->cardname)) break; } if (dev == ndevs) { gensio_sound_win_api_close_dev(si); return GE_NOTFOUND; } /* Windows does the conversion for us. */ mres = waveInOpen(&w->inh, dev, &wfx, (DWORD_PTR) gensio_sound_win_in_handler, (DWORD_PTR) w->ci, CALLBACK_FUNCTION); if (mres != MMSYSERR_NOERROR) { gensio_sound_win_api_close_dev(si); return gensio_mres_err_to_err(si, mres); } for (i = 0; i < si->num_bufs; i++) { assert(waveInPrepareHeader(w->inh, &w->hdrs[i].whdr, sizeof(WAVEHDR)) == MMSYSERR_NOERROR); assert(waveInAddBuffer(w->inh, &w->hdrs[i].whdr, sizeof(WAVEHDR)) == MMSYSERR_NOERROR); w->hdrs[i].in_driver = true; } w->num_bufs_in_driver = si->num_bufs; } else { WAVEOUTCAPS ocaps; ndevs = waveOutGetNumDevs(); for (dev = 0; dev < ndevs; dev++) { mres = waveOutGetDevCaps(dev, &ocaps, sizeof(ocaps)); if (mres != MMSYSERR_NOERROR) continue; snprintf(tmpstr, sizeof(tmpstr), "%d:%s", dev, ocaps.szPname); if (strstr(tmpstr, si->cardname)) break; } if (dev == ndevs) { gensio_sound_win_api_close_dev(si); return GE_NOTFOUND; } /* Windows does the conversion for us. */ mres = waveOutOpen(&w->outh, dev, &wfx, (DWORD_PTR) gensio_sound_win_out_handler, (DWORD_PTR) w->ci, CALLBACK_FUNCTION); if (mres != MMSYSERR_NOERROR) { gensio_sound_win_api_close_dev(si); return gensio_mres_err_to_err(si, mres); } for (i = 0; i < si->num_bufs; i++) { struct win_bufhdr *hdr = &w->hdrs[i]; hdr->in_driver = false; hdr->next = NULL; if (!w->head) { w->head = hdr; w->tail = hdr; } else { w->tail->next = hdr; w->tail = hdr; } } /* We unprepare them in the write routine. */ for (i = 0; i < si->num_bufs; i++) { assert(waveOutPrepareHeader(w->outh, &w->hdrs[i].whdr, sizeof(WAVEHDR)) == MMSYSERR_NOERROR); } w->num_bufs_in_driver = 0; si->ready = true; } return 0; } static int gensio_sound_win_api_setup(struct gensio_pparm_info *p, struct sound_info *si, struct gensio_sound_info *io) { struct gensio_os_funcs *o = si->soundll->o; si->cardname = gensio_strdup(o, io->devname); if (!si->cardname) return GE_NOMEM; si->pinfo = o->zalloc(o, sizeof(struct win_sound_info)); if (!si->pinfo) { o->free(o, si->cardname); si->cardname = NULL; return GE_NOMEM; } return 0; } static void gensio_sound_win_api_cleanup(struct sound_info *si) { struct gensio_os_funcs *o = si->soundll->o; gensio_sound_win_api_close_dev(si); if (si->pinfo) o->free(o, si->pinfo); si->pinfo = NULL; } static int gensio_sound_win_api_devices(struct gensio_os_funcs *o, char ***rnames, char ***rspecs, gensiods *rcount) { gensiods count = 0, size = 0; UINT i, ndevs; MMRESULT mres; WAVEINCAPS icaps; WAVEOUTCAPS ocaps; char **names = NULL, **specs = NULL; ndevs = waveInGetNumDevs(); for (i = 0; i < ndevs; i++) { char *name = NULL, *spec = NULL, tspec[100]; mres = waveInGetDevCaps(i, &icaps, sizeof(icaps)); if (mres != MMSYSERR_NOERROR) continue; snprintf(tspec, sizeof(tspec), "%d:%s", i, icaps.szPname); name = strdup(tspec); if (!name) goto nextin; snprintf(tspec, sizeof(tspec), "input,inchans=%d", icaps.wChannels); spec = strdup(tspec); if (!spec) goto nextin; if (count >= size) { if (extend_sound_devs(&names, &specs, &size)) { free(name); free(spec); goto out_nomem; } } names[count] = name; name = NULL; specs[count] = spec; spec = NULL; count++; nextin: if (name) free(name); if (spec) free(spec); } ndevs = waveOutGetNumDevs(); for (i = 0; i < ndevs; i++) { char *name = NULL, *spec = NULL, tspec[100]; mres = waveOutGetDevCaps(i, &ocaps, sizeof(ocaps)); if (mres != MMSYSERR_NOERROR) continue; snprintf(tspec, sizeof(tspec), "%d:%s", i, ocaps.szPname); name = strdup(tspec); if (!name) goto nextout; snprintf(tspec, sizeof(tspec), "output,outchans=%d", ocaps.wChannels); spec = strdup(tspec); if (!spec) goto nextout; if (count >= size) { if (extend_sound_devs(&names, &specs, &size)) { free(name); free(spec); goto out_nomem; } } names[count] = name; name = NULL; specs[count] = spec; spec = NULL; count++; nextout: if (name) free(name); if (spec) free(spec); } *rnames = names; *rspecs = specs; *rcount = count; return 0; out_nomem: gensio_sound_devices_free(names, specs, count); return GE_NOMEM; } static struct sound_type win_sound_type = { "win", .setup = gensio_sound_win_api_setup, .cleanup = gensio_sound_win_api_cleanup, .open_dev = gensio_sound_win_api_open_dev, .close_dev = gensio_sound_win_api_close_dev, .write = gensio_sound_win_api_write, .set_write_enable = gensio_sound_win_api_set_write, .set_read_enable = gensio_sound_win_api_set_read, .next_read = gensio_sound_win_api_next_read, .start_close = gensio_sound_win_api_start_close, .drain_count = gensio_sound_win_drain_count, .devices = gensio_sound_win_api_devices }; #define WIN_INIT &win_sound_type, gensio-3.0.0/lib/gensio_conacc.c0000664000175000017500000006725714664224267012223 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* This code creates a gensio accepter that make a gensio connection. */ #include "config.h" #include #include #include #include #include #include enum conaccn_state { CONACCN_CLOSED, CONACCN_IN_OPEN, CONACCN_OPEN, CONACCN_IN_CLOSE }; struct conaccna_data; struct conaccn_data { struct gensio_os_funcs *o; struct gensio_lock *lock; struct conaccna_data *nadata; enum conaccn_state child_state; struct gensio *io; gensio_event cb; void *user_data; struct gensio *child; bool in_close; gensio_done close_done; void *close_data; unsigned int refcount; }; enum conaccna_state { /* * Events of concern: * From the user: * startup * shutdown * cb_enable * cb_disable * Internal: * timeout * open failed * open succeeded * ndata closed * deferred op * stop timer done * * Variables of concern: * retry_timeout * enabled */ /* * Starting state, or state when shutdown completes. * * startup: * !enabled: -> CONACCNA_DISABLED * enabled: * ndata open: -> CONACCNA_READY * ndata not open: * open no error: -> CONACCNA_OPENING * open error: * retry_timeout == 0: -> return error * retry_timeout != 0: -> CONACCNA_WAITING_RETRY * * cb_enable: enabled = true * * cb_disable: enabled = false */ CONACCNA_SHUTDOWN, /* * started, but disabled * * cb_enable: * ndata open: -> CONACCNA_READY * ndata not open: * open no error: -> CONACCNA_OPENING, enabled_cb = cb * open error: * retry_timeout == 0: -> return error * retry_timeout != 0: -> CONACCNA_WAITING_RETRY * * cb_disable: do nothing * * shutdown: -> CONACCNA_IN_SHUTDOWN, start deferred op */ CONACCNA_DISABLED, /* Started, but disabled. */ /* * ndata is being opened. * * shutdown: -> CONACCNA_OPEN_SHUTDOWN * * cb_enable: do nothing * * cb_disable: -> CONACCNA_OPEN_DISABLE * * open failed: * retry_timeout == 0: -> CONACCNA_DEAD * retry_timeout != 0: -> CONACCNA_WAITING_RETRY, start timer * * open succeeded: -> CONACCNA_READY */ CONACCNA_OPENING, /* * ndata is open. * * shutdown: -> CONACC_IN_SHUTDOWN, start deferred op * * cb_enable: do nothing * * cb_disable: -> CONACC_IN_DISABLE, start deferred op * * ndata closed: * retry_timeout != 0: -> CONACCNA_WAITING_RETRY, start timer * retry_timeout == 0: * open no error: -> CONACCNA_OPENING, enabled_cb = cb * open error: start timer */ CONACCNA_READY, /* * Timer is running waiting to retry the open. * * timeout: * open no error: -> CONACCNA_OPENING * open error: -> CONACCNA_WAITING_RETRY, start timer * * shutdown: * -> CONACCNA_IN_SHUTDOWN * stop timer failed: start deferred op * stop timer succeeded: do nothing * * cb_enable: do nothing * * cb_disable: * -> CONACC_IN_DISABLE, * stop timer failed: start deferred op * stop timer succeeded: do nothing */ CONACCNA_WAITING_RETRY, /* * Got a shutdown while opening. * * open failed: -> CONACCNA_SHUTDOWN * * open succeeded: -> CONACCNA_SHUTDOWN * * cb_enable: enabled = true * * cb_disable: enabled = false */ CONACCNA_OPEN_SHUTDOWN, /* * Waiting for timer cancel or deferred op to shut down. * * cb_enable: enabled = true * * cb_disable: enabled = false * * stop timer done: -> CONACCNA_SHUTDOWN * * deferred op: -> CONACCNA_SHUTDOWN */ CONACCNA_IN_SHUTDOWN, /* * Got a disable while opening. * * shutdown: -> CONACCNA_OPEN_SHUTDOWN * * open failed: -> CONACCNA_DISABLED * * open succeeded: -> CONACCNA_DISABLED * * cb_enable: -> CONACCNA_OPENING, enabled = true * * cb_disable: do nothing */ CONACCNA_OPEN_DISABLE, /* * Currently being disabled. * * shutdown: -> CONACCNA_IN_SHUTDOWN * * cb_enable: -> CONACCNA_IN_DISABLE_RESTART, enabled = true * * cb_disable: do nothing * * (timeout, stop timer done, deferred op): -> CONACCNA_DISABLED */ CONACCNA_IN_DISABLE, /* * In disable, re-enable when disable done. * * shutdown: -> CONACCNA_IN_SHUTDOWN, start deferred op * * cb_enable: do nothing * * cb_disable: -> CONACC_IN_DISABLE, enabled = false * * (timeout, stop timer done, deferred op): * ndata open: -> CONACCNA_READY * ndata not open: * open no error: -> CONACCNA_OPENING * open error: * retry_timeout == 0: -> CONACCNA_DEAD * retry_timeout != 0: -> CONACCNA_WAITING_RETRY */ CONACCNA_IN_DISABLE_RESTART, /* * Got an error on open. * * shutdown: -> CONACCNA_IN_SHUTDOWN, start deferred op * * cb_enable: enabled = true * * cb_disable: enabled = false */ CONACCNA_DEAD /* Got an error from the start and no retry. */ }; struct conaccna_data { struct gensio_os_funcs *o; struct gensio_lock *lock; struct gensio_accepter *acc; struct conaccn_data *ndata; struct gensio_timer *retry_timer; struct gensio_time retry_time; bool deferred_op_pending; struct gensio_runner *deferred_runner; gensio_acc_done enabled_done; gensio_acc_done shutdown_done; bool enabled; /* accepter enable/disable state */ enum conaccna_state state; /* Set when an error happens to report it back to the accepter log. */ int con_err; /* Used to start the child gensio. */ char *gensio_str; unsigned int refcount; }; static void conacc_start(struct conaccna_data *nadata); static void start_retry(struct conaccna_data *nadata); static void conaccn_lock(struct conaccn_data *ndata) { ndata->o->lock(ndata->lock); } static void conaccn_unlock(struct conaccn_data *ndata) { ndata->o->unlock(ndata->lock); } static void conaccn_ref(struct conaccn_data *ndata) { assert(ndata->refcount > 0); ndata->refcount++; } static void conaccn_finish_free(struct conaccn_data *ndata) { struct gensio_os_funcs *o = ndata->o; if (ndata->io) gensio_data_free(ndata->io); if (ndata->child) gensio_free(ndata->child); if (ndata->lock) o->free_lock(ndata->lock); o->free(o, ndata); } static void conaccn_deref_and_unlock(struct conaccn_data *ndata) { assert(ndata->refcount > 0); ndata->refcount--; if (ndata->refcount == 0) { conaccn_unlock(ndata); conaccn_finish_free(ndata); } else { conaccn_unlock(ndata); } } static void conaccna_lock(struct conaccna_data *nadata) { nadata->o->lock(nadata->lock); } static void conaccna_unlock(struct conaccna_data *nadata) { nadata->o->unlock(nadata->lock); } static void conaccna_ref(struct conaccna_data *nadata) { assert(nadata->refcount > 0); nadata->refcount++; } static void conaccna_finish_free(struct conaccna_data *nadata) { struct gensio_os_funcs *o = nadata->o; if (nadata->gensio_str) o->free(o, nadata->gensio_str); if (nadata->deferred_runner) o->free_runner(nadata->deferred_runner); if (nadata->retry_timer) o->free_timer(nadata->retry_timer); if (nadata->lock) o->free_lock(nadata->lock); o->free(o, nadata); } static void conaccna_deref(struct conaccna_data *nadata) { /* Can only be called if this is not the final deref. Must hold lock. */ assert(nadata->refcount > 1); nadata->refcount--; } static void conaccna_deref_and_unlock(struct conaccna_data *nadata) { assert(nadata->refcount > 0); nadata->refcount--; if (nadata->refcount == 0) { conaccna_unlock(nadata); conaccna_finish_free(nadata); } else { conaccna_unlock(nadata); } } /* Releases the lock and re-acquires it. */ static void conaccna_call_enabled(struct conaccna_data *nadata) { gensio_acc_done done; if (nadata->enabled_done) { done = nadata->enabled_done; nadata->enabled_done = NULL; conaccna_unlock(nadata); done(nadata->acc, NULL); conaccna_lock(nadata); } } static void conaccna_finish_shutdown(struct conaccna_data *nadata) { gensio_acc_done done; conaccna_call_enabled(nadata); nadata->state = CONACCNA_SHUTDOWN; if (nadata->shutdown_done) { done = nadata->shutdown_done; nadata->shutdown_done = NULL; conaccna_unlock(nadata); done(nadata->acc, NULL); conaccna_lock(nadata); } } static void conaccna_do_deferred(struct gensio_runner *runner, void *cb_data) { struct conaccna_data *nadata = cb_data; conaccna_lock(nadata); nadata->deferred_op_pending = false; conaccna_call_enabled(nadata); switch (nadata->state) { case CONACCNA_SHUTDOWN: case CONACCNA_OPENING: case CONACCNA_READY: case CONACCNA_WAITING_RETRY: case CONACCNA_OPEN_SHUTDOWN: case CONACCNA_OPEN_DISABLE: case CONACCNA_DISABLED: break; case CONACCNA_IN_SHUTDOWN: conaccna_finish_shutdown(nadata); break; case CONACCNA_IN_DISABLE: nadata->state = CONACCNA_DISABLED; break; case CONACCNA_IN_DISABLE_RESTART: conacc_start(nadata); break; case CONACCNA_DEAD: if (nadata->con_err) { int err = nadata->con_err; nadata->con_err = 0; conaccna_unlock(nadata); gensio_acc_log(nadata->acc, GENSIO_LOG_ERR, "Error opening gensio: %s", gensio_err_to_str(err)); conaccna_lock(nadata); } break; } conaccna_deref_and_unlock(nadata); } static void conaccna_deferred_op(struct conaccna_data *nadata) { if (!nadata->deferred_op_pending) { nadata->deferred_op_pending = true; conaccna_ref(nadata); nadata->o->run(nadata->deferred_runner); } } static void conaccn_finish_close(struct conaccn_data *ndata) { struct conaccna_data *nadata = ndata->nadata; ndata->child_state = CONACCN_CLOSED; if (nadata) { conaccna_lock(nadata); nadata->ndata = NULL; switch (nadata->state) { case CONACCNA_SHUTDOWN: case CONACCNA_DISABLED: case CONACCNA_OPENING: case CONACCNA_WAITING_RETRY: case CONACCNA_OPEN_SHUTDOWN: case CONACCNA_IN_SHUTDOWN: case CONACCNA_OPEN_DISABLE: case CONACCNA_IN_DISABLE: case CONACCNA_IN_DISABLE_RESTART: case CONACCNA_DEAD: break; case CONACCNA_READY: if (!gensio_time_is_zero(nadata->retry_time)) start_retry(nadata); else conacc_start(nadata); } conaccna_deref_and_unlock(nadata); } } static void conaccn_close_done(struct gensio *child_io, void *close_cb_data) { struct conaccn_data *ndata = close_cb_data; gensio_done close_done; void *close_data; conaccn_lock(ndata); close_done = ndata->close_done; close_data = ndata->close_data; ndata->close_done = NULL; conaccn_unlock(ndata); if (close_done) close_done(ndata->io, close_data); conaccn_lock(ndata); conaccn_finish_close(ndata); conaccn_deref_and_unlock(ndata); } static int i_conaccn_close(struct conaccn_data *ndata, gensio_done close_done, void *close_data) { int err = 0; if (ndata->in_close || !ndata->child) return GE_NOTREADY; ndata->child_state = CONACCN_IN_CLOSE; err = gensio_close(ndata->child, conaccn_close_done, ndata); if (err) { conaccn_finish_close(ndata); } else { /* Note that we are using the ref owned by open. */ conaccn_ref(ndata); ndata->close_done = close_done; ndata->close_data = close_data; } return err; } static int conaccn_close(struct conaccn_data *ndata, gensio_done close_done, void *close_data) { int err; conaccn_lock(ndata); err = i_conaccn_close(ndata, close_done, close_data); conaccn_unlock(ndata); return err; } static void conaccn_free(struct conaccn_data *ndata) { conaccn_lock(ndata); switch (ndata->child_state) { case CONACCN_IN_OPEN: case CONACCN_OPEN: i_conaccn_close(ndata, NULL, NULL); /* * If close returns an error, it won't grab a refcount and the * below deref will free it. Otherwise the deref in the close * callback will free it. */ break; case CONACCN_CLOSED: case CONACCN_IN_CLOSE: /* Nothing to do except the deref below. */ break; } conaccn_deref_and_unlock(ndata); } static void conaccn_disable(struct conaccn_data *ndata) { struct conaccna_data *nadata; conaccn_lock(ndata); ndata->child_state = CONACCN_CLOSED; gensio_disable(ndata->child); nadata = ndata->nadata; ndata->nadata = NULL; if (nadata) { conaccna_lock(nadata); nadata->ndata = NULL; if (!gensio_time_is_zero(nadata->retry_time)) start_retry(nadata); else conacc_start(nadata); conacc_start(nadata); conaccna_unlock(nadata); } conaccn_unlock(ndata); } static int conaccn_func(struct gensio *io, int func, gensiods *count, const void *cbuf, gensiods buflen, void *buf, const char *const *auxdata) { struct conaccn_data *ndata = gensio_get_gensio_data(io); switch (func) { case GENSIO_FUNC_OPEN: return GE_NOTSUP; case GENSIO_FUNC_CLOSE: return conaccn_close(ndata, (void *) cbuf, buf); case GENSIO_FUNC_FREE: conaccn_free(ndata); return 0; case GENSIO_FUNC_DISABLE: conaccn_disable(ndata); return 0; default: /* Everything but the above just passes through. */ return gensio_call_func(ndata->child, func, count, cbuf, buflen, buf, auxdata); } } static int conaccn_event(struct gensio *io, void *user_data, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) { struct conaccn_data *ndata = user_data; if (!ndata->io) return GE_NOTSUP; /* All events just pass through. */ return gensio_cb(ndata->io, event, err, buf, buflen, auxdata); } /* Called with the lock held. */ static void start_retry(struct conaccna_data *nadata) { struct gensio_os_funcs *o = nadata->o; nadata->state = CONACCNA_WAITING_RETRY; if (o->start_timer(nadata->retry_timer, &nadata->retry_time) != 0) assert(0); conaccna_ref(nadata); } static void conaccn_open_done(struct gensio *io, int err, void *open_data) { struct conaccn_data *ndata = open_data; struct conaccna_data *nadata = ndata->nadata; conaccna_lock(nadata); if (nadata->state == CONACCNA_OPEN_SHUTDOWN || nadata->state == CONACCNA_OPEN_DISABLE) { /* * A close has been done, let the processing be handled in the * close callback, as it is guarnateed to happen after the * open callback. */ conaccna_unlock(nadata); return; } conaccna_unlock(nadata); if (err) goto out_err; ndata->io = gensio_data_alloc(nadata->o, NULL, NULL, conaccn_func, ndata->child, "conacc", ndata); if (!ndata->io) { err = GE_NOMEM; goto out_err; } err = base_gensio_accepter_new_child_start(nadata->acc); if (err) goto out_err; gensio_set_attr_from_child(ndata->io, ndata->child); ndata->child_state = CONACCN_OPEN; base_gensio_accepter_new_child_end(nadata->acc, ndata->io, err); out_err: conaccna_lock(nadata); switch (nadata->state) { case CONACCNA_SHUTDOWN: case CONACCNA_DISABLED: case CONACCNA_READY: case CONACCNA_WAITING_RETRY: case CONACCNA_IN_SHUTDOWN: case CONACCNA_DEAD: case CONACCNA_IN_DISABLE: case CONACCNA_IN_DISABLE_RESTART: case CONACCNA_OPEN_SHUTDOWN: assert(0); break; case CONACCNA_OPENING: if (err) { if (!gensio_time_is_zero(nadata->retry_time)) { start_retry(nadata); } else { nadata->con_err = err; nadata->state = CONACCNA_DEAD; conaccna_deferred_op(nadata); } goto out_cleanup; } nadata->state = CONACCNA_READY; break; case CONACCNA_OPEN_DISABLE: nadata->state = CONACCNA_DISABLED; goto out_cleanup; } conaccna_unlock(nadata); /* Keep the nadata ref for the open child. */ base_gensio_server_open_done(nadata->acc, ndata->io, 0); return; out_cleanup: if (!err) { err = GE_NOTREADY; base_gensio_server_open_done(nadata->acc, ndata->io, err); } conaccn_finish_free(ndata); nadata->ndata = NULL; conaccna_deref_and_unlock(nadata); } static void conacc_start(struct conaccna_data *nadata) { struct conaccn_data *ndata; int err = GE_NOMEM; if (nadata->ndata) { nadata->state = CONACCNA_READY; return; } nadata->state = CONACCNA_OPENING; ndata = nadata->o->zalloc(nadata->o, sizeof(*ndata)); if (!ndata) goto out_err_nofree; ndata->o = nadata->o; ndata->nadata = nadata; ndata->refcount = 1; ndata->lock = nadata->o->alloc_lock(nadata->o); if (!ndata->lock) goto out_err; err = str_to_gensio(nadata->gensio_str, ndata->o, conaccn_event, ndata, &ndata->child); if (err) goto out_err; nadata->ndata = ndata; conaccna_ref(nadata); ndata->child_state = CONACCN_IN_OPEN; err = gensio_open(ndata->child, conaccn_open_done, ndata); if (err) { nadata->ndata = NULL; conaccna_deref(nadata); goto out_err; } return; out_err: conaccn_finish_free(ndata); out_err_nofree: if (!gensio_time_is_zero(nadata->retry_time)) { start_retry(nadata); } else { nadata->state = CONACCNA_DEAD; nadata->con_err = err; conaccna_deferred_op(nadata); } } static void conaccna_retry_timeout(struct gensio_timer *t, void *cb_data) { struct conaccna_data *nadata = cb_data; conaccna_lock(nadata); switch (nadata->state) { case CONACCNA_SHUTDOWN: case CONACCNA_DISABLED: case CONACCNA_OPENING: case CONACCNA_READY: case CONACCNA_OPEN_SHUTDOWN: case CONACCNA_OPEN_DISABLE: case CONACCNA_DEAD: assert(0); case CONACCNA_IN_SHUTDOWN: conaccna_finish_shutdown(nadata); break; case CONACCNA_IN_DISABLE_RESTART: case CONACCNA_WAITING_RETRY: conacc_start(nadata); break; case CONACCNA_IN_DISABLE: nadata->state = CONACCNA_DISABLED; break; } conaccna_deref_and_unlock(nadata); } static void retry_timer_done(struct gensio_timer *t, void *cb_data) { struct conaccna_data *nadata = cb_data; conaccna_lock(nadata); switch (nadata->state) { case CONACCNA_SHUTDOWN: case CONACCNA_DISABLED: case CONACCNA_OPENING: case CONACCNA_READY: case CONACCNA_WAITING_RETRY: case CONACCNA_OPEN_SHUTDOWN: case CONACCNA_OPEN_DISABLE: case CONACCNA_DEAD: assert(0); break; case CONACCNA_IN_SHUTDOWN: conaccna_finish_shutdown(nadata); break; case CONACCNA_IN_DISABLE: nadata->state = CONACCNA_DISABLED; conaccna_call_enabled(nadata); break; case CONACCNA_IN_DISABLE_RESTART: conacc_start(nadata); break; default: assert(0); } conaccna_deref_and_unlock(nadata); } static int conaccna_startup(struct gensio_accepter *accepter, struct conaccna_data *nadata) { int rv = 0; conaccna_lock(nadata); if (nadata->state == CONACCNA_SHUTDOWN) { nadata->con_err = 0; if (!nadata->enabled) nadata->state = CONACCNA_DISABLED; else { conacc_start(nadata); if (nadata->state == CONACCNA_DEAD) { nadata->state = CONACCNA_SHUTDOWN; rv = nadata->con_err; nadata->con_err = 0; } } } else { rv = GE_NOTREADY; } conaccna_unlock(nadata); return rv; } static void conaccn_shutdown_close_done(struct gensio *child_io, void *close_cb_data) { struct conaccn_data *ndata = close_cb_data; struct conaccna_data *nadata = ndata->nadata; conaccn_finish_free(ndata); conaccna_lock(nadata); nadata->ndata = NULL; switch (nadata->state) { case CONACCNA_OPEN_DISABLE: nadata->state = CONACCNA_DISABLED; conaccna_call_enabled(nadata); break; case CONACCNA_OPEN_SHUTDOWN: conaccna_finish_shutdown(nadata); break; default: assert(0); } conaccna_deref_and_unlock(nadata); } static int conaccna_shutdown(struct gensio_accepter *accepter, struct conaccna_data *nadata, gensio_acc_done shutdown_done) { struct gensio_os_funcs *o = nadata->o; struct conaccn_data *ndata; int rv = 0, err; conaccna_lock(nadata); switch (nadata->state) { case CONACCNA_SHUTDOWN: case CONACCNA_OPEN_SHUTDOWN: case CONACCNA_IN_SHUTDOWN: rv = GE_NOTREADY; break; case CONACCNA_OPENING: ndata = nadata->ndata; err = gensio_close(ndata->child, conaccn_shutdown_close_done, ndata); if (err) { nadata->state = CONACCNA_IN_SHUTDOWN; conaccna_deferred_op(nadata); } else { nadata->state = CONACCNA_OPEN_SHUTDOWN; } break; case CONACCNA_READY: nadata->state = CONACCNA_IN_SHUTDOWN; conaccna_deferred_op(nadata); break; case CONACCNA_WAITING_RETRY: nadata->state = CONACCNA_IN_SHUTDOWN; err = o->stop_timer_with_done(nadata->retry_timer, retry_timer_done, nadata); if (err == GE_TIMEDOUT) { /* Done handler won't be called, run it in the deferred op. */ conaccna_deferred_op(nadata); } else if (!err) { /* Done handler will be called. */ } else { /* * We should not get GE_INUSE, that means there is already * a stop in progress and the done handler will be called. */ assert(0); } break; case CONACCNA_OPEN_DISABLE: nadata->state = CONACCNA_OPEN_SHUTDOWN; break; case CONACCNA_IN_DISABLE: nadata->state = CONACCNA_IN_SHUTDOWN; break; case CONACCNA_IN_DISABLE_RESTART: nadata->state = CONACCNA_IN_SHUTDOWN; conaccna_deferred_op(nadata); break; case CONACCNA_DISABLED: case CONACCNA_DEAD: nadata->state = CONACCNA_IN_SHUTDOWN; conaccna_deferred_op(nadata); break; } if (!rv) nadata->shutdown_done = shutdown_done; conaccna_unlock(nadata); return rv; } static int conaccna_set_accept_callback_enable(struct gensio_accepter *accepter, struct conaccna_data *nadata, bool enabled, gensio_acc_done done) { int rv = 0, err; bool do_deferred = true; conaccna_lock(nadata); if (nadata->enabled_done) { rv = GE_INUSE; goto out_unlock; } switch (nadata->state) { case CONACCNA_SHUTDOWN: case CONACCNA_DEAD: case CONACCNA_OPEN_SHUTDOWN: case CONACCNA_IN_SHUTDOWN: break; case CONACCNA_DISABLED: if (enabled) { conacc_start(nadata); if (nadata->state == CONACCNA_DEAD) { nadata->state = CONACCNA_SHUTDOWN; rv = nadata->con_err; nadata->con_err = 0; } } break; case CONACCNA_OPENING: if (!enabled) { struct conaccn_data *ndata = nadata->ndata; err = gensio_close(ndata->child, conaccn_shutdown_close_done, ndata); if (err) { nadata->state = CONACCNA_IN_DISABLE; } else { nadata->state = CONACCNA_OPEN_DISABLE; do_deferred = false; } } break; case CONACCNA_READY: nadata->state = CONACCNA_IN_DISABLE; break; case CONACCNA_WAITING_RETRY: if (!enabled) { nadata->state = CONACCNA_IN_DISABLE; err = nadata->o->stop_timer_with_done(nadata->retry_timer, retry_timer_done, nadata); if (err == GE_TIMEDOUT) { /* Done handler won't be called, run it in the deferred op. */ } else if (!err) { /* Done handler will be called. */ do_deferred = false; } else { /* * We should not get GE_INUSE, that means there is already * a stop in progress and the done handler will be called. */ assert(0); } } break; case CONACCNA_OPEN_DISABLE: if (enabled) nadata->state = CONACCNA_OPENING; break; case CONACCNA_IN_DISABLE: if (enabled) nadata->state = CONACCNA_IN_DISABLE_RESTART; break; case CONACCNA_IN_DISABLE_RESTART: if (!enabled) nadata->state = CONACCNA_IN_DISABLE; break; } if (!rv) { nadata->enabled = enabled; nadata->enabled_done = done; if (do_deferred) conaccna_deferred_op(nadata); } out_unlock: conaccna_unlock(nadata); return rv; } static void conaccna_free(struct gensio_accepter *accepter, struct conaccna_data *nadata) { conaccna_lock(nadata); conaccna_deref_and_unlock(nadata); } static void conaccna_disable(struct gensio_accepter *accepter, struct conaccna_data *nadata) { conaccna_lock(nadata); nadata->state = CONACCNA_DEAD; conaccna_unlock(nadata); } static int conaccna_control(struct gensio_accepter *accepter, struct conaccna_data *nadata, bool get, unsigned int option, char *data, gensiods *datalen) { int err; int iooption; switch (option) { case GENSIO_ACC_CONTROL_LADDR: iooption = GENSIO_CONTROL_LADDR; break; case GENSIO_ACC_CONTROL_LPORT: iooption = GENSIO_CONTROL_LPORT; break; default: return GE_NOTSUP; } conaccna_lock(nadata); if (!nadata->ndata || !nadata->ndata->child) { err = GE_NOTREADY; } else { err = gensio_control(nadata->ndata->child, GENSIO_CONTROL_DEPTH_FIRST, get, iooption, data, datalen); } conaccna_unlock(nadata); return err; } static int conacc_base_acc_op(struct gensio_accepter *acc, int func, void *acc_op_data, void *done, int val1, void *data, void *data2, void *ret) { switch (func) { case GENSIO_BASE_ACC_STARTUP: return conaccna_startup(acc, acc_op_data); case GENSIO_BASE_ACC_SHUTDOWN: return conaccna_shutdown(acc, acc_op_data, done); case GENSIO_BASE_ACC_SET_CB_ENABLE: return conaccna_set_accept_callback_enable(acc, acc_op_data, val1, done); case GENSIO_BASE_ACC_FREE: conaccna_free(acc, acc_op_data); return 0; case GENSIO_BASE_ACC_DISABLE: conaccna_disable(acc, acc_op_data); return 0; case GENSIO_BASE_ACC_CONTROL: return conaccna_control(acc, acc_op_data, val1, *((unsigned int *) done), data, ret); default: return GE_NOTSUP; } } static int conacc_gensio_accepter_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { const char *gensio_str = gdata; struct conaccna_data *nadata; unsigned int i; struct gensio_time retry_time = { 0, 0 }; int err; GENSIO_DECLARE_PPACCEPTER(p, o, cb, "conacc", user_data); for (i = 0; args && args[i]; i++) { if (gensio_pparm_time(&p, args[i], "retry-time", 'm', &retry_time) > 0) continue; gensio_pparm_unknown_parm(&p, args[i]); return GE_INVAL; } nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) return GE_NOMEM; nadata->o = o; nadata->enabled = true; nadata->refcount = 1; nadata->retry_time = retry_time; nadata->gensio_str = gensio_strdup(o, gensio_str); if (!nadata->gensio_str) goto out_nomem; nadata->lock = o->alloc_lock(o); if (!nadata->lock) goto out_nomem; nadata->retry_timer = o->alloc_timer(o, conaccna_retry_timeout, nadata); if (!nadata->retry_timer) goto out_nomem; nadata->deferred_runner = o->alloc_runner(o, conaccna_do_deferred, nadata); if (!nadata->deferred_runner) goto out_nomem; err = base_gensio_accepter_alloc(NULL, conacc_base_acc_op, nadata, o, "conacc", cb, user_data, accepter); if (err) goto out_err; nadata->acc = *accepter; /* FIXME - how to set gensio_acc attributes (reliable, etc.) */ return 0; out_nomem: err = GE_NOMEM; out_err: conaccna_finish_free(nadata); return err; } static int str_to_conacc_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { return conacc_gensio_accepter_alloc(str, args, o, cb, user_data, acc); } int gensio_init_conacc(struct gensio_os_funcs *o) { int rv; rv = register_gensio_accepter(o, "conacc", str_to_conacc_gensio_accepter, conacc_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/utils.c0000664000175000017500000004510414747451760010556 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include #include "utils.h" char * gensio_strdup(struct gensio_os_funcs *o, const char *str) { char *s; if (!str) return NULL; s = o->zalloc(o, strlen(str) + 1); if (!s) return NULL; strcpy(s, str); return s; } char * gensio_strndup(struct gensio_os_funcs *o, const char *str, gensiods len) { char *s; gensiods slen = strlen(str); if (len > slen) len = slen; s = o->zalloc(o, len + 1); if (!s) return NULL; memcpy(s, str, len); return s; } int gensio_argv_copy(struct gensio_os_funcs *o, const char * const oargv[], int *r_argc, const char ***r_argv) { unsigned int len; const char **argv; for (len = 0; oargv[len]; len++) ; argv = o->zalloc(o, (len + 1) * sizeof(*argv)); if (!argv) return GE_NOMEM; for (len = 0; oargv[len]; len++) { argv[len] = gensio_strdup(o, oargv[len]); if (!argv[len]) goto out_nomem; } argv[len] = NULL; if (r_argc) *r_argc = len; *r_argv = argv; return 0; out_nomem: while (len > 0) { len--; o->free(o, (void *) argv[len]); } o->free(o, (void *) argv); return GE_NOMEM; } int gensio_argv_nappend(struct gensio_os_funcs *o, const char ***argv, const char *str, gensiods len, gensiods *args, gensiods *argc, bool allocstr) { if (!*argv) { *args = 10; *argc = 0; *argv = o->zalloc(o, *args * sizeof(char *)); if (!*argv) return GE_NOMEM; } /* + 1 to leave room for the ending NULL. */ if (*argc + 1 >= *args) { const char **nargv; nargv = o->zalloc(o, sizeof(char *) * (*args + 10)); if (!nargv) return GE_NOMEM; memcpy((void *) nargv, *argv, sizeof(char *) * *args); o->free(o, (void *) *argv); *argv = nargv; *args += 10; } if (str) { if (allocstr) { char *s = o->zalloc(o, len + 1); if (!s) return GE_NOMEM; memcpy(s, str, len); (*argv)[*argc] = s; } else { (*argv)[*argc] = str; } (*argc)++; } else { (*argv)[*argc] = NULL; } return 0; } int gensio_argv_append(struct gensio_os_funcs *o, const char ***argv, const char *str, gensiods *args, gensiods *argc, bool allocstr) { gensiods len = 0; if (str) len = strlen(str); return gensio_argv_nappend(o, argv, str, len, args, argc, allocstr); } int gensio_argv_vappend(struct gensio_os_funcs *o, const char ***argv, gensiods *args, gensiods *argc, const char *fmt, va_list ap) { int err; char *s; s = gensio_alloc_vsprintf(o, fmt, ap); if (!s) return GE_NOMEM; err = gensio_argv_append(o, argv, s, args, argc, false); if (err) o->free(o, s); return err; } int gensio_argv_sappend(struct gensio_os_funcs *o, const char ***argv, gensiods *args, gensiods *argc, const char *fmt, ...) { va_list ap; int err; va_start(ap, fmt); err = gensio_argv_vappend(o, argv, args, argc, fmt, ap); va_end(ap); return err; } void gensio_argv_free(struct gensio_os_funcs *o, const char **argv) { unsigned int i; if (!argv) return; for (i = 0; argv[i]; i++) o->free(o, (void *) argv[i]); o->free(o, (void *) argv); } static bool is_sep(char c, const char *seps) { return c && strchr(seps, c); } static const char * skip_seps(const char *s, const char *seps) { while (is_sep(*s, seps)) s++; return s; } static bool isodigit(char c) { return isdigit(c) && c != '8' && c != '9'; } static void set_out(char **o, char s, unsigned int *len) { if (*o) { **o = s; (*o)++; } (*len)++; } static int gettok(struct gensio_os_funcs *o, const char **s, char **tok, const char *seps, const char *endchars) { const char *p = skip_seps(*s, seps); const char *t = p; char *out = NULL; char inquote = '\0'; unsigned int escape = 0; unsigned int base = 8; char cval = 0; unsigned int len = 0; if (!*p || strchr(endchars, *p)) { *s = p; *tok = NULL; return 0; } restart: for (; *p; p++) { if (escape) { if (escape == 1) { cval = 0; if (isodigit(*p)) { base = 8; cval = *p - '0'; escape++; } else if (*p == 'x') { base = 16; escape++; } else { switch (*p) { case 'a': set_out(&out, '\a', &len); break; case 'b': set_out(&out, '\b', &len); break; case 'f': set_out(&out, '\f', &len); break; case 'n': set_out(&out, '\n', &len); break; case 'r': set_out(&out, '\r', &len); break; case 't': set_out(&out, '\t', &len); break; case 'v': set_out(&out, '\v', &len); break; default: set_out(&out, *p, &len); } escape = 0; } } else if (escape >= 2) { if ((base == 16 && isxdigit(*p)) || isodigit(*p)) { if (isdigit(*p)) cval = cval * base + *p - '0'; else if (isupper(*p)) cval = cval * base + *p - 'A'; else cval = cval * base + *p - 'a'; if (escape >= 3) { set_out(&out, cval, &len); escape = 0; } else { escape++; } } else { set_out(&out, cval, &len); escape = 0; goto process_char; } } continue; } process_char: if (*p == inquote) { inquote = '\0'; } else if (!inquote && (*p == '\'' || *p == '"')) { inquote = *p; } else if (*p == '\\') { escape = 1; } else if (!inquote) { if (is_sep(*p, seps)) { p++; break; } else if (strchr(endchars, *p)) { /* Don't skip endchars. */ break; } else { set_out(&out, *p, &len); } } else { set_out(&out, *p, &len); } } if ((base == 8 && escape > 1) || (base == 16 && escape > 2)) { set_out(&out, cval, &len); escape = 0; } if (inquote || escape) return GE_INVAL; if (!out) { out = o->zalloc(o, len + 1); if (!out) return GE_NOMEM; *tok = out; len = 0; p = t; goto restart; } *s = p; *out = '\0'; return 0; } int gensio_str_to_argv_endchar(struct gensio_os_funcs *o, const char *ins, int *r_argc, const char ***r_argv, const char *seps, const char *endchars, const char **nextptr) { const char **argv = NULL; char *tok = NULL; gensiods argc = 0; gensiods args = 0; int err; if (!seps) seps = " \f\n\r\t\v"; if (!endchars) endchars = ""; err = gettok(o, &ins, &tok, seps, endchars); while (tok && !err) { err = gensio_argv_append(o, &argv, tok, &args, &argc, false); if (err) goto out; tok = NULL; err = gettok(o, &ins, &tok, seps, endchars); } /* NULL terminate the array. */ if (!err) err = gensio_argv_append(o, &argv, NULL, &args, &argc, false); out: if (err) { if (tok) o->free(o, tok); if (argv) { while (argc > 0) { argc--; o->free(o, (void *) argv[argc]); } o->free(o, (void *) argv); } } else { if (r_argc) *r_argc = argc; *r_argv = argv; if (nextptr) *nextptr = ins; } return err; } int gensio_str_to_argv(struct gensio_os_funcs *o, const char *ins, int *r_argc, const char ***r_argv, const char *seps) { return gensio_str_to_argv_endchar(o, ins, r_argc, r_argv, seps, NULL, NULL); } int gensio_scan_args(struct gensio_os_funcs *o, const char **rstr, int *argc, const char ***args) { const char *str = *rstr; int err = 0; if (*str == '(') { err = gensio_str_to_argv_endchar(o, str + 1, argc, args, " \f\n\r\t\v,", ")", &str); if (!err) { if (*str != ')') { err = GE_INVAL; /* Didn't end in ')'. */ } else { str++; if (*str != ',' && *str) err = GE_INVAL; /* Not a ',' or end of string after */ else if (*str) str++; } } } else { if (*str) str += 1; /* skip the comma */ err = gensio_str_to_argv(o, "", argc, args, ")"); } if (!err) *rstr = str; return err; } int gensio_time_cmp(gensio_time *t1, gensio_time *t2) { if (t1->secs < t2->secs) return -1; if (t1->secs > t2->secs) return 1; if (t1->nsecs < t2->nsecs) return -1; if (t1->nsecs > t2->nsecs) return 1; return 0; } bool gensio_str_in_auxdata(const char *const *auxdata, const char *str) { unsigned int i; if (!auxdata) return false; for (i = 0; auxdata[i]; i++) { if (strcmp(auxdata[i], str) == 0) return true; } return false; } uint32_t gensio_buf_to_u32(unsigned char *data) { return (data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]); } void gensio_u32_to_buf(unsigned char *data, uint32_t v) { data[0] = v >> 24; data[1] = v >> 16; data[2] = v >> 8; data[3] = v; } uint16_t gensio_buf_to_u16(unsigned char *data) { return (data[0] << 8 | data[1]); } void gensio_u16_to_buf(unsigned char *data, uint16_t v) { data[0] = v >> 8; data[1] = v; } gensiods gensio_pos_snprintf(char *buf, gensiods len, gensiods *pos, char *format, ...) { va_list ap; int rv; gensiods size = len; gensiods lpos = 0; if (!pos) pos = &lpos; if (*pos > len) { /* * If we are past the end of buffer, go to the end and don't * output anything, just get the return from vsnprintf(). */ size = 0; buf += len; } else { size = len - *pos; buf += *pos; } va_start(ap, format); rv = vsnprintf(buf, size, format, ap); va_end(ap); *pos += rv; return rv; } static gensiods gensio_quote_str(char *buf, gensiods len, gensiods *pos, const char *arg) { gensiods olen = 0; olen = gensio_pos_snprintf(buf, len, pos, "\""); while (*arg) { if (*arg == '"') olen += gensio_pos_snprintf(buf, len, pos, "\\\""); else if (*arg == '\\') olen += gensio_pos_snprintf(buf, len, pos, "\\\\"); else olen += gensio_pos_snprintf(buf, len, pos, "%c", *arg); arg++; } olen += gensio_pos_snprintf(buf, len, pos, "\""); if (*pos < len) buf[*pos] = '\0'; return olen; } gensiods gensio_argv_snprintf(char *buf, gensiods len, gensiods *pos, const char **argv) { gensiods olen = 0; bool first = true; gensiods lpos = 0; if (!pos) pos = &lpos; while (argv && *argv) { if (!first) { olen += gensio_pos_snprintf(buf, len, pos, " "); } else { first = false; } olen += gensio_quote_str(buf, len, pos, *argv); argv++; } if (*pos < len) buf[*pos] = '\0'; return olen; } char * gensio_alloc_vsprintf(struct gensio_os_funcs *o, const char *fmt, va_list va) { va_list va2; size_t len; char c[1], *str; va_copy(va2, va); len = (size_t) vsnprintf(c, 0, fmt, va) + 1L; str = o->zalloc(o, len); if (str) vsnprintf(str, len, fmt, va2); va_end(va2); return str; } char * gensio_alloc_sprintf(struct gensio_os_funcs *o, const char *fmt, ...) { va_list va; char *s; va_start(va, fmt); s = gensio_alloc_vsprintf(o, fmt, va); va_end(va); return s; } char * gensio_quote_string(struct gensio_os_funcs *o, const char *str) { const char *ic; char *ostr, *oc; gensiods count = 3; /* Space for two quotes and a \0. */ /* We need two characters for all \ and ". */ for (ic = str; *ic; ic++) { count++; if (*ic == '\\' || *ic == '"') count++; } ostr = o->zalloc(o, count); if (!ostr) return NULL; oc = ostr; *oc++ = '"'; for (ic = str; *ic; ic++) { if (*ic == '\\' || *ic == '"') *oc++ = '\\'; *oc++ = *ic; } *oc++ = '"'; return ostr; } static const char *gensio_errs[] = { /* 0 */ "No error", /* 1 */ "Out of memory", /* 2 */ "Operation not supported", /* 3 */ "Invalid data to parameter", /* 4 */ "Value or file not found", /* 5 */ "Value already exists", /* 6 */ "Value out of range", /* 7 */ "Parameters inconsistent in call", /* 8 */ "No data was available for the function", /* 9 */ "OS error, see logs", /* 10 */ "Object was already in use", /* 11 */ "Operation is in progress", /* 12 */ "Object was not ready for operation", /* 13 */ "Value was too large for data", /* 14 */ "Operation timed out", /* 15 */ "Retry operation later", /* 16 */ "Invalid error number 1", /* 17 */ "Unable to find the given key", /* 18 */ "Key was revoked", /* 19 */ "Key was expired", /* 20 */ "Key is not valid", /* 21 */ "Certificate not provided", /* 22 */ "Certificate is not valid", /* 23 */ "Protocol error", /* 24 */ "Communication error", /* 25 */ "Internal I/O error", /* 26 */ "Remote end closed connection", /* 27 */ "Host could not be reached", /* 28 */ "Connection refused", /* 29 */ "Data was missing", /* 30 */ "Unable to find given certificate", /* 31 */ "Authentication tokens rejected", /* 32 */ "Address already in use", /* 33 */ "Operation was interrupted by a signal", /* 34 */ "Operation on shutdown fd", /* 35 */ "Local end closed connection", /* 36 */ "Permission denied", /* 37 */ "Application error", /* 38 */ "Unknown name server lookup failure", /* 39 */ "Unable to find a valid name on the name server", /* 40 */ "Serious name server failure", /* 41 */ "Invalid name server information", /* 42 */ "Network address for the given name is not available" }; const int errno_len = sizeof(gensio_errs) / sizeof(char *); const char * gensio_err_to_str(int err) { if (err < 0 || err >= errno_len) return "Unknown error"; return gensio_errs[err]; } #ifndef HAVE_STRCASECMP int strcasecmp(const char *s1, const char *s2) { while (s1 && s2) { char c1 = tolower(*s1); char c2 = tolower(*s2); if (c1 < c2) return -1; if (c1 > c2) return 1; if (!c1 || !c2) break; s1++; s2++; } return 0; } #endif #ifndef HAVE_STRNCASECMP int strncasecmp(const char *s1, const char *s2, int n) { while (s1 && s2 && n) { char c1 = tolower(*s1); char c2 = tolower(*s2); if (c1 < c2) return -1; if (c1 > c2) return 1; if (!c1 || !c2) break; s1++; s2++; n--; } return 0; } #endif void gensio_list_rm(struct gensio_list *list, struct gensio_link *link) { assert(link->list == list); link->next->prev = link->prev; link->prev->next = link->next; link->next = NULL; link->prev = NULL; link->list = NULL; } void gensio_list_add_head(struct gensio_list *list, struct gensio_link *link) { assert(link->list == NULL && link->next == NULL && link->prev == NULL); link->next = list->link.next; link->prev = &list->link; list->link.next->prev = link; list->link.next = link; link->list = list; } void gensio_list_add_tail(struct gensio_list *list, struct gensio_link *link) { assert(link->list == NULL && link->next == NULL && link->prev == NULL); link->prev = list->link.prev; link->next = &list->link; list->link.prev->next = link; list->link.prev = link; link->list = list; } void gensio_list_add_next(struct gensio_list *list, struct gensio_link *curr, struct gensio_link *link) { assert(link->list == NULL && link->next == NULL && link->prev == NULL); link->next = curr->next; link->prev = curr; curr->next->prev = link; curr->next = link; link->list = list; } void gensio_list_add_prev(struct gensio_list *list, struct gensio_link *curr, struct gensio_link *link) { assert(link->list == NULL && link->next == NULL && link->prev == NULL); link->prev = curr->prev; link->next = curr; curr->prev->next = link; curr->prev = link; link->list = list; } void gensio_list_init(struct gensio_list *list) { list->link.next = &list->link; list->link.prev = &list->link; list->link.list = list; } bool gensio_list_empty(struct gensio_list *list) { return list->link.next == &list->link; } static unsigned int gensio_log_mask = (1 << GENSIO_LOG_FATAL) | (1 << GENSIO_LOG_ERR); void gensio_set_log_mask(unsigned int mask) { gensio_log_mask = mask; } unsigned int gensio_get_log_mask(void) { return gensio_log_mask; } void gensio_vlog(struct gensio_os_funcs *o, enum gensio_log_levels level, const char *str, va_list args) { if (!(gensio_log_mask & (1 << level))) return; if (o->vlog) o->vlog(o, level, str, args); } void gensio_log(struct gensio_os_funcs *o, enum gensio_log_levels level, const char *str, ...) { va_list args; va_start(args, str); gensio_vlog(o, level, str, args); va_end(args); } const char * gensio_log_level_to_str(enum gensio_log_levels level) { switch (level) { case GENSIO_LOG_FATAL: return "fatal"; break; case GENSIO_LOG_ERR: return "err"; break; case GENSIO_LOG_WARNING: return "warning"; break; case GENSIO_LOG_INFO: return "info"; break; case GENSIO_LOG_DEBUG: return "debug"; break; default: return "invalid"; } } struct gensio_cntstr { gensio_refcount refcount; char *str; }; int gensio_cntstr_make(struct gensio_os_funcs *o, const char *src, gensio_cntstr **dest) { gensio_cntstr *str; unsigned int len; if (src) len = strlen(src) + 1; else len = 0; str = o->zalloc(o, len + sizeof(*str)); if (!str) return GE_NOMEM; gensio_refcount_init(o, &str->refcount, 1); if (src) { str->str = ((char *) str) + sizeof(*str); strcpy(str->str, src); } *dest = str; return 0; } gensio_cntstr * gensio_cntstr_ref(struct gensio_os_funcs *o, gensio_cntstr *str) { gensio_refcount_inc(&str->refcount); return str; } void gensio_cntstr_free(struct gensio_os_funcs *o, gensio_cntstr *str) { unsigned int newval = gensio_refcount_dec(&str->refcount); if (newval == 0) { gensio_refcount_cleanup(&str->refcount); o->free(o, str); } } int gensio_cntstr_vsprintf(struct gensio_os_funcs *o, gensio_cntstr **dest, const char *fmt, va_list va) { va_list va2; size_t len; char c[1]; gensio_cntstr *str; va_copy(va2, va); len = (size_t) vsnprintf(c, 0, fmt, va) + 1L; str = o->zalloc(o, len + sizeof(*str)); if (!str) { va_end(va2); return GE_NOMEM; } gensio_refcount_init(o, &str->refcount, 1); str->str = ((char *) str) + sizeof(*str); vsnprintf(str->str, len, fmt, va2); va_end(va2); *dest = str; return 0; } int gensio_cntstr_sprintf(struct gensio_os_funcs *o, gensio_cntstr **dest, const char *fmt, ...) { va_list va; int err; va_start(va, fmt); err = gensio_cntstr_vsprintf(o, dest, fmt, va); va_end(va); return err; } const char * gensio_cntstr_get(gensio_cntstr *str) { return str->str; } gensio-3.0.0/lib/gensio_kiss.c0000664000175000017500000005666415055560702011736 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include #include struct kiss_config { bool server; gensiods max_read_size; gensiods max_write_size; bool tncs[16]; unsigned int txdelay; unsigned int persist; unsigned int slot_time; bool full_duplex; unsigned int set_hardware; unsigned int setup_delay; bool set_hardware_set; char *setupstr; gensiods setupstr_len; }; static void gensio_kiss_config_cleanup(struct gensio_os_funcs *o, struct kiss_config *config) { if (config->setupstr) o->free(o, config->setupstr); } struct kiss_filter { struct gensio_filter *filter; struct gensio_os_funcs *o; struct kiss_config config; struct gensio_lock *lock; gensio_filter_cb filter_cb; void *filter_cb_data; bool waiting_setup_timer; unsigned char *setupstr; gensiods setupstr_pos; unsigned int setup_delay; bool in_esc; /* Currently processing message data (after a start). */ bool in_msg_complete; /* A full message is ready. */ bool out_msg_ready; bool in_bad_packet; /* Data waiting to be delivered to the user. */ unsigned char *read_data; gensiods read_data_pos; gensiods read_data_len; /* Data waiting to be written. */ unsigned char *write_data; gensiods buf_max_write; /* Maximum raw bytes (escaping c0s, etc.) */ gensiods write_data_pos; gensiods write_data_len; gensiods user_write_pos; /* Current user position. */ uint8_t curr_tnc; unsigned char startdata[320]; unsigned char startdata_len; }; #define filter_to_kiss(v) ((struct kiss_filter *) \ gensio_filter_get_user_data(v)) static void kiss_lock(struct kiss_filter *kfilter) { kfilter->o->lock(kfilter->lock); } static void kiss_unlock(struct kiss_filter *kfilter) { kfilter->o->unlock(kfilter->lock); } static bool kiss_ul_read_pending(struct gensio_filter *filter) { struct kiss_filter *kfilter = filter_to_kiss(filter); return kfilter->in_msg_complete; } static bool kiss_ll_write_pending(struct gensio_filter *filter) { struct kiss_filter *kfilter = filter_to_kiss(filter); return kfilter->out_msg_ready || kfilter->setupstr_pos < kfilter->config.setupstr_len; } static bool kiss_ll_read_needed(struct gensio_filter *filter) { return false; } static int kiss_check_open_done(struct gensio_filter *filter, struct gensio *io) { gensio_set_is_packet(io, true); return 0; } static void kiss_add_wrbyte(struct kiss_filter *kfilter, unsigned char byte) { if (byte == 0xc0) { kfilter->write_data[kfilter->write_data_len++] = 0xdb; kfilter->write_data[kfilter->write_data_len++] = 0xdc; } else if (byte == 0xdb) { kfilter->write_data[kfilter->write_data_len++] = 0xdb; kfilter->write_data[kfilter->write_data_len++] = 0xdd; } else { kfilter->write_data[kfilter->write_data_len++] = byte; } } static int kiss_try_connect(struct gensio_filter *filter, gensio_time *timeout) { struct kiss_filter *kfilter = filter_to_kiss(filter); unsigned int i; if (!kfilter->waiting_setup_timer && kfilter->config.setupstr_len) { kfilter->setupstr_pos = 0; kfilter->waiting_setup_timer = true; timeout->secs = kfilter->setup_delay / 1000; timeout->nsecs = kfilter->setup_delay % 1000 * 1000000; return GE_RETRY; } else { kfilter->waiting_setup_timer = false; } for (i = 0; i < kfilter->startdata_len; i++) kiss_add_wrbyte(kfilter, kfilter->startdata[i]); if (i > 0) kfilter->out_msg_ready = true; return 0; } static int kiss_try_disconnect(struct gensio_filter *filter, gensio_time *timeout) { struct kiss_filter *kfilter = filter_to_kiss(filter); if (kfilter->write_data_len == 0 || !kfilter->out_msg_ready) return 0; else return GE_INPROGRESS; } static int kiss_ul_write(struct gensio_filter *filter, gensio_ul_filter_data_handler handler, void *cb_data, gensiods *rcount, const struct gensio_sg *isg, gensiods sglen, const char *const *auxdata) { struct kiss_filter *kfilter = filter_to_kiss(filter); unsigned int tnc = 0; int rv = 0; if (auxdata) { unsigned int i; for (i = 0; auxdata[i]; i++) { if (strncmp(auxdata[i], "tnc:", 4) == 0) { char *end; tnc = strtoul(auxdata[i] + 4, &end, 10); if (!isdigit(auxdata[i][4]) || tnc > 15 || *end) return GE_INVAL; } else { return GE_INVAL; } } } kiss_lock(kfilter); if (!kfilter->config.tncs[tnc]) { printf("A\n"); rv = GE_INVAL; } else if (kfilter->setupstr_pos < kfilter->config.setupstr_len) { struct gensio_sg sg[1]; gensiods count; kiss_unlock(kfilter); sg[0].buflen = kfilter->config.setupstr_len - kfilter->setupstr_pos; sg[0].buf = kfilter->setupstr + kfilter->setupstr_pos; rv = handler(cb_data, &count, sg, 1, NULL); kiss_lock(kfilter); if (!rv) { kfilter->setupstr_pos += count; if (rcount) *rcount = 0; } } else if (kfilter->out_msg_ready) { if (rcount) *rcount = 0; } else { gensiods i, j, writelen = 0; kfilter->write_data[kfilter->write_data_len++] = 0xc0; kiss_add_wrbyte(kfilter, tnc << 4); for (i = 0; i < sglen; i++) { gensiods inlen = isg[i].buflen; const unsigned char *buf = isg[i].buf; for (j = 0; j < inlen; j++) { if (kfilter->user_write_pos >= kfilter->config.max_write_size) break; kfilter->user_write_pos++; kiss_add_wrbyte(kfilter, buf[j]); } writelen += inlen; } if (rcount) *rcount = writelen; if (kfilter->user_write_pos > 0) { kfilter->out_msg_ready = true; kfilter->write_data[kfilter->write_data_len++] = 0xc0; } } if (kfilter->out_msg_ready) { struct gensio_sg sg[1]; gensiods len = kfilter->write_data_len - kfilter->write_data_pos; gensiods count; sg[0].buflen = len; sg[0].buf = kfilter->write_data + kfilter->write_data_pos; kiss_unlock(kfilter); rv = handler(cb_data, &count, sg, 1, NULL); kiss_lock(kfilter); if (rv) { kfilter->out_msg_ready = false; } else { if (count >= len) { kfilter->write_data_len = 0; kfilter->write_data_pos = 0; kfilter->out_msg_ready = false; kfilter->user_write_pos = 0; } else { kfilter->write_data_pos += count; } } } kiss_unlock(kfilter); return rv; } static int kiss_ll_write(struct gensio_filter *filter, gensio_ll_filter_data_handler handler, void *cb_data, gensiods *rcount, unsigned char *buf, gensiods buflen, const char *const *iauxdata) { struct kiss_filter *kfilter = filter_to_kiss(filter); gensiods in_buflen = buflen, count = 0; int err = 0; kiss_lock(kfilter); if (kfilter->in_msg_complete || buflen == 0) { if (rcount) *rcount = 0; } else { while (buflen && !kfilter->in_msg_complete) { unsigned char b = *buf++; buflen--; if (b == 0xc0) { /* Frame end char */ kfilter->in_esc = 0; if (kfilter->in_bad_packet) { kfilter->read_data_len = 0; kfilter->in_bad_packet = false; } else if (kfilter->read_data_len > 0) { kfilter->read_data_pos = 0; kfilter->in_msg_complete = true; } continue; } else if (kfilter->in_bad_packet) { /* Ignore input until a frame end. */ } else if (kfilter->in_esc) { kfilter->in_esc = false; if (b == 0xdc) { b = 0xc0; } else if (b == 0xdd) { b = 0xdb; } else { kfilter->in_bad_packet = true; continue; } } else if (b == 0xdb) { /* escape char */ kfilter->in_esc = true; continue; } if (kfilter->read_data_len >= kfilter->config.max_read_size) { kfilter->in_bad_packet = true; continue; } kfilter->read_data[kfilter->read_data_len++] = b; } if (rcount) *rcount = in_buflen - buflen; } if (kfilter->in_msg_complete) { char tncbuf[10]; const char *auxdata[2] = { tncbuf, NULL }; count = 0; if (kfilter->read_data_pos == 0) { kfilter->curr_tnc = kfilter->read_data[0] >> 4; /* Throw away everything but data to tncs we have. */ if (kfilter->read_data[0] & 0xf || !kfilter->config.tncs[kfilter->curr_tnc]) { kfilter->in_msg_complete = false; kfilter->read_data_len = 0; kfilter->in_esc = 0; goto out_unlock; } kfilter->read_data_pos = 1; kfilter->read_data_len--; } snprintf(tncbuf, sizeof(tncbuf), "tnc:%u", kfilter->curr_tnc); kiss_unlock(kfilter); err = handler(cb_data, &count, kfilter->read_data + kfilter->read_data_pos, kfilter->read_data_len, auxdata); kiss_lock(kfilter); if (!err) { if (count >= kfilter->read_data_len) { kfilter->in_msg_complete = false; kfilter->read_data_len = 0; kfilter->read_data_pos = 0; } else { kfilter->read_data_len -= count; kfilter->read_data_pos += count; } } } out_unlock: kiss_unlock(kfilter); return err; } static int kiss_setup(struct gensio_filter *filter) { return 0; } static void kiss_filter_cleanup(struct gensio_filter *filter) { struct kiss_filter *kfilter = filter_to_kiss(filter); kfilter->read_data_len = 0; kfilter->read_data_pos = 0; kfilter->write_data_len = 0; kfilter->write_data_pos = 0; kfilter->user_write_pos = 0; kfilter->in_msg_complete = false; kfilter->in_esc = false; kfilter->out_msg_ready = false; } static void kfilter_free(struct kiss_filter *kfilter) { struct gensio_os_funcs *o = kfilter->o; gensio_kiss_config_cleanup(o, &kfilter->config); if (kfilter->lock) o->free_lock(kfilter->lock); if (kfilter->setupstr) o->free(o, kfilter->setupstr); if (kfilter->read_data) o->free(o, kfilter->read_data); if (kfilter->write_data) o->free(o, kfilter->write_data); if (kfilter->filter) gensio_filter_free_data(kfilter->filter); o->free(o, kfilter); } static void kiss_free(struct gensio_filter *filter) { struct kiss_filter *kfilter = filter_to_kiss(filter); kfilter_free(kfilter); } static int gensio_kiss_filter_func(struct gensio_filter *filter, int op, void *func, void *data, gensiods *count, void *buf, const void *cbuf, gensiods buflen, const char *const *auxdata) { switch (op) { case GENSIO_FILTER_FUNC_UL_READ_PENDING: return kiss_ul_read_pending(filter); case GENSIO_FILTER_FUNC_LL_WRITE_PENDING: return kiss_ll_write_pending(filter); case GENSIO_FILTER_FUNC_LL_READ_NEEDED: return kiss_ll_read_needed(filter); case GENSIO_FILTER_FUNC_CHECK_OPEN_DONE: return kiss_check_open_done(filter, data); case GENSIO_FILTER_FUNC_TRY_CONNECT: return kiss_try_connect(filter, data); case GENSIO_FILTER_FUNC_TRY_DISCONNECT: return kiss_try_disconnect(filter, data); case GENSIO_FILTER_FUNC_UL_WRITE_SG: return kiss_ul_write(filter, func, data, count, cbuf, buflen, auxdata); case GENSIO_FILTER_FUNC_LL_WRITE: return kiss_ll_write(filter, func, data, count, buf, buflen, auxdata); case GENSIO_FILTER_FUNC_SETUP: return kiss_setup(filter); case GENSIO_FILTER_FUNC_CLEANUP: kiss_filter_cleanup(filter); return 0; case GENSIO_FILTER_FUNC_FREE: kiss_free(filter); return 0; default: return GE_NOTSUP; } } static int handle_get_ranges(bool vals[16], const char *str) { unsigned int v1, v2, i; char *end; while (*str) { if (!isdigit(*str)) return GE_INVAL; v1 = strtoul(str, &end, 10); if (*end && *end != ',' && *end != '-') return GE_INVAL; if (v1 > 15) return GE_INVAL; if (*end == '-') { str = end + 1; if (!isdigit(*str)) return GE_INVAL; v2 = strtoul(str, &end, 10); if (*end && *end != ',') return GE_INVAL; if (v2 > 15) return GE_INVAL; for (i = v1; i < v2; i++) vals[i] = true; } else { vals[v1] = true; } if (*end) str = end + 1; else str = end; } return 0; } static int gensio_kiss_config(struct gensio_pparm_info *p, struct gensio_os_funcs *o, const char * const args[], struct gensio_base_parms *parms, struct kiss_config *config) { unsigned int i; const char *str, *setupstr = NULL; bool bval; int rv; config->max_read_size = 1024; /* FIXME - magic number. */ config->max_write_size = 1024; /* FIXME - magic number. */ config->tncs[0] = true; config->txdelay = 500; config->persist = 63; config->slot_time = 100; config->full_duplex = false; config->set_hardware = 0; config->setup_delay = 1000; config->set_hardware_set = false; for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(p, args[i], "readbuf", &config->max_read_size) > 0) continue; if (gensio_pparm_ds(p, args[i], "writebuf", &config->max_write_size) > 0) continue; if (gensio_pparm_value(p, args[i], "tncs", &str) > 0) { rv = handle_get_ranges(config->tncs, str); if (rv) return rv; continue; } if (gensio_pparm_uint(p, args[i], "txdelay", &config->txdelay) > 0) { if (config->txdelay > 2550) return GE_INVAL; continue; } if (gensio_pparm_uint(p, args[i], "persist", &config->persist) > 0) { if (config->persist > 255) return GE_INVAL; continue; } if (gensio_pparm_uint(p, args[i], "slottime", &config->slot_time) > 0) { if (config->slot_time > 2550) return GE_INVAL; continue; } if (gensio_pparm_bool(p, args[i], "fullduplex", &config->full_duplex) > 0) continue; if (gensio_pparm_uint(p, args[i], "sethardware", &config->set_hardware) > 0) { if (config->set_hardware > 255) return GE_INVAL; config->set_hardware_set = true; continue; } if (gensio_pparm_bool(p, args[i], "server", &config->server) > 0) continue; if (gensio_pparm_value(p, args[i], "setupstr", &setupstr) > 0) continue; if (gensio_pparm_uint(p, args[i], "setup-delay", &config->setup_delay) > 0) continue; if (gensio_pparm_bool(p, args[i], "d710", &bval) > 0) { if (bval) config->setupstr = "xflow on\rhbaud 1200\rkiss on\rrestart\r"; continue; } if (gensio_pparm_bool(p, args[i], "d710-9600", &bval) > 0) { if (bval) config->setupstr = "xflow on\rhbaud 9600\rkiss on\rrestart\r"; continue; } if (gensio_base_parm(parms, p, args[i]) > 0) continue; gensio_pparm_unknown_parm(p, args[i]); return GE_INVAL; } if (config->max_read_size < 256) { gensio_pparm_slog(p, "readbuf must be >= 256"); return GE_INVAL; } if (config->max_write_size < 256) { gensio_pparm_slog(p, "writebuf must be >= 256"); return GE_INVAL; } if (setupstr) { config->setupstr = gensio_strdup(o, setupstr); if (!config->setupstr) return GE_NOMEM; config->setupstr_len = strlen(config->setupstr); } return 0; } static int gensio_kiss_filter_alloc(struct gensio_os_funcs *o, struct kiss_config *config, struct gensio_filter **rfilter) { struct kiss_filter *kfilter; unsigned int i; kfilter = o->zalloc(o, sizeof(*kfilter)); if (!kfilter) return GE_NOMEM; kfilter->o = o; kfilter->config = *config; if (config->setupstr) { kfilter->config.setupstr = gensio_strdup(o, config->setupstr); if (!kfilter->config.setupstr) goto out_nomem; } /* Room to double every byte and the begin and end frame markers. */ kfilter->buf_max_write = ((config->max_write_size + 2) * 2) + 2; kfilter->lock = o->alloc_lock(o); if (!kfilter->lock) goto out_nomem; kfilter->read_data = o->zalloc(o, config->max_read_size); if (!kfilter->read_data) goto out_nomem; kfilter->write_data = o->zalloc(o, kfilter->buf_max_write); if (!kfilter->write_data) goto out_nomem; kfilter->filter = gensio_filter_alloc_data(o, gensio_kiss_filter_func, kfilter); if (!kfilter->filter) goto out_nomem; for (i = 0; !config->server && i < 16; i++) { if (!config->tncs[i]) continue; kfilter->startdata[kfilter->startdata_len++] = 0xc0; kfilter->startdata[kfilter->startdata_len++] = (i << 4) | 1; kfilter->startdata[kfilter->startdata_len++] = (config->txdelay + 5) / 10; kfilter->startdata[kfilter->startdata_len++] = 0xc0; kfilter->startdata[kfilter->startdata_len++] = 0xc0; kfilter->startdata[kfilter->startdata_len++] = (i << 4) | 2; kfilter->startdata[kfilter->startdata_len++] = config->persist; kfilter->startdata[kfilter->startdata_len++] = 0xc0; kfilter->startdata[kfilter->startdata_len++] = 0xc0; kfilter->startdata[kfilter->startdata_len++] = (i << 4) | 3; kfilter->startdata[kfilter->startdata_len++] = (config->slot_time + 5) / 10; kfilter->startdata[kfilter->startdata_len++] = 0xc0; kfilter->startdata[kfilter->startdata_len++] = 0xc0; kfilter->startdata[kfilter->startdata_len++] = (i << 4) | 5; kfilter->startdata[kfilter->startdata_len++] = config->full_duplex; kfilter->startdata[kfilter->startdata_len++] = 0xc0; if (config->set_hardware_set) { kfilter->startdata[kfilter->startdata_len++] = 0xc0; kfilter->startdata[kfilter->startdata_len++] = (i << 4) | 6; kfilter->startdata[kfilter->startdata_len++] = config->set_hardware; kfilter->startdata[kfilter->startdata_len++] = 0xc0; } } *rfilter = kfilter->filter; return 0; out_nomem: kfilter_free(kfilter); return GE_NOMEM; } static int kiss_gensio_alloc2(struct gensio *child, const char *const args[], bool server, struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio_base_parms **parms, struct gensio **net) { int err; struct gensio_filter *filter; struct gensio_ll *ll; struct gensio *io; struct kiss_config config; GENSIO_DECLARE_PPGENSIO(p, o, cb, "kiss", user_data); memset(&config, 0, sizeof(config)); config.server = server; err = gensio_kiss_config(&p, 0, args, *parms, &config); if (err) goto out_err; err = gensio_kiss_filter_alloc(o, &config, &filter); if (err) goto out_err; ll = gensio_gensio_ll_alloc(o, child); if (!ll) { gensio_filter_free(filter); goto out_nomem; } gensio_ref(child); /* So gensio_ll_free doesn't free the child if fail */ io = base_gensio_alloc(o, ll, filter, child, "kiss", cb, user_data); if (!io) { gensio_ll_free(ll); gensio_filter_free(filter); goto out_nomem; } gensio_free(child); /* Lose the ref we acquired. */ err = gensio_base_parms_set(io, parms); if (err) { gensio_free(io); goto out_err; } gensio_set_is_packet(io, true); *net = io; return 0; out_nomem: err = GE_NOMEM; out_err: gensio_kiss_config_cleanup(o, &config); return err; } static int kiss_gensio_alloc(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **net) { struct gensio_base_parms *parms; int err; err = gensio_base_parms_alloc(o, true, "kiss", &parms); if (err) return err; err = kiss_gensio_alloc2(child, args, false, o, cb, user_data, &parms, net); if (parms) gensio_base_parms_free(&parms); return err; } static int str_to_kiss_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct gensio *io2; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio(str, o, cb, user_data, &io2); if (err) return err; err = kiss_gensio_alloc(io2, args, o, cb, user_data, new_gensio); if (err) gensio_free(io2); return err; } struct kissna_data { struct gensio_accepter *acc; struct gensio_os_funcs *o; gensio_accepter_event cb; struct kiss_config config; void *user_data; }; static void kissna_free(void *acc_data) { struct kissna_data *nadata = acc_data; gensio_kiss_config_cleanup(nadata->o, &nadata->config); nadata->o->free(nadata->o, nadata); } static int kissna_alloc_gensio(void *acc_data, const char * const *iargs, struct gensio *child, struct gensio **rio) { struct kissna_data *nadata = acc_data; struct gensio_base_parms *parms = NULL; int err; parms = gensio_acc_base_parms_dup(nadata->acc); if (!parms) return GE_NOMEM; err = kiss_gensio_alloc2(child, iargs, false, nadata->o, NULL, NULL, &parms, rio); if (parms) gensio_base_parms_free(&parms); return err; } static int kissna_new_child(void *acc_data, void **finish_data, struct gensio_filter **filter) { struct kissna_data *nadata = acc_data; return gensio_kiss_filter_alloc(nadata->o, &nadata->config, filter); } static int kissna_finish_parent(void *acc_data, void *finish_data, struct gensio *io) { struct kissna_data *nadata = acc_data; int err; err = gensio_acc_base_parms_apply(nadata->acc, io); if (err) return err; gensio_set_is_packet(io, true); return 0; } static int gensio_gensio_acc_kiss_cb(void *acc_data, int op, void *data1, void *data2, void *data3, const void *data4) { switch (op) { case GENSIO_GENSIO_ACC_ALLOC_GENSIO: return kissna_alloc_gensio(acc_data, data4, data1, data2); case GENSIO_GENSIO_ACC_NEW_CHILD: return kissna_new_child(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FINISH_PARENT: return kissna_finish_parent(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FREE: kissna_free(acc_data); return 0; default: return GE_NOTSUP; } } static int kiss_gensio_accepter_alloc(struct gensio_accepter *child, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { struct kissna_data *nadata = NULL; int err; struct gensio_base_parms *parms = NULL; GENSIO_DECLARE_PPACCEPTER(p, o, cb, "kiss", user_data); err = gensio_base_parms_alloc(o, true, "kiss", &parms); if (err) goto out_err; nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) goto out_nomem; nadata->config.server = true; err = gensio_kiss_config(&p, o, args, parms, &nadata->config); if (err) goto out_err; nadata->o = o; nadata->cb = cb; nadata->user_data = user_data; err = gensio_gensio_accepter_alloc(child, o, "kiss", cb, user_data, gensio_gensio_acc_kiss_cb, nadata, &nadata->acc); if (err) goto out_err; err = gensio_acc_base_parms_set(nadata->acc, &parms); if (err) goto out_err; gensio_acc_set_is_packet(nadata->acc, true); *accepter = nadata->acc; return 0; out_nomem: err = GE_NOMEM; out_err: if (nadata) { if (nadata->acc) gensio_acc_free(nadata->acc); else kissna_free(nadata); } if (parms) gensio_base_parms_free(&parms); return err; } static int str_to_kiss_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { int err; struct gensio_accepter *acc2 = NULL; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio_accepter(str, o, cb, user_data, &acc2); if (!err) { err = kiss_gensio_accepter_alloc(acc2, args, o, cb, user_data, acc); if (err) gensio_acc_free(acc2); } return err; } int gensio_init_kiss(struct gensio_os_funcs *o) { int rv; rv = register_filter_gensio(o, "kiss", str_to_kiss_gensio, kiss_gensio_alloc); if (rv) return rv; rv = register_filter_gensio_accepter(o, "kiss", str_to_kiss_gensio_accepter, kiss_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/gensio.c0000664000175000017500000024743515060677132010705 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "gensio_net.h" static void check_flush_sync_io(struct gensio *io); struct gensio_nocbwait { bool queued; struct gensio_waiter *waiter; struct gensio_link link; }; struct gensio { struct gensio_os_funcs *o; void *user_data; gensio_event cb; unsigned int cb_count; struct gensio_list waiters; unsigned int refcount; struct gensio_lock *lock; gensio_func func; void *gensio_data; struct gensio_frdata *frdata; const char *typename; struct gensio *child; bool is_client; bool is_packet; bool is_reliable; bool is_authenticated; bool is_encrypted; bool is_message; bool is_mux; bool is_serial; struct gensio_sync_io *sync_io; struct gensio_link link; }; static struct gensio_os_funcs *o_base; static struct gensio_once gensio_base_initialized; static struct gensio_lock *gensio_base_lock; static int gensio_base_init_rv; static gensiods num_alloced_gensios; gensiods gensio_num_alloced(void) { gensiods rv; if (!o_base) return 0; o_base->lock(gensio_base_lock); rv = num_alloced_gensios; o_base->unlock(gensio_base_lock); return rv; } static void gensio_base_init(void *cb_data) { struct gensio_os_funcs *o = cb_data; gensio_base_lock = o->alloc_lock(o); if (!gensio_base_lock) { gensio_base_init_rv = GE_NOMEM; } else { o->get_funcs(o); o_base = o; } } struct gensio * gensio_data_alloc(struct gensio_os_funcs *o, gensio_event cb, void *user_data, gensio_func func, struct gensio *child, const char *typename, void *gensio_data) { struct gensio *io; o->call_once(o, &gensio_base_initialized, gensio_base_init, o); if (gensio_base_init_rv) return NULL; io = o->zalloc(o, sizeof(*io)); if (!io) return NULL; io->refcount = 1; io->lock = o->alloc_lock(o); if (!io->lock) { o->free(o, io); return NULL; } gensio_list_init(&io->waiters); io->o = o; io->cb = cb; io->user_data = user_data; io->func = func; io->typename = typename; io->gensio_data = gensio_data; io->child = child; o_base->lock(gensio_base_lock); num_alloced_gensios++; o_base->unlock(gensio_base_lock); return io; } void gensio_data_free(struct gensio *io) { assert(gensio_list_empty(&io->waiters)); gensio_clear_sync(io); if (io->frdata && io->frdata->freed) io->frdata->freed(io, io->frdata); io->o->free_lock(io->lock); io->o->free(io->o, io); o_base->lock(gensio_base_lock); num_alloced_gensios--; o_base->unlock(gensio_base_lock); } void * gensio_get_gensio_data(struct gensio *io) { return io->gensio_data; } gensio_event gensio_get_cb(struct gensio *io) { return io->cb; } int gensio_cb(struct gensio *io, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) { struct gensio_os_funcs *o = io->o; int rv; if (!io->cb) return GE_NOTSUP; o->lock(io->lock); io->cb_count++; o->unlock(io->lock); rv = io->cb(io, io->user_data, event, err, buf, buflen, auxdata); o->lock(io->lock); assert(io->cb_count > 0); io->cb_count--; if (io->cb_count == 0) { struct gensio_link *l, *l2; gensio_list_for_each_safe(&io->waiters, l, l2) { struct gensio_nocbwait *w = gensio_container_of(l, struct gensio_nocbwait, link); gensio_list_rm(&io->waiters, l); w->queued = false; o->wake(w->waiter); } } o->unlock(io->lock); return rv; } void gensio_gvlog(struct gensio *io, enum gensio_log_levels level, const char *log, va_list args) { struct gensio_log_data data; int rv; data.level = level; data.log = log; va_copy(data.args, args); rv = gensio_cb(io, GENSIO_EVENT_LOG, 0, (unsigned char *) &data, NULL, NULL); if (rv == GE_NOTSUP) gensio_vlog(io->o, level, log, args); va_end(data.args); } void gensio_glog(struct gensio *io, enum gensio_log_levels level, const char *log, ...) { va_list args; va_start(args, log); gensio_gvlog(io, level, log, args); va_end(args); } struct gensio_accepter { struct gensio_os_funcs *o; void *user_data; gensio_accepter_event cb; struct gensio_lock *lock; const struct gensio_accepter_functions *funcs; gensio_acc_func func; void *gensio_acc_data; struct gensio_acc_frdata *frdata; const char *typename; struct gensio_accepter *child; bool is_packet; bool is_reliable; bool is_message; bool is_mux; bool is_serial; bool sync; bool enabled; struct gensio_list pending_ios; struct gensio_list waiting_ios; struct gensio_list waiting_accepts; }; struct gensio_waiting_accept { bool queued; struct gensio_waiter *waiter; struct gensio_link link; }; struct gensio_accepter * gensio_acc_data_alloc(struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, gensio_acc_func func, struct gensio_accepter *child, const char *typename, void *gensio_acc_data) { struct gensio_accepter *acc = o->zalloc(o, sizeof(*acc)); if (!acc) return NULL; acc->lock = o->alloc_lock(o); if (!acc->lock) { o->free(o, acc); return NULL; } acc->o = o; acc->cb = cb; acc->user_data = user_data; acc->func = func; acc->typename = typename; acc->child = child; acc->gensio_acc_data = gensio_acc_data; gensio_list_init(&acc->pending_ios); gensio_list_init(&acc->waiting_ios); gensio_list_init(&acc->waiting_accepts); return acc; } void gensio_acc_data_free(struct gensio_accepter *acc) { if (acc->frdata && acc->frdata->freed) acc->frdata->freed(acc, acc->frdata); if (acc->lock) acc->o->free_lock(acc->lock); acc->o->free(acc->o, acc); } void * gensio_acc_get_gensio_data(struct gensio_accepter *acc) { return acc->gensio_acc_data; } int gensio_acc_cb(struct gensio_accepter *acc, int event, void *data) { if (event == GENSIO_ACC_EVENT_NEW_CONNECTION && acc->sync) { struct gensio *io = data; acc->o->lock(acc->lock); if (!acc->enabled) { gensio_free(io); } else { gensio_list_add_tail(&acc->waiting_ios, &io->link); if (!gensio_list_empty(&acc->waiting_accepts)) { struct gensio_link *l = gensio_list_first(&acc->waiting_accepts); struct gensio_waiting_accept *wa = gensio_container_of(l, struct gensio_waiting_accept, link); wa->queued = false; gensio_list_rm(&acc->waiting_accepts, &wa->link); acc->o->wake(wa->waiter); } } acc->o->unlock(acc->lock); return 0; } if (!acc->cb) return GE_NOTSUP; return acc->cb(acc, acc->user_data, event, data); } const char * gensio_acc_get_type(struct gensio_accepter *acc, unsigned int depth) { struct gensio_accepter *c = acc; while (depth > 0) { if (!c->child) return NULL; depth--; c = c->child; } return c->typename; } void gensio_acc_add_pending_gensio(struct gensio_accepter *acc, struct gensio *io) { gensio_list_add_tail(&acc->pending_ios, &io->link); } void gensio_acc_remove_pending_gensio(struct gensio_accepter *acc, struct gensio *io) { gensio_list_rm(&acc->pending_ios, &io->link); } void gensio_acc_set_frdata(struct gensio_accepter *acc, struct gensio_acc_frdata *frdata) { acc->frdata = frdata; } struct gensio_acc_frdata * gensio_acc_get_frdata(struct gensio_accepter *acc) { return acc->frdata; } void gensio_set_callback(struct gensio *io, gensio_event cb, void *user_data) { io->cb = cb; io->user_data = user_data; } void * gensio_get_user_data(struct gensio *io) { return io->user_data; } void gensio_set_user_data(struct gensio *io, void *user_data) { io->user_data = user_data; } int gensio_call_func(struct gensio *io, int func, gensiods *count, const void *cbuf, gensiods buflen, void *buf, const char *const *auxdata) { return io->func(io, func, count, cbuf, buflen, buf, auxdata); } int gensio_write(struct gensio *io, gensiods *count, const void *buf, gensiods buflen, const char *const *auxdata) { struct gensio_sg sg; if (buflen == 0) { if (count) *count = 0; return 0; } sg.buf = buf; sg.buflen = buflen; return io->func(io, GENSIO_FUNC_WRITE_SG, count, &sg, 1, NULL, auxdata); } int gensio_write_sg(struct gensio *io, gensiods *count, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { if (sglen == 0) { if (count) *count = 0; return 0; } return io->func(io, GENSIO_FUNC_WRITE_SG, count, sg, sglen, NULL, auxdata); } int gensio_raddr_to_str(struct gensio *io, gensiods *pos, char *buf, gensiods buflen) { gensiods dummypos = 0, curlen; char *data; int rv; if (!pos) pos = &dummypos; if (buflen > *pos) { curlen = buflen - *pos; data = buf + *pos; } else { curlen = 0; data = buf; } rv = gensio_control(io, GENSIO_CONTROL_DEPTH_FIRST, GENSIO_CONTROL_GET, GENSIO_CONTROL_RADDR, data, &curlen); if (!rv) *pos += curlen; return rv; } int gensio_get_raddr(struct gensio *io, void *addr, gensiods *addrlen) { return gensio_control(io, GENSIO_CONTROL_DEPTH_FIRST, GENSIO_CONTROL_GET, GENSIO_CONTROL_RADDR_BIN, addr, addrlen); } int gensio_open(struct gensio *io, gensio_done_err open_done, void *open_data) { return io->func(io, GENSIO_FUNC_OPEN, NULL, open_done, 0, open_data, NULL); } int gensio_open_nochild(struct gensio *io, gensio_done_err open_done, void *open_data) { return io->func(io, GENSIO_FUNC_OPEN_NOCHILD, NULL, open_done, 0, open_data, NULL); } struct gensio_open_s_data { struct gensio_os_funcs *o; int err; struct gensio_waiter *waiter; }; static void gensio_open_s_done(struct gensio *io, int err, void *cb_data) { struct gensio_open_s_data *data = cb_data; data->err = err; data->o->wake(data->waiter); } static int i_gensio_open_s(struct gensio *io, int (*func)(struct gensio *io, gensio_done_err open_done, void *open_data)) { struct gensio_os_funcs *o = io->o; struct gensio_open_s_data data; int err; data.o = o; data.err = 0; data.waiter = o->alloc_waiter(o); if (!data.waiter) return GE_NOMEM; err = func(io, gensio_open_s_done, &data); if (!err) { o->wait(data.waiter, 1, NULL); err = data.err; } o->free_waiter(data.waiter); return err; } int gensio_open_s(struct gensio *io) { return i_gensio_open_s(io, gensio_open); } int gensio_open_nochild_s(struct gensio *io) { return i_gensio_open_s(io, gensio_open_nochild); } int gensio_alloc_channel(struct gensio *io, const char * const args[], gensio_event cb, void *user_data, struct gensio **new_io) { int rv; struct gensio_func_alloc_channel_data d; d.args = args; d.cb = cb; d.user_data = user_data; rv = io->func(io, GENSIO_FUNC_ALLOC_CHANNEL, NULL, NULL, 0, &d, NULL); if (!rv) *new_io = d.new_io; return rv; } int gensio_control(struct gensio *io, int depth, bool get, unsigned int option, char *data, gensiods *datalen) { struct gensio *c = io; if (depth == GENSIO_CONTROL_DEPTH_ALL) { if (get) return GE_INVAL; while (c) { int rv = c->func(c, GENSIO_FUNC_CONTROL, datalen, &get, option, data, NULL); if (rv && rv != GE_NOTSUP) return rv; c = c->child; } return 0; } if (depth == GENSIO_CONTROL_DEPTH_FIRST) { while (c) { int rv = c->func(c, GENSIO_FUNC_CONTROL, datalen, &get, option, data, NULL); if (rv != GE_NOTSUP) return rv; c = c->child; } return GE_NOTFOUND; } if (depth < 0) return GE_INVAL; while (depth > 0) { if (!c->child) return GE_NOTFOUND; depth--; c = c->child; } return c->func(c, GENSIO_FUNC_CONTROL, datalen, &get, option, data, NULL); } int gensio_acontrol(struct gensio *io, int depth, bool get, unsigned int option, const char *data, gensiods datalen, gensio_control_done done, void *cb_data, gensio_time *timeout) { struct gensio_func_acontrol ctrldata = { .data = data, .datalen = datalen, .timeout = timeout, .done = done, .cb_data = cb_data }; struct gensio *c = io; if (depth == GENSIO_CONTROL_DEPTH_FIRST) { while (c) { int rv = c->func(c, GENSIO_FUNC_ACONTROL, NULL, &get, option, &ctrldata, NULL); if (rv != GE_NOTSUP) return rv; c = c->child; } return GE_NOTFOUND; } if (depth < 0) return GE_INVAL; while (depth > 0) { if (!c->child) return GE_NOTFOUND; depth--; c = c->child; } return c->func(c, GENSIO_FUNC_ACONTROL, NULL, &get, option, &ctrldata, NULL); } struct gensio_acontrol_s_data { bool is_get; struct gensio_os_funcs *o; struct gensio_waiter *waiter; char *data; gensiods datalen; int err; }; static void gensio_acontrol_s_done(struct gensio *io, int err, const char *str, gensiods len, void *cb_data) { struct gensio_acontrol_s_data *data = cb_data; gensiods copysize = len; data->err = err; if (!err && data->is_get) { if (copysize > data->datalen - 1) copysize = data->datalen - 1; if (copysize) memcpy(data->data, str, len); data->datalen = len; } data->o->wake(data->waiter); } int gensio_acontrol_s(struct gensio *io, int depth, bool get, unsigned int option, char *idata, gensiods *datalen, gensio_time *timeout) { struct gensio_os_funcs *o = io->o; struct gensio_acontrol_s_data data = { .is_get = get, .o = o, .waiter = o->alloc_waiter(o), .data = idata, .datalen = *datalen, .err = 0 }; int rv; if (!data.waiter) return GE_NOMEM; rv = gensio_acontrol(io, depth, get, option, idata, *datalen, gensio_acontrol_s_done, &data, timeout); if (rv) return rv; o->wait(data.waiter, 1, NULL); o->free_waiter(data.waiter); *datalen = data.datalen; return data.err; } int gensio_acontrol_s_intr(struct gensio *io, int depth, bool get, unsigned int option, char *idata, gensiods *datalen, gensio_time *timeout) { struct gensio_os_funcs *o = io->o; struct gensio_acontrol_s_data data = { .is_get = get, .o = o, .waiter = o->alloc_waiter(o), .data = idata, .datalen = *datalen, .err = 0 }; int rv; if (!data.waiter) return GE_NOMEM; rv = gensio_acontrol(io, depth, get, option, idata, *datalen, gensio_acontrol_s_done, &data, timeout); if (rv) return rv; rv = o->wait_intr(data.waiter, 1, timeout); if (rv) return rv; o->free_waiter(data.waiter); *datalen = data.datalen; return data.err; } const char * gensio_get_type(struct gensio *io, unsigned int depth) { struct gensio *c = io; while (depth > 0) { if (!c->child) return NULL; depth--; c = c->child; } return c->typename; } struct gensio * gensio_get_child(struct gensio *io, unsigned int depth) { struct gensio *c = io; while (depth > 0) { if (!c->child) return NULL; depth--; c = c->child; } return c; } int gensio_close(struct gensio *io, gensio_done close_done, void *close_data) { int rv; rv = io->func(io, GENSIO_FUNC_CLOSE, NULL, close_done, 0, close_data, NULL); if (!rv) check_flush_sync_io(io); return rv; } struct gensio_close_s_data { struct gensio_os_funcs *o; struct gensio_waiter *waiter; }; static void gensio_close_s_done(struct gensio *io, void *cb_data) { struct gensio_close_s_data *data = cb_data; data->o->wake(data->waiter); } int gensio_close_s(struct gensio *io) { struct gensio_os_funcs *o = io->o; struct gensio_close_s_data data; int err; data.o = o; data.waiter = o->alloc_waiter(o); if (!data.waiter) return GE_NOMEM; err = gensio_close(io, gensio_close_s_done, &data); if (!err) o->wait(data.waiter, 1, NULL); o->free_waiter(data.waiter); return err; } void gensio_disable(struct gensio *io) { struct gensio *c = io; while (c) { c->func(c, GENSIO_FUNC_DISABLE, NULL, NULL, 0, NULL, NULL); c = c->child; } } void gensio_free(struct gensio *io) { struct gensio_os_funcs *o = io->o; unsigned int count; o->lock(io->lock); count = --io->refcount; o->unlock(io->lock); if (count == 0) { check_flush_sync_io(io); io->func(io, GENSIO_FUNC_FREE, NULL, NULL, 0, NULL, NULL); } } void gensio_set_read_callback_enable(struct gensio *io, bool enabled) { io->func(io, GENSIO_FUNC_SET_READ_CALLBACK, NULL, NULL, enabled, NULL, NULL); } void gensio_set_write_callback_enable(struct gensio *io, bool enabled) { io->func(io, GENSIO_FUNC_SET_WRITE_CALLBACK, NULL, NULL, enabled, NULL, NULL); } void gensio_ref(struct gensio *io) { struct gensio_os_funcs *o = io->o; o->lock(io->lock); io->refcount++; o->unlock(io->lock); } bool gensio_is_client(struct gensio *io) { return io->is_client; } bool gensio_is_reliable(struct gensio *io) { return io->is_reliable; } bool gensio_is_packet(struct gensio *io) { return io->is_packet; } bool gensio_is_message(struct gensio *io) { return io->is_message; } bool gensio_is_authenticated(struct gensio *io) { return io->is_authenticated; } bool gensio_is_encrypted(struct gensio *io) { return io->is_encrypted; } bool gensio_is_mux(struct gensio *io) { return io->is_mux; } bool gensio_is_serial(struct gensio *io) { return io->is_serial; } void gensio_set_is_client(struct gensio *io, bool is_client) { io->is_client = is_client; } void gensio_set_is_reliable(struct gensio *io, bool is_reliable) { io->is_reliable = is_reliable; } void gensio_set_is_packet(struct gensio *io, bool is_packet) { io->is_packet = is_packet; } void gensio_set_is_message(struct gensio *io, bool is_message) { io->is_message = is_message; } void gensio_set_is_authenticated(struct gensio *io, bool is_authenticated) { io->is_authenticated = is_authenticated; } void gensio_set_is_encrypted(struct gensio *io, bool is_encrypted) { io->is_encrypted = is_encrypted; } void gensio_set_is_mux(struct gensio *io, bool is_mux) { io->is_mux = is_mux; } void gensio_set_is_serial(struct gensio *io, bool is_serial) { io->is_serial = is_serial; } void gensio_set_frdata(struct gensio *io, struct gensio_frdata *frdata) { io->frdata = frdata; } struct gensio_frdata * gensio_get_frdata(struct gensio *io) { return io->frdata; } void gensio_set_attr_from_child(struct gensio *io, struct gensio *child) { gensio_set_is_reliable(io, gensio_is_reliable(child)); gensio_set_is_packet(io, gensio_is_packet(child)); gensio_set_is_authenticated(io, gensio_is_authenticated(child)); gensio_set_is_encrypted(io, gensio_is_encrypted(child)); gensio_set_is_message(io, gensio_is_message(child)); gensio_set_is_serial(io, gensio_is_serial(child)); } struct gensio_accepter * gensio_acc_get_child(struct gensio_accepter *acc, unsigned int depth) { struct gensio_accepter *c = acc; while (depth > 0) { if (!c->child) return NULL; depth--; c = c->child; } return c; } void * gensio_acc_get_user_data(struct gensio_accepter *accepter) { return accepter->user_data; } void gensio_acc_set_user_data(struct gensio_accepter *accepter, void *user_data) { accepter->user_data = user_data; } void gensio_acc_set_callback(struct gensio_accepter *accepter, gensio_accepter_event cb, void *user_data) { accepter->cb = cb; accepter->user_data = user_data; } int gensio_acc_startup(struct gensio_accepter *accepter) { accepter->enabled = true; return accepter->func(accepter, GENSIO_ACC_FUNC_STARTUP, 0, NULL, NULL, NULL, NULL, NULL); } int gensio_acc_shutdown(struct gensio_accepter *accepter, gensio_acc_done shutdown_done, void *shutdown_data) { struct gensio_link *l, *l2; accepter->o->lock(accepter->lock); accepter->enabled = false; accepter->sync = false; gensio_list_for_each_safe(&accepter->waiting_accepts, l, l2) { struct gensio_waiting_accept *wa = gensio_container_of(l, struct gensio_waiting_accept, link); wa->queued = false; gensio_list_rm(&accepter->waiting_accepts, &wa->link); accepter->o->wake(wa->waiter); } gensio_list_for_each_safe(&accepter->waiting_ios, l, l2) { struct gensio *io = gensio_container_of(l, struct gensio, link); gensio_list_rm(&accepter->waiting_ios, &io->link); gensio_free(io); } accepter->o->unlock(accepter->lock); return accepter->func(accepter, GENSIO_ACC_FUNC_SHUTDOWN, 0, 0, shutdown_done, shutdown_data, NULL, NULL); } static void gensio_acc_shutdown_s_done(struct gensio_accepter *acc, void *cb_data) { struct gensio_close_s_data *data = cb_data; data->o->wake(data->waiter); } int gensio_acc_shutdown_s(struct gensio_accepter *acc) { struct gensio_os_funcs *o = acc->o; struct gensio_close_s_data data; int err; data.o = o; data.waiter = o->alloc_waiter(o); if (!data.waiter) return GE_NOMEM; err = gensio_acc_shutdown(acc, gensio_acc_shutdown_s_done, &data); if (!err) o->wait(data.waiter, 1, NULL); o->free_waiter(data.waiter); return err; } void gensio_acc_disable(struct gensio_accepter *acc) { struct gensio_accepter *c = acc; acc->enabled = false; while (c) { struct gensio_link *l, *l2; gensio_list_for_each_safe(&acc->pending_ios, l, l2) { struct gensio *io = gensio_container_of(l, struct gensio, link); gensio_acc_remove_pending_gensio(acc, io); gensio_disable(io); gensio_free(io); } gensio_list_for_each_safe(&acc->waiting_ios, l, l2) { struct gensio *io = gensio_container_of(l, struct gensio, link); gensio_list_rm(&acc->waiting_ios, &io->link); gensio_disable(io); gensio_free(io); } c->func(c, GENSIO_ACC_FUNC_DISABLE, 0, NULL, NULL, NULL, NULL, NULL); c = c->child; } } int gensio_acc_control(struct gensio_accepter *acc, int depth, bool get, unsigned int option, char *data, gensiods *datalen) { struct gensio_accepter *c = acc; if (depth == GENSIO_CONTROL_DEPTH_ALL) { if (get) return GE_INVAL; while (c) { int rv = c->func(c, GENSIO_ACC_FUNC_CONTROL, get, NULL, &option, data, NULL, datalen); if (rv && rv != GE_NOTSUP) return rv; c = c->child; } return 0; } if (depth == GENSIO_CONTROL_DEPTH_FIRST) { while (c) { int rv = c->func(c, GENSIO_ACC_FUNC_CONTROL, get, NULL, &option, data, NULL, datalen); if (rv != GE_NOTSUP) return rv; c = c->child; } return GE_NOTSUP; } if (depth < 0) return GE_INVAL; while (depth > 0) { if (!c->child) return GE_NOTFOUND; depth--; c = c->child; } return c->func(c, GENSIO_ACC_FUNC_CONTROL, get, NULL, &option, data, NULL, datalen); } void gensio_acc_set_accept_callback_enable(struct gensio_accepter *accepter, bool enabled) { accepter->func(accepter, GENSIO_ACC_FUNC_SET_ACCEPT_CALLBACK, enabled, NULL, NULL, NULL, NULL, NULL); } int gensio_acc_set_accept_callback_enable_cb(struct gensio_accepter *accepter, bool enabled, gensio_acc_done done, void *done_data) { return accepter->func(accepter, GENSIO_ACC_FUNC_SET_ACCEPT_CALLBACK, enabled, NULL, done, done_data, NULL, NULL); } struct acc_cb_enable_data { struct gensio_os_funcs *o; struct gensio_waiter *waiter; }; static void acc_cb_enable_done(struct gensio_accepter *acc, void *done_data) { struct acc_cb_enable_data *data = done_data; data->o->wake(data->waiter); } int gensio_acc_set_accept_callback_enable_s(struct gensio_accepter *accepter, bool enabled) { struct acc_cb_enable_data data; int err; data.o = accepter->o; data.waiter = data.o->alloc_waiter(data.o); if (!data.waiter) return GE_NOMEM; err = gensio_acc_set_accept_callback_enable_cb(accepter, enabled, acc_cb_enable_done, &data); if (err) { data.o->free_waiter(data.waiter); return err; } data.o->wait(data.waiter, 1, NULL); data.o->free_waiter(data.waiter); return 0; } void gensio_acc_free(struct gensio_accepter *accepter) { accepter->func(accepter, GENSIO_ACC_FUNC_FREE, 0, NULL, NULL, NULL, NULL, NULL); } int gensio_acc_str_to_gensio(struct gensio_accepter *accepter, const char *addr, gensio_event cb, void *user_data, struct gensio **new_io) { return accepter->func(accepter, GENSIO_ACC_FUNC_STR_TO_GENSIO, 0, addr, cb, user_data, NULL, new_io); } /* FIXME - this is a cheap hack and needs to be fixed. */ bool gensio_acc_exit_on_close(struct gensio_accepter *accepter) { return strcmp(accepter->typename, "stdio") == 0; } bool gensio_acc_is_reliable(struct gensio_accepter *accepter) { return accepter->is_reliable; } bool gensio_acc_is_packet(struct gensio_accepter *accepter) { return accepter->is_packet; } bool gensio_acc_is_message(struct gensio_accepter *accepter) { return accepter->is_message; } bool gensio_acc_is_mux(struct gensio_accepter *accepter) { return accepter->is_mux; } bool gensio_acc_is_serial(struct gensio_accepter *accepter) { return accepter->is_serial; } void gensio_acc_set_is_reliable(struct gensio_accepter *accepter, bool is_reliable) { accepter->is_reliable = is_reliable; } void gensio_acc_set_is_packet(struct gensio_accepter *accepter, bool is_packet) { accepter->is_packet = is_packet; } void gensio_acc_set_is_message(struct gensio_accepter *accepter, bool is_message) { accepter->is_message = is_message; } void gensio_acc_set_is_mux(struct gensio_accepter *accepter, bool is_mux) { accepter->is_mux = is_mux; } void gensio_acc_set_is_serial(struct gensio_accepter *accepter, bool is_serial) { accepter->is_serial = is_serial; } struct registered_gensio_accepter { const char *name; str_to_gensio_acc_handler handler; gensio_terminal_acc_alloch terminal_alloc; gensio_filter_acc_alloch filter_alloc; struct registered_gensio_accepter *next; }; static struct gensio_os_funcs *reg_o; static struct registered_gensio *reg_gensios; static struct gensio_lock *reg_gensio_lock; static struct registered_gensio_accepter *reg_gensio_accs; static struct gensio_lock *reg_gensio_acc_lock; static struct gensio_class_cleanup *cleanups; static struct gensio_lock *cleanups_lock; static struct gensio_once gensio_str_initialized; static int reg_gensio_rv; #define INIT_GENSIO(name) \ int gensio_init_##name(struct gensio_os_funcs *o); #include "builtin_gensios.h" #undef INIT_GENSIO static void add_default_gensios(void *cb_data) { struct gensio_os_funcs *o = cb_data; reg_o = o; reg_gensio_lock = o->alloc_lock(o); if (!reg_gensio_lock) { reg_gensio_rv = GE_NOMEM; return; } reg_gensio_acc_lock = o->alloc_lock(o); if (!reg_gensio_acc_lock) { reg_gensio_rv = GE_NOMEM; return; } cleanups_lock = o->alloc_lock(o); if (!cleanups_lock) { reg_gensio_rv = GE_NOMEM; return; } #define INIT_GENSIO(name) \ do { \ reg_gensio_rv = gensio_init_##name(o); \ if (reg_gensio_rv) \ return; \ } while(0) #include "builtin_gensios.h" #undef INIT_GENSIO } int register_base_gensio_accepter(struct gensio_os_funcs *o, const char *name, str_to_gensio_acc_handler handler, gensio_terminal_acc_alloch terminal_alloc, gensio_filter_acc_alloch filter_alloc) { struct registered_gensio_accepter *n; o->call_once(o, &gensio_str_initialized, add_default_gensios, o); if (reg_gensio_rv) return reg_gensio_rv; n = o->zalloc(o, sizeof(*n)); if (!n) return GE_NOMEM; n->name = name; n->handler = handler; n->terminal_alloc = terminal_alloc; n->filter_alloc = filter_alloc; o->lock(reg_gensio_acc_lock); n->next = reg_gensio_accs; reg_gensio_accs = n; o->unlock(reg_gensio_acc_lock); return 0; } int register_filter_gensio_accepter(struct gensio_os_funcs *o, const char *name, str_to_gensio_acc_handler handler, gensio_filter_acc_alloch alloc) { return register_base_gensio_accepter(o, name, handler, NULL, alloc); } int register_gensio_accepter(struct gensio_os_funcs *o, const char *name, str_to_gensio_acc_handler handler, gensio_terminal_acc_alloch alloc) { return register_base_gensio_accepter(o, name, handler, alloc, NULL); } static bool gensio_loadlib(struct gensio_os_funcs *o, const char *str) { const char *end = str; unsigned int len; char name[50]; while (*end && *end != '(' && *end != ',') end++; len = end - str; if (len >= sizeof(name)) return false; memcpy(name, str, len); name[len] = '\0'; if (strcmp(name, "udp") == 0 || strcmp(name, "unixdgram") == 0) strncpy(name, "dgram", sizeof(name)); else if (strcmp(name, "tcp") == 0 || strncmp(name, "unix", 4) == 0) strncpy(name, "net", sizeof(name)); else if (strcmp(name, "dev") == 0 || strcmp(name, "sdev") == 0) strncpy(name, "serialdev", sizeof(name)); return gensio_os_loadlib(o, name); } int str_to_gensio_accepter(const char *str, struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { int err = GE_INVAL; struct registered_gensio_accepter *r; size_t len; bool retried = false; o->call_once(o, &gensio_str_initialized, add_default_gensios, o); if (reg_gensio_rv) return reg_gensio_rv; while (isspace(*str)) str++; retry: for (r = reg_gensio_accs; r; r = r->next) { const char **args = NULL; len = strlen(r->name); if (strncmp(r->name, str, len) != 0 || (str[len] != ',' && str[len] != '(' && str[len])) continue; str += len; err = gensio_scan_args(o, &str, NULL, &args); if (!err) { while (isspace(*str)) str++; err = r->handler(str, args, o, cb, user_data, accepter); } if (args) gensio_argv_free(o, args); return err; } if (!retried && gensio_loadlib(o, str)) { retried = true; goto retry; } return err; } int gensio_terminal_acc_alloc(const char *gensiotype, const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { struct registered_gensio_accepter *r; bool retried = false; o->call_once(o, &gensio_str_initialized, add_default_gensios, o); if (reg_gensio_rv) return reg_gensio_rv; retry: for (r = reg_gensio_accs; r; r = r->next) { if (strcmp(r->name, gensiotype) != 0) continue; if (!r->terminal_alloc) break; return r->terminal_alloc(gdata, args, o, cb, user_data, accepter); } if (!retried && gensio_loadlib(o, gensiotype)) { retried = true; goto retry; } return GE_NOTSUP; } int gensio_filter_acc_alloc(const char *gensiotype, struct gensio_accepter *child, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { struct registered_gensio_accepter *r; bool retried = false; o->call_once(o, &gensio_str_initialized, add_default_gensios, o); if (reg_gensio_rv) return reg_gensio_rv; retry: for (r = reg_gensio_accs; r; r = r->next) { if (strcmp(r->name, gensiotype) != 0) continue; if (!r->filter_alloc) break; return r->filter_alloc(child, args, o, cb, user_data, accepter); } if (!retried && gensio_loadlib(o, gensiotype)) { retried = true; goto retry; } return GE_NOTSUP; } int str_to_gensio_accepter_child(struct gensio_accepter *child, const char *str, struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { int err = GE_INVAL; struct registered_gensio_accepter *r; size_t len; bool retried = false; o->call_once(o, &gensio_str_initialized, add_default_gensios, o); if (reg_gensio_rv) return reg_gensio_rv; while (isspace(*str)) str++; retry: for (r = reg_gensio_accs; r; r = r->next) { const char **args = NULL; len = strlen(r->name); if (strncmp(r->name, str, len) != 0 || (str[len] != ',' && str[len] != '(' && str[len])) continue; str += len; err = gensio_scan_args(o, &str, NULL, &args); if (!err) err = r->filter_alloc(child, args, o, cb, user_data, accepter); if (args) gensio_argv_free(o, args); return err; } if (!retried && gensio_loadlib(o, str)) { retried = true; goto retry; } return err; } struct registered_gensio { const char *name; str_to_gensio_handler handler; gensio_terminal_alloch terminal_alloc; gensio_filter_alloch filter_alloc; struct registered_gensio *next; }; static int register_base_gensio(struct gensio_os_funcs *o, const char *name, str_to_gensio_handler handler, gensio_terminal_alloch terminal_alloc, gensio_filter_alloch filter_alloc) { struct registered_gensio *n; o->call_once(o, &gensio_str_initialized, add_default_gensios, o); if (reg_gensio_rv) return reg_gensio_rv; n = o->zalloc(o, sizeof(*n)); if (!n) return GE_NOMEM; n->name = name; n->handler = handler; n->terminal_alloc = terminal_alloc; n->filter_alloc = filter_alloc; o->lock(reg_gensio_lock); n->next = reg_gensios; reg_gensios = n; o->unlock(reg_gensio_lock); return 0; } int register_filter_gensio(struct gensio_os_funcs *o, const char *name, str_to_gensio_handler handler, gensio_filter_alloch alloc) { return register_base_gensio(o, name, handler, NULL, alloc); } int register_gensio(struct gensio_os_funcs *o, const char *name, str_to_gensio_handler handler, gensio_terminal_alloch alloc) { return register_base_gensio(o, name, handler, alloc, NULL); } int str_to_gensio(const char *str, struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **gensio) { int err = GE_INVAL; const char **args = NULL; struct registered_gensio *r; size_t len; bool retried = false; o->call_once(o, &gensio_str_initialized, add_default_gensios, o); if (reg_gensio_rv) return reg_gensio_rv; while (isspace(*str)) str++; retry: for (r = reg_gensios; r; r = r->next) { len = strlen(r->name); if (strncmp(r->name, str, len) != 0 || (str[len] != ',' && str[len] != '(' && str[len])) continue; str += len; err = gensio_scan_args(o, &str, NULL, &args); if (!err) { while (isspace(*str)) str++; err = r->handler(str, args, o, cb, user_data, gensio); } goto out; } if (!retried && gensio_loadlib(o, str)) { retried = true; goto retry; } do { GENSIO_DECLARE_PPGENSIO(p, o, cb, "base", user_data); gensio_pparm_log(&p, "Unknown gensio type: %s", str); } while(false); out: if (args) gensio_argv_free(o, args); return err; } int gensio_terminal_alloc(const char *gensiotype, const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { struct registered_gensio *r; bool retried = false; o->call_once(o, &gensio_str_initialized, add_default_gensios, o); if (reg_gensio_rv) return reg_gensio_rv; retry: for (r = reg_gensios; r; r = r->next) { if (strcmp(r->name, gensiotype) != 0) continue; if (!r->terminal_alloc) break; return r->terminal_alloc(gdata, args, o, cb, user_data, new_gensio); } if (!retried && gensio_loadlib(o, gensiotype)) { retried = true; goto retry; } return GE_NOTSUP; } int gensio_filter_alloc(const char *gensiotype, struct gensio *child, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { struct registered_gensio *r; bool retried = false; o->call_once(o, &gensio_str_initialized, add_default_gensios, o); if (reg_gensio_rv) return reg_gensio_rv; retry: for (r = reg_gensios; r; r = r->next) { if (strcmp(r->name, gensiotype) != 0) continue; if (!r->filter_alloc) break; return r->filter_alloc(child, args, o, cb, user_data, new_gensio); } if (!retried && gensio_loadlib(o, gensiotype)) { retried = true; goto retry; } return GE_NOTSUP; } int str_to_gensio_child(struct gensio *child, const char *str, struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **gensio) { int err = 0; const char **args = NULL; struct registered_gensio *r; size_t len; bool retried = false; while (isspace(*str)) str++; retry: for (r = reg_gensios; r; r = r->next) { len = strlen(r->name); if (strncmp(r->name, str, len) != 0 || (str[len] != '(' && str[len])) continue; if (!r->filter_alloc) return GE_INVAL; str += len; err = gensio_scan_args(o, &str, NULL, &args); if (!err) err = r->filter_alloc(child, args, o, cb, user_data, gensio); if (args) gensio_argv_free(o, args); return err; } if (!retried && gensio_loadlib(o, str)) { retried = true; goto retry; } else { GENSIO_DECLARE_PPGENSIO(p, o, cb, "base", user_data); gensio_pparm_log(&p, "Unknown gensio type: %s", str); } return GE_NOTSUP; } int gensio_check_keyvalue(const char *str, const char *key, const char **value) { GENSIO_DECLARE_PPNULL(p); return gensio_pparm_value(&p, str, key, value); } int gensio_check_keyds(const char *str, const char *key, gensiods *rvalue) { GENSIO_DECLARE_PPNULL(p); return gensio_pparm_ds(&p, str, key, rvalue); } int gensio_check_keyuint(const char *str, const char *key, unsigned int *rvalue) { GENSIO_DECLARE_PPNULL(p); return gensio_pparm_uint(&p, str, key, rvalue); } int gensio_check_keyint(const char *str, const char *key, int *rvalue) { GENSIO_DECLARE_PPNULL(p); return gensio_pparm_int(&p, str, key, rvalue); } int gensio_check_keybool(const char *str, const char *key, bool *rvalue) { GENSIO_DECLARE_PPNULL(p); return gensio_pparm_bool(&p, str, key, rvalue); } int gensio_check_keyboolv(const char *str, const char *key, const char *trueval, const char *falseval, bool *rvalue) { GENSIO_DECLARE_PPNULL(p); return gensio_pparm_boolv(&p, str, key, trueval, falseval, rvalue); } int gensio_check_keyenum(const char *str, const char *key, struct gensio_enum_val *enums, int *rval) { GENSIO_DECLARE_PPNULL(p); return gensio_pparm_enum(&p, str, key, enums, rval); } int gensio_check_keyaddrs(struct gensio_os_funcs *o, const char *str, const char *key, int iprotocol, bool listen, bool require_port, struct gensio_addr **rai) { GENSIO_DECLARE_PPNULL(p); p.o = o; return gensio_pparm_addrs(&p, str, key, iprotocol, listen, require_port, rai); } int gensio_check_keyaddrs_noport(struct gensio_os_funcs *o, const char *str, const char *key, int protocol, struct gensio_addr **rai) { GENSIO_DECLARE_PPNULL(p); p.o = o; return gensio_pparm_addrs_noport(&p, str, key, protocol, rai); } int gensio_check_keymode(const char *str, const char *key, unsigned int *rmode) { GENSIO_DECLARE_PPNULL(p); return gensio_pparm_mode(&p, str, key, rmode); } int gensio_check_keyperm(const char *str, const char *key, unsigned int *rmode) { GENSIO_DECLARE_PPNULL(p); return gensio_pparm_perm(&p, str, key, rmode); } int gensio_check_keytime(const char *str, const char *key, char mod, gensio_time *rgt) { GENSIO_DECLARE_PPNULL(p); return gensio_pparm_time(&p, str, key, mod, rgt); } int gensio_check_keyfloat(const char *str, const char *key, float *rvalue) { GENSIO_DECLARE_PPNULL(p); return gensio_pparm_float(&p, str, key, rvalue); } void gensio_pparm_vlog(struct gensio_pparm_info *p, const char *log, va_list args) { struct gensio_parmlog_data data; data.log = log; va_copy(data.args, args); p->err = -1; if (p->ghandler) p->ghandler(NULL, p->user_data, GENSIO_EVENT_PARMLOG, 0, (unsigned char *) &data, NULL, NULL); else if (p->acchandler) p->acchandler(NULL, p->user_data, GENSIO_ACC_EVENT_PARMLOG, (unsigned char *) &data); va_end(data.args); } void i_gensio_pparm_log(struct gensio_pparm_info *p, const char *log, ...) { va_list args; va_start(args, log); gensio_pparm_vlog(p, log, args); va_end(args); } int gensio_pparm_value(struct gensio_pparm_info *p, const char *str, const char *key, const char **value) { size_t keylen; if (p->err) return 0; keylen = strlen(key); if (strncasecmp(str, key, keylen) != 0) return 0; if (str[keylen] != '=') return 0; *value = str + keylen + 1; return 1; } int gensio_pparm_ds(struct gensio_pparm_info *p, const char *str, const char *key, gensiods *rvalue) { const char *sval; char *end; int rv = gensio_pparm_value(p, str, key, &sval); gensiods value; if (!rv) return 0; if (!*sval) { gensio_pparm_log(p, "no value given in parameter %s", str); return -1; } value = strtoul(sval, &end, 0); if (*end != '\0') { gensio_pparm_log(p, "invalid number in parameter %s", str); return -1; } *rvalue = value; return 1; } int gensio_pparm_uint(struct gensio_pparm_info *p, const char *str, const char *key, unsigned int *rvalue) { const char *sval; char *end; int rv = gensio_pparm_value(p, str, key, &sval); unsigned long value; if (!rv) return 0; if (!*sval) { gensio_pparm_log(p, "no value given in parameter %s", str); return -1; } value = strtoul(sval, &end, 0); if (*end != '\0') { gensio_pparm_log(p, "invalid number in parameter %s", str); return -1; } if (value > UINT_MAX) { gensio_pparm_log(p, "unsigned int range exceeded in parameter %s", str); return -1; } *rvalue = value; return 1; } int gensio_pparm_int(struct gensio_pparm_info *p, const char *str, const char *key, int *rvalue) { const char *sval; char *end; int rv = gensio_pparm_value(p, str, key, &sval); long value; if (!rv) return 0; if (!*sval) { gensio_pparm_log(p, "no value given in parameter %s", str); return -1; } value = strtol(sval, &end, 0); if (*end != '\0') { gensio_pparm_log(p, "invalid number in parameter %s", str); return -1; } if (value > INT_MAX || value < INT_MIN) { gensio_pparm_log(p, "unsigned int range exceeded in parameter %s", str); } *rvalue = value; return 1; } int gensio_pparm_bool(struct gensio_pparm_info *p, const char *str, const char *key, bool *rvalue) { const char *sval; int rv; if (p->err) return 0; if (strcasecmp(str, key) == 0) { *rvalue = true; return 1; } rv = gensio_pparm_value(p, str, key, &sval); if (!rv) return 0; if (!*sval) { gensio_pparm_log(p, "no value given in parameter %s", str); return -1; } if (strcmp(sval, "true") == 0 || strcmp(sval, "1") == 0 || strcmp(sval, "yes") == 0 || strcmp(sval, "on") == 0) *rvalue = true; else if (strcmp(sval, "false") == 0 || strcmp(sval, "0") == 0 || strcmp(sval, "no") == 0 || strcmp(sval, "off") == 0) *rvalue = false; else { gensio_pparm_log(p, "invalid bool in parameter %s", str); return -1; } return 1; } int gensio_pparm_boolv(struct gensio_pparm_info *p, const char *str, const char *key, const char *trueval, const char *falseval, bool *rvalue) { const char *sval; int rv; rv = gensio_pparm_value(p, str, key, &sval); if (!rv) return 0; if (!*sval) { gensio_pparm_log(p, "no value given in parameter %s", str); return -1; } if (strcmp(sval, trueval) == 0) *rvalue = true; else if (strcmp(sval, falseval) == 0) *rvalue = false; else { gensio_pparm_log(p, "invalid bool in parameter %s", str); return -1; } return 1; } int gensio_pparm_enum(struct gensio_pparm_info *p, const char *str, const char *key, struct gensio_enum_val *enums, int *rval) { const char *sval; int rv; unsigned int i; rv = gensio_pparm_value(p, str, key, &sval); if (!rv) return 0; for (i = 0; enums[i].name; i++) { if (strcasecmp(sval, enums[i].name) == 0) { *rval = enums[i].val; return 1; } } gensio_pparm_log(p, "invalid enum value in parameter %s", str); return -1; } int gensio_pparm_addrs(struct gensio_pparm_info *p, const char *str, const char *key, int iprotocol, bool listen, bool require_port, struct gensio_addr **rai) { const char *sval; int rv; struct gensio_addr *ai; int protocol = iprotocol; bool is_port_set; rv = gensio_pparm_value(p, str, key, &sval); if (!rv) return 0; if (!*sval) { gensio_pparm_log(p, "no value given in parameter %s",str); return -1; } rv = gensio_scan_network_port(p->o, sval, listen, &ai, &protocol, &is_port_set, NULL, NULL); if (rv) { gensio_pparm_log(p, "Invalid network address in parameter %s", str); return -1; } if (require_port && !is_port_set) { gensio_pparm_log(p, "Port not set in parameter %s", str); gensio_addr_free(ai); } else if (protocol != iprotocol) { gensio_pparm_log(p, "Protocol mismatch in parameter %s", str); gensio_addr_free(ai); return -1; } if (*rai) gensio_addr_free(*rai); *rai = ai; return 1; } int gensio_pparm_addrs_noport(struct gensio_pparm_info *p, const char *str, const char *key, int protocol, struct gensio_addr **rai) { const char *sval; int rv; struct gensio_addr *ai; rv = gensio_pparm_value(p, str, key, &sval); if (!rv) return 0; if (!*sval) { gensio_pparm_log(p, "no value given in parameter %s", str); return -1; } rv = gensio_scan_network_addr(p->o, sval, protocol, &ai); if (rv) { gensio_pparm_log(p, "Invalid network address in parameter %s", str); return -1; } if (*rai) gensio_addr_free(*rai); *rai = ai; return 1; } int gensio_pparm_mode(struct gensio_pparm_info *p, const char *str, const char *key, unsigned int *rmode) { const char *sval; int rv = gensio_pparm_value(p, str, key, &sval); unsigned int mode; if (!rv) return 0; if (*sval >= '0' && *sval <= '7') { if (sval[1]) { gensio_pparm_log(p, "Invalid keymode in parameter %s", str); return -1; } *rmode = *sval - '0'; return 1; } mode = 0; while (*sval) { if (*sval == 'r') mode |= 4; else if (*sval == 'w') mode |= 2; else if (*sval == 'x') mode |= 1; else { gensio_pparm_log(p, "Invalid keymode in parameter %s", str); return -1; } sval++; } *rmode = mode; return 1; } int gensio_pparm_perm(struct gensio_pparm_info *p, const char *str, const char *key, unsigned int *rmode) { const char *sval; char *end; int rv = gensio_pparm_value(p, str, key, &sval); unsigned int mode; if (!rv) return 0; mode = strtoul(sval, &end, 8); if (end == sval || *end != '\0') { gensio_pparm_log(p, "Invalid permissions in parameter %s", str); return -1; } *rmode = mode; return 1; } int gensio_pparm_time(struct gensio_pparm_info *p, const char *str, const char *key, char mod, gensio_time *rgt) { const char *sval; char *end; int rv = gensio_pparm_value(p, str, key, &sval); gensio_time gt = { 0, 0 }; int64_t v; int64_t nsecs = 0; /* Use this to avoid overflows. */ if (!rv) return 0; while (true) { v = strtoul(sval, &end, 0); if (end == sval) { gensio_pparm_log(p, "Invalid time in parameter %s", str); return -1; } if (*end) { mod = *end; end++; } switch (mod) { case 'D': gt.secs += v * 24 * 3600; break; case 'H': gt.secs += v * 3600; break; case 'M': gt.secs += v * 60; break; case 's': gt.secs += v; break; case 'm': nsecs += GENSIO_MSECS_TO_NSECS(v); goto done; case 'u': nsecs += GENSIO_USECS_TO_NSECS(v); goto done; case 'n': nsecs += v; goto done; default: return -1; } gt.secs += nsecs / GENSIO_NSECS_IN_SEC; nsecs = nsecs % GENSIO_NSECS_IN_SEC; if (!*end) break; mod = 0; sval = end; } done: gt.nsecs = nsecs; if (*end) { gensio_pparm_log(p, "Invalid time in parameter %s", str); return -1; } *rgt = gt; return 1; } int gensio_pparm_float(struct gensio_pparm_info *p, const char *str, const char *key, float *rvalue) { const char *sval; char *end; int rv = gensio_pparm_value(p, str, key, &sval); float value; if (!rv) return 0; if (!*sval) { gensio_pparm_log(p, "no value given in parameter %s", str); return -1; } value = strtof(sval, &end); if (*end != '\0') { gensio_pparm_log(p, "invalid number in parameter %s", str); return -1; } *rvalue = value; return 1; } int gensio_pparm_argv(struct gensio_pparm_info *p, const char *str, const char *key, const char *seps, int *argc, const char ***argv) { const char *sval; int rv = gensio_pparm_value(p, str, key, &sval); if (!rv) return 0; if (!*sval) { gensio_pparm_log(p, "no value given in parameter %s", str); return -1; } rv = gensio_str_to_argv(p->o, sval, argc, argv, seps); if (rv) { gensio_pparm_log(p, "Error getting argv list for %s: %s", str, gensio_err_to_str(rv)); return -1; } return 1; } void gensio_pparm_unknown_parm(struct gensio_pparm_info *p, const char *arg) { if (p->err) return; gensio_pparm_log(p, "unknown parameter %s", arg); } void gensio_acc_vlog(struct gensio_accepter *acc, enum gensio_log_levels level, const char *str, va_list args) { struct gensio_loginfo info; if (!(gensio_get_log_mask() & (1 << level))) return; info.level = level; info.str = str; va_copy(info.args, args); acc->cb(acc, acc->user_data, GENSIO_ACC_EVENT_LOG, &info); va_end(info.args); } void gensio_acc_log(struct gensio_accepter *acc, enum gensio_log_levels level, const char *str, ...) { va_list args; va_start(args, str); gensio_acc_vlog(acc, level, str, args); va_end(args); } static struct gensio_once gensio_default_initialized; static struct gensio_lock *deflock; static struct gensio_os_funcs *deflock_osh; struct gensio_def_val { char *strval; int intval; /* data length, not including terminating \0, when data */ }; struct gensio_class_def { char *class; struct gensio_def_val val; struct gensio_class_def *next; }; struct gensio_def_entry { char *name; enum gensio_default_type type; int min; int max; struct gensio_def_val val; bool val_set; struct gensio_def_val def; const struct gensio_enum_val *enums; struct gensio_class_def *classvals; struct gensio_def_entry *next; }; #if HAVE_OPENIPMI #include #include struct gensio_enum_val shared_serial_alert_enums[] = { { "fail", ipmi_sol_serial_alerts_fail }, { "deferred", ipmi_sol_serial_alerts_deferred }, { "succeed", ipmi_sol_serial_alerts_succeed }, { NULL } }; #endif #ifdef HAVE_TCPD_H static struct gensio_enum_val tcpd_enums[] = { { "on", GENSIO_TCPD_ON }, { "print", GENSIO_TCPD_PRINT }, { "off", GENSIO_TCPD_OFF }, { NULL } }; #endif struct gensio_def_entry builtin_defaults[] = { /* Defaults for TCP, UDP, and SCTP. */ { "nodelay", GENSIO_DEFAULT_BOOL, .def.intval = 0 }, { "laddr", GENSIO_DEFAULT_STR, .def.strval = NULL }, /* TCP only */ #ifdef HAVE_TCPD_H { "tcpd", GENSIO_DEFAULT_ENUM, .enums = tcpd_enums, .def.intval = GENSIO_TCPD_ON }, #endif /* UDP only */ { "mttl", GENSIO_DEFAULT_INT, .min = 1, .max = 255, .def.intval = 1 }, /* SCTP only */ { "instreams", GENSIO_DEFAULT_INT, .min = 1, .max = INT_MAX, .def.intval = 1 }, { "ostreams", GENSIO_DEFAULT_INT, .min = 1, .max = INT_MAX, .def.intval = 1 }, { "sack_freq", GENSIO_DEFAULT_INT, .min = 0, .max = INT_MAX, .def.intval = 1 }, { "sack_delay", GENSIO_DEFAULT_INT, .min = 0, .max = INT_MAX, .def.intval = 10 }, /* TCP and SCTP, UDP get added in init as false. */ { "reuseaddr", GENSIO_DEFAULT_BOOL, .def.intval = 1 }, { "drain_timeout", GENSIO_DEFAULT_INT, .min = -1, .max = INT_MAX, .def.intval = -1, }, /* serialdev */ { "xonxoff", GENSIO_DEFAULT_BOOL, .def.intval = 0 }, { "rtscts", GENSIO_DEFAULT_BOOL, .def.intval = 0 }, { "local", GENSIO_DEFAULT_BOOL, .def.intval = 0 }, { "hangup-when-done", GENSIO_DEFAULT_INT, .def.intval = -1 }, { "custspeed", GENSIO_DEFAULT_BOOL, .def.intval = 0 }, { "rs485", GENSIO_DEFAULT_STR, .def.strval = NULL }, { "uucplock", GENSIO_DEFAULT_BOOL, .def.intval = 1 }, { "flock", GENSIO_DEFAULT_BOOL, .def.intval = 1 }, { "drain_time", GENSIO_DEFAULT_INT, .min = -1, .max = INT_MAX, .def.intval = -1, }, { "char_drain_wait",GENSIO_DEFAULT_INT, .min = -1, .max = INT_MAX, .def.intval = 50, }, /* serialdev and SOL */ { "speed", GENSIO_DEFAULT_STR, .def.strval = "9600N81" }, { "nobreak", GENSIO_DEFAULT_BOOL, .def.intval = 0 }, #if HAVE_OPENIPMI /* SOL only */ { "authenticated", GENSIO_DEFAULT_BOOL, .def.intval = 1 }, { "encrypted", GENSIO_DEFAULT_BOOL, .def.intval = 1 }, { "ack-timeout", GENSIO_DEFAULT_INT, .min = 1, .max = INT_MAX, .def.intval = 1000000 }, { "ack-retries", GENSIO_DEFAULT_INT, .min = 1, .max = INT_MAX, .def.intval = 10 }, { "shared-serial-alert", GENSIO_DEFAULT_ENUM, .enums = shared_serial_alert_enums, .def.intval = ipmi_sol_serial_alerts_fail }, { "deassert-CTS-DCD-DSR-on-connect", GENSIO_DEFAULT_BOOL, .def.intval = 0 }, #endif /* For client/server protocols. */ { "mode", GENSIO_DEFAULT_STR, .def.strval = NULL }, /* For telnet */ { "rfc2217", GENSIO_DEFAULT_BOOL, .def.intval = false }, { "winsize", GENSIO_DEFAULT_BOOL, .def.intval = false }, /* For SSL or other key authentication. */ { "CA", GENSIO_DEFAULT_STR, .def.strval = NULL }, { "cert", GENSIO_DEFAULT_STR, .def.strval = NULL }, { "key", GENSIO_DEFAULT_STR, .def.strval = NULL }, { "clientauth", GENSIO_DEFAULT_BOOL, .def.intval = false }, /* General authentication flags. */ { "allow-authfail", GENSIO_DEFAULT_BOOL, .def.intval = false }, { "username", GENSIO_DEFAULT_STR, .def.strval = NULL }, { "password", GENSIO_DEFAULT_STR, .def.strval = NULL }, { "service", GENSIO_DEFAULT_STR, .def.strval = NULL }, { "use-child-auth", GENSIO_DEFAULT_BOOL, .def.intval = false }, { "enable-password",GENSIO_DEFAULT_BOOL, .def.intval = false }, { "require-password",GENSIO_DEFAULT_BOOL, .def.intval = false }, /* For mux */ { "max-channels", GENSIO_DEFAULT_INT, .min = 1, .max = INT_MAX, .def.intval = 1000 }, /* For unix (accepter only) */ { "delsock", GENSIO_DEFAULT_BOOL, .def.intval = false }, /* * For certauth and ssl, at least. Anything that does some sort of * connection can use this to time out. Value is in seconds. */ { "con-timeout", GENSIO_DEFAULT_INT, .def.intval = 60 }, /* For mdns */ { "name", GENSIO_DEFAULT_STR, .def.strval = NULL }, { "type", GENSIO_DEFAULT_STR, .def.strval = NULL }, { "domain", GENSIO_DEFAULT_STR, .def.strval = NULL }, { "host", GENSIO_DEFAULT_STR, .def.strval = NULL }, { "interface", GENSIO_DEFAULT_INT, .min = -1, .max = INT_MAX, .def.intval = -1 }, { "nettype", GENSIO_DEFAULT_STR, .def.strval = "unspec" }, { "nostack", GENSIO_DEFAULT_BOOL, .def.intval = 0 }, { "mdnstimeout", GENSIO_DEFAULT_INT, .def.intval = 1000 }, { "ignore-v6-link-local",GENSIO_DEFAULT_BOOL,.def.intval = 0 }, { NULL } }; static struct gensio_def_entry *defaults; static int gensio_def_init_rv; static int l_gensio_set_default(struct gensio_os_funcs *o, const char *class, const char *name, const char *strval, int intval); static void l_gensio_reset_defaults(struct gensio_os_funcs *o); static void gensio_default_init(void *cb_data) { struct gensio_os_funcs *o = cb_data; deflock = o->alloc_lock(o); if (!deflock) { gensio_def_init_rv = GE_NOMEM; } else { deflock_osh = o->get_funcs(o); /* Default reuseaddr to false for UDP. */ gensio_def_init_rv = l_gensio_set_default(o, "udp", "reuseaddr", NULL, 0); } } void gensio_register_class_cleanup(struct gensio_class_cleanup *cleanup) { reg_o->lock(cleanups_lock); if (!cleanup->ginfo) { cleanup->ginfo = (void *) 1; /* Just mark it as in use. */ cleanup->next = cleanups; cleanups = cleanup; } reg_o->unlock(cleanups_lock); } void gensio_cleanup_mem(struct gensio_os_funcs *o) { struct registered_gensio_accepter *n, *n2; struct registered_gensio *g, *g2; struct gensio_class_cleanup *cl = cleanups; if (gensio_base_lock) o->free_lock(gensio_base_lock); gensio_base_lock = NULL; l_gensio_reset_defaults(o); if (deflock) o->free_lock(deflock); deflock = NULL; if (deflock_osh) deflock_osh->free_funcs(deflock_osh); deflock_osh = NULL; if (reg_gensio_acc_lock) o->free_lock(reg_gensio_acc_lock); reg_gensio_acc_lock = NULL; n = reg_gensio_accs; while (n) { n2 = n->next; o->free(o, n); n = n2; } reg_gensio_accs = NULL; if (reg_gensio_lock) o->free_lock(reg_gensio_lock); reg_gensio_lock = NULL; g = reg_gensios; while (g) { g2 = g->next; o->free(o, g); g = g2; } reg_gensios = NULL; memset(&gensio_default_initialized, 0, sizeof(gensio_default_initialized)); memset(&gensio_base_initialized, 0, sizeof(gensio_base_initialized)); cleanups = NULL; while (cl) { cl->ginfo = NULL; cl->cleanup(); cl = cl->next; } if (cleanups_lock) o->free_lock(cleanups_lock); cleanups_lock = NULL; if (o_base) { o_base->free_funcs(o_base); o_base = NULL; } reg_o = NULL; } static void gensio_reset_default(struct gensio_os_funcs *o, struct gensio_def_entry *d) { struct gensio_class_def *n, *c = d->classvals; for (; c; c = n) { n = c->next; o->free(o, c->class); if (d->type == GENSIO_DEFAULT_STR && c->val.strval) o->free(o, c->val.strval); o->free(o, c); } d->classvals = NULL; if (d->type == GENSIO_DEFAULT_STR && d->val.strval) { o->free(o, d->val.strval); d->val.strval = NULL; } d->val_set = false; } static void l_gensio_reset_defaults(struct gensio_os_funcs *o) { struct gensio_def_entry *d; unsigned int i; if (deflock) { deflock_osh->lock(deflock); for (i = 0; builtin_defaults[i].name; i++) gensio_reset_default(o, &builtin_defaults[i]); for (d = defaults; d; d = d->next) gensio_reset_default(o, d); deflock_osh->unlock(deflock); } } int gensio_reset_defaults(struct gensio_os_funcs *o) { o->call_once(o, &gensio_default_initialized, gensio_default_init, o); if (gensio_def_init_rv) return gensio_def_init_rv; l_gensio_reset_defaults(o); return 0; } static struct gensio_def_entry * gensio_lookup_default(const char *name, struct gensio_def_entry **prev, bool *isdefault) { struct gensio_def_entry *d, *p = NULL; unsigned int i; for (i = 0; builtin_defaults[i].name; i++) { if (strcmp(builtin_defaults[i].name, name) == 0) { if (prev) *prev = NULL; if (isdefault) *isdefault = true; return &builtin_defaults[i]; } } for (d = defaults; d; d = d->next) { if (strcmp(d->name, name) == 0) { if (prev) *prev = p; if (isdefault) *isdefault = false; return d; } p = d; } return NULL; } static struct gensio_class_def * gensio_lookup_default_class(struct gensio_def_entry *d, const char *class, struct gensio_class_def **prev) { struct gensio_class_def *c = d->classvals; struct gensio_class_def *p = NULL; for (; c; c = c->next) { if (strcmp(c->class, class) == 0) { if (prev) *prev = p; return c; } p = c; } return NULL; } int gensio_add_default(struct gensio_os_funcs *o, const char *name, enum gensio_default_type type, const char *strval, int intval, int minval, int maxval, const struct gensio_enum_val *enums) { int err = 0; struct gensio_def_entry *d; o->call_once(o, &gensio_default_initialized, gensio_default_init, o); if (gensio_def_init_rv) return gensio_def_init_rv; deflock_osh->lock(deflock); d = gensio_lookup_default(name, NULL, NULL); if (d) { err = GE_EXISTS; goto out_unlock; } d = o->zalloc(o, sizeof(*d)); if (!d) { err = GE_NOMEM; goto out_unlock; } d->name = gensio_strdup(o, name); if (!d->name) { o->free(o, d); err = GE_NOMEM; goto out_unlock; } d->type = type; d->min = minval; d->max = maxval; d->enums = enums; d->def.intval = intval; if (strval) { if (type == GENSIO_DEFAULT_DATA) { d->def.strval = o->zalloc(o, intval + 1); if (d->def.strval) { memcpy(d->def.strval, strval, intval); d->def.strval[intval] = '\0'; } } else { d->def.strval = gensio_strdup(o, strval); } if (!d->def.strval) { o->free(o, d->name); o->free(o, d); err = GE_NOMEM; goto out_unlock; } } d->next = defaults; defaults = d; out_unlock: deflock_osh->unlock(deflock); return err; } static int l_gensio_set_default(struct gensio_os_funcs *o, const char *class, const char *name, const char *strval, int intval) { int err = 0; struct gensio_def_entry *d; char *new_strval = NULL, *end; unsigned int i; deflock_osh->lock(deflock); d = gensio_lookup_default(name, NULL, NULL); if (!d) { err = GE_NOTFOUND; goto out_unlock; } switch (d->type) { case GENSIO_DEFAULT_ENUM: if (!strval) { err = GE_INVAL; goto out_unlock; } for (i = 0; d->enums[i].name; i++) { if (strcmp(d->enums[i].name, strval) == 0) break; } if (!d->enums[i].name) { err = GE_INVAL; goto out_unlock; } intval = d->enums[i].val; break; case GENSIO_DEFAULT_BOOL: if (strval) { if (strcmp(strval, "true") == 0 || strcmp(strval, "TRUE") == 0) { intval = 1; } else if (strcmp(strval, "false") == 0 || strcmp(strval, "FALSE") == 0) { intval = 0; } else { intval = strtoul(strval, &end, 10); if (end == strval || *end) { err = GE_INVAL; goto out_unlock; } } } else { intval = !!intval; } break; case GENSIO_DEFAULT_INT: if (strval) { intval = strtoul(strval, &end, 10); if (end == strval || *end) { err = GE_INVAL; goto out_unlock; } if (intval < d->min || intval > d->max) { err = GE_OUTOFRANGE; goto out_unlock; } } break; case GENSIO_DEFAULT_STR: if (strval) { new_strval = gensio_strdup(o, strval); if (!new_strval) { err = GE_NOMEM; goto out_unlock; } } break; case GENSIO_DEFAULT_DATA: if (intval < 0) { err = GE_INVAL; goto out_unlock; } new_strval = o->zalloc(o, intval + 1); if (!new_strval) { err = GE_NOMEM; goto out_unlock; } memcpy(new_strval, strval, intval); new_strval[intval] = '\0'; break; default: err = GE_INVAL; goto out_unlock; } if (class) { struct gensio_class_def *c = gensio_lookup_default_class(d, class, NULL); if (!c) { c = o->zalloc(o, sizeof(*c)); if (!c) { err = GE_NOMEM; goto out_unlock; } c->class = gensio_strdup(o, class); if (!c->class) { o->free(o, c); err = GE_NOMEM; goto out_unlock; } c->next = d->classvals; d->classvals = c; } c->val.intval = intval; if (d->type == GENSIO_DEFAULT_STR || d->type == GENSIO_DEFAULT_DATA) { if (c->val.strval) o->free(o, c->val.strval); c->val.strval = new_strval; new_strval = NULL; } } else { d->val.intval = intval; if (d->type == GENSIO_DEFAULT_STR || d->type == GENSIO_DEFAULT_DATA) { if (d->val.strval) o->free(o, d->val.strval); d->val.strval = new_strval; new_strval = NULL; } d->val_set = true; } out_unlock: if (new_strval) o->free(o, new_strval); deflock_osh->unlock(deflock); return err; } int gensio_set_default(struct gensio_os_funcs *o, const char *class, const char *name, const char *strval, int intval) { o->call_once(o, &gensio_default_initialized, gensio_default_init, o); if (gensio_def_init_rv) return gensio_def_init_rv; return l_gensio_set_default(o, class, name, strval, intval); } int gensio_get_default(struct gensio_os_funcs *o, const char *class, const char *name, bool classonly, enum gensio_default_type type, char **strval, int *intval) { struct gensio_def_entry *d; struct gensio_class_def *c = NULL; struct gensio_def_val *val; int err = 0; char *str; o->call_once(o, &gensio_default_initialized, gensio_default_init, o); if (gensio_def_init_rv) return gensio_def_init_rv; deflock_osh->lock(deflock); d = gensio_lookup_default(name, NULL, NULL); if (!d) { err = GE_NOTFOUND; goto out_unlock; } if (d->type != type && !(d->type == GENSIO_DEFAULT_ENUM && type == GENSIO_DEFAULT_INT) && !(d->type == GENSIO_DEFAULT_BOOL && type == GENSIO_DEFAULT_INT)) { err = GE_INVAL; goto out_unlock; } if (class) c = gensio_lookup_default_class(d, class, NULL); if (c) val = &c->val; else if (classonly) { err = GE_NOTFOUND; goto out_unlock; } else if (d->val_set) val = &d->val; else val = &d->def; switch (type) { case GENSIO_DEFAULT_BOOL: case GENSIO_DEFAULT_ENUM: case GENSIO_DEFAULT_INT: *intval = val->intval; break; case GENSIO_DEFAULT_STR: if (val->strval) { str = gensio_strdup(o, val->strval); if (!str) { err = GE_NOMEM; goto out_unlock; } *strval = str; } else { *strval = NULL; } break; case GENSIO_DEFAULT_DATA: if (val->strval) { str = o->zalloc(o, val->intval); if (!str) { err = GE_NOMEM; goto out_unlock; } memcpy(str, val->strval, (size_t) val->intval + 1); /* copy emding \0 */ *strval = str; *intval = val->intval; } else { *strval = NULL; *intval = 0; } break; default: abort(); /* Shouldn't happen. */ } out_unlock: deflock_osh->unlock(deflock); return err; } int gensio_del_default(struct gensio_os_funcs *o, const char *class, const char *name, bool delclasses) { struct gensio_def_entry *d, *prev; struct gensio_class_def *c = NULL, *prevc; bool isdefault; int err = 0; o->call_once(o, &gensio_default_initialized, gensio_default_init, o); if (gensio_def_init_rv) return gensio_def_init_rv; deflock_osh->lock(deflock); d = gensio_lookup_default(name, &prev, &isdefault); if (!d) { err = GE_NOTFOUND; goto out_unlock; } if (class) { c = gensio_lookup_default_class(d, class, &prevc); if (!c) { err = GE_NOTFOUND; goto out_unlock; } if (prevc) prevc->next = c->next; else d->classvals = c->next; if (c->val.strval) o->free(o, c->val.strval); o->free(o, c->class); o->free(o, c); goto out_unlock; } if (isdefault) { err = GE_NOTSUP; goto out_unlock; } if (d->classvals && !delclasses) { err = GE_INUSE; goto out_unlock; } if (prev) prev->next = d->next; else defaults = d->next; while (d->classvals) { c = d->classvals; d->classvals = c->next; if (c->val.strval) o->free(o, c->val.strval); o->free(o, c->class); o->free(o, c); } if (d->val.strval) o->free(o, d->val.strval); o->free(o, d->name); o->free(o, d); out_unlock: deflock_osh->unlock(deflock); return err; } int gensio_get_defaultaddr(struct gensio_os_funcs *o, const char *class, const char *name, bool classonly, int iprotocol, bool listen, bool require_port, struct gensio_addr **rai) { int err; int protocol = iprotocol; struct gensio_addr *ai; bool is_port_set; char *str; err = gensio_get_default(o, class, name, classonly, GENSIO_DEFAULT_STR, &str, NULL); if (err) return err; if (!str) return GE_NOTSUP; err = gensio_scan_network_port(o, str, listen, &ai, &protocol, &is_port_set, NULL, NULL); o->free(o, str); if (err) return err; if ((require_port && !is_port_set) || protocol != iprotocol) { gensio_addr_free(ai); return GE_INCONSISTENT; } if (*rai) gensio_addr_free(*rai); *rai = ai; return 1; } static int gensio_wait_no_cb(struct gensio *io, struct gensio_waiter *waiter, gensio_time *timeout) { struct gensio_os_funcs *o = io->o; struct gensio_nocbwait wait; int rv = 0; memset(&wait, 0, sizeof(wait)); wait.waiter = waiter; o->lock(io->lock); if (io->cb_count != 0) { wait.queued = true; gensio_list_add_tail(&io->waiters, &wait.link); o->unlock(io->lock); rv = o->wait(waiter, 1, timeout); o->lock(io->lock); if (wait.queued) { rv = GE_TIMEDOUT; gensio_list_rm(&io->waiters, &wait.link); } } o->unlock(io->lock); return rv; } struct gensio_sync_op { bool queued; unsigned char *buf; gensiods len; int err; struct gensio_waiter *waiter; struct gensio_link link; }; struct gensio_sync_io { gensio_event old_cb; struct gensio_list readops; struct gensio_list writeops; int err; struct gensio_lock *lock; struct gensio_waiter *close_waiter; }; static void gensio_sync_flush_waiters(struct gensio_sync_io *sync_io, struct gensio_os_funcs *o) { struct gensio_link *l, *l2; gensio_list_for_each_safe(&sync_io->readops, l, l2) { struct gensio_sync_op *op = gensio_container_of(l, struct gensio_sync_op, link); op->err = sync_io->err; op->queued = false; o->wake(op->waiter); gensio_list_rm(&sync_io->readops, l); } gensio_list_for_each_safe(&sync_io->writeops, l, l2) { struct gensio_sync_op *op = gensio_container_of(l, struct gensio_sync_op, link); op->err = sync_io->err; op->queued = false; o->wake(op->waiter); gensio_list_rm(&sync_io->writeops, l); } } static void check_flush_sync_io(struct gensio *io) { struct gensio_sync_io *sync_io = io->sync_io; struct gensio_os_funcs *o = io->o; if (sync_io) { o->lock(sync_io->lock); if (!sync_io->err) sync_io->err = GE_LOCALCLOSED; gensio_sync_flush_waiters(sync_io, io->o); o->unlock(sync_io->lock); } } static int gensio_syncio_event(struct gensio *io, void *user_data, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) { struct gensio_os_funcs *o = io->o; struct gensio_sync_io *sync_io = io->sync_io; gensiods done_len; switch (event) { case GENSIO_EVENT_READ: o->lock(sync_io->lock); if (err) { if (!sync_io->err) sync_io->err = err; gensio_set_read_callback_enable(io, false); gensio_sync_flush_waiters(sync_io, o); goto read_unlock; } if (gensio_list_empty(&sync_io->readops)) { *buflen = 0; gensio_set_read_callback_enable(io, false); goto read_unlock; } done_len = *buflen; while (*buflen && !gensio_list_empty(&sync_io->readops)) { struct gensio_link *l = gensio_list_first(&sync_io->readops); struct gensio_sync_op *op = gensio_container_of(l, struct gensio_sync_op, link); gensiods len = done_len; if (len > op->len) len = op->len; memcpy(op->buf, buf, len); op->len = len; gensio_list_rm(&sync_io->readops, l); op->queued = false; o->wake(op->waiter); done_len -= len; } *buflen -= done_len; if (done_len > 0) gensio_set_read_callback_enable(io, false); read_unlock: o->unlock(sync_io->lock); return 0; case GENSIO_EVENT_WRITE_READY: o->lock(sync_io->lock); if (gensio_list_empty(&sync_io->writeops)) { gensio_set_write_callback_enable(io, false); goto write_unlock; } while (!gensio_list_empty(&sync_io->writeops)) { struct gensio_link *l = gensio_list_first(&sync_io->writeops); struct gensio_sync_op *op = gensio_container_of(l, struct gensio_sync_op, link); gensiods len = 0; err = gensio_write(io, &len, op->buf, op->len, NULL); if (err) { if (!sync_io->err) sync_io->err = err; gensio_sync_flush_waiters(sync_io, o); } else { op->buf += len; op->len -= len; if (op->len == 0) { gensio_list_rm(&sync_io->writeops, l); op->queued = false; o->wake(op->waiter); } else { break; } } } if (gensio_list_empty(&sync_io->writeops)) gensio_set_write_callback_enable(io, false); write_unlock: o->unlock(sync_io->lock); return 0; default: if (sync_io->old_cb) return sync_io->old_cb(io, io->user_data, event, err, buf, buflen, auxdata); return GE_NOTSUP; } } int gensio_set_sync(struct gensio *io) { struct gensio_os_funcs *o = io->o; struct gensio_sync_io *sync_io = o->zalloc(o, sizeof(*sync_io)); if (!sync_io) return GE_NOMEM; sync_io->lock = o->alloc_lock(o); if (!sync_io->lock) { o->free(o, sync_io); return GE_NOMEM; } sync_io->close_waiter = o->alloc_waiter(o); if (!sync_io->close_waiter) { o->free_lock(sync_io->lock); o->free(o, sync_io); return GE_NOMEM; } gensio_list_init(&sync_io->readops); gensio_list_init(&sync_io->writeops); gensio_set_read_callback_enable(io, false); gensio_set_write_callback_enable(io, false); gensio_wait_no_cb(io, sync_io->close_waiter, NULL); io->sync_io = sync_io; sync_io->old_cb = io->cb; io->cb = gensio_syncio_event; return 0; } int gensio_clear_sync(struct gensio *io) { struct gensio_os_funcs *o = io->o; struct gensio_sync_io *sync_io = io->sync_io; if (!sync_io) return GE_NOTREADY; gensio_set_read_callback_enable(io, false); gensio_set_write_callback_enable(io, false); gensio_wait_no_cb(io, sync_io->close_waiter, NULL); io->cb = sync_io->old_cb; o->free_waiter(sync_io->close_waiter); o->free_lock(sync_io->lock); o->free(o, sync_io); io->sync_io = NULL; return 0; } static int i_gensio_read_s(struct gensio *io, gensiods *count, void *data, gensiods datalen, gensio_time *timeout, bool return_on_intr) { struct gensio_os_funcs *o = io->o; struct gensio_sync_io *sync_io = io->sync_io; struct gensio_sync_op op; int rv = 0; if (!sync_io) return GE_NOTREADY; if (datalen == 0) { if (count) *count = 0; return 0; } op.queued = true; op.buf = data; op.len = datalen; op.err = 0; op.waiter = o->alloc_waiter(o); if (!op.waiter) return GE_NOMEM; o->lock(sync_io->lock); if (sync_io->err) { rv = sync_io->err; goto out_unlock; } gensio_set_read_callback_enable(io, true); memset(&op.link, 0, sizeof(op.link)); gensio_list_add_tail(&sync_io->readops, &op.link); o->unlock(sync_io->lock); retry: rv = o->wait_intr(op.waiter, 1, timeout); if (!return_on_intr && rv == GE_INTERRUPTED) goto retry; if (rv == GE_TIMEDOUT) rv = 0; o->lock(sync_io->lock); if (op.err) { rv = op.err; } else if (op.queued) { if (count) *count = 0; gensio_list_rm(&sync_io->readops, &op.link); } else if (count) { *count = op.len; } if (gensio_list_empty(&sync_io->readops)) gensio_set_read_callback_enable(io, false); out_unlock: o->unlock(sync_io->lock); o->free_waiter(op.waiter); return rv; } int gensio_read_s(struct gensio *io, gensiods *count, void *data, gensiods datalen, gensio_time *timeout) { return i_gensio_read_s(io, count, data, datalen, timeout, false); } int gensio_read_s_intr(struct gensio *io, gensiods *count, void *data, gensiods datalen, gensio_time *timeout) { return i_gensio_read_s(io, count, data, datalen, timeout, true); } static int i_gensio_write_s(struct gensio *io, gensiods *count, const void *data, gensiods datalen, gensio_time *timeout, bool return_on_intr) { struct gensio_os_funcs *o = io->o; struct gensio_sync_io *sync_io = io->sync_io; struct gensio_sync_op op; int rv = 0; gensiods origlen; if (!sync_io) return GE_NOTREADY; if (datalen == 0) { if (count) *count = 0; return 0; } origlen = datalen; op.queued = true; op.buf = (void *) data; op.len = datalen; op.err = 0; op.waiter = o->alloc_waiter(o); if (!op.waiter) return GE_NOMEM; o->lock(sync_io->lock); if (sync_io->err) { rv = sync_io->err; goto out_unlock; } gensio_set_write_callback_enable(io, true); memset(&op.link, 0, sizeof(op.link)); gensio_list_add_tail(&sync_io->writeops, &op.link); o->unlock(sync_io->lock); retry: rv = o->wait_intr(op.waiter, 1, timeout); if (!return_on_intr && rv == GE_INTERRUPTED) goto retry; if (rv == GE_TIMEDOUT) rv = 0; o->lock(sync_io->lock); if (op.queued) gensio_list_rm(&sync_io->writeops, &op.link); if (op.err) rv = op.err; else if (count) *count = origlen - op.len; if (gensio_list_empty(&sync_io->writeops)) gensio_set_write_callback_enable(io, false); out_unlock: o->unlock(sync_io->lock); o->free_waiter(op.waiter); return rv; } int gensio_write_s(struct gensio *io, gensiods *count, const void *data, gensiods datalen, gensio_time *timeout) { return i_gensio_write_s(io, count, data, datalen, timeout, false); } int gensio_write_s_intr(struct gensio *io, gensiods *count, const void *data, gensiods datalen, gensio_time *timeout) { return i_gensio_write_s(io, count, data, datalen, timeout, true); } int gensio_acc_set_sync(struct gensio_accepter *acc) { if (acc->enabled) return GE_NOTREADY; acc->sync = true; return 0; } static int i_gensio_acc_accept_s(struct gensio_accepter *acc, gensio_time *timeout, struct gensio **new_io, bool return_on_intr) { struct gensio_os_funcs *o = acc->o; struct gensio_waiting_accept wa; struct gensio_link *l; int rv = 0; memset(&wa, 0, sizeof(wa)); wa.waiter = o->alloc_waiter(o); if (!wa.waiter) return GE_NOMEM; wa.queued = true; o->lock(acc->lock); if (!gensio_list_empty(&acc->waiting_ios)) goto got_one; gensio_list_add_tail(&acc->waiting_accepts, &wa.link); o->unlock(acc->lock); retry: rv = o->wait_intr(wa.waiter, 1, timeout); if (!return_on_intr && rv == GE_INTERRUPTED) goto retry; if (rv == GE_TIMEDOUT) rv = 0; o->lock(acc->lock); if (wa.queued) { rv = GE_TIMEDOUT; gensio_list_rm(&acc->waiting_accepts, &wa.link); } else if (gensio_list_empty(&acc->waiting_ios)) { rv = GE_LOCALCLOSED; } else if (!rv) { got_one: l = gensio_list_first(&acc->waiting_ios); gensio_list_rm(&acc->waiting_ios, l); *new_io = gensio_container_of(l, struct gensio, link); } o->unlock(acc->lock); o->free_waiter(wa.waiter); return rv; } int gensio_acc_accept_s(struct gensio_accepter *acc, gensio_time *timeout, struct gensio **new_io) { return i_gensio_acc_accept_s(acc, timeout, new_io, false); } int gensio_acc_accept_s_intr(struct gensio_accepter *acc, gensio_time *timeout, struct gensio **new_io) { return i_gensio_acc_accept_s(acc, timeout, new_io, true); } void gensio_fdump_init(struct gensio_fdump *h, unsigned int indent) { h->column = 0; h->pos = 0; h->indent = indent; } void gensio_fdump_buf(FILE *f, const unsigned char *buf, gensiods len, struct gensio_fdump *h) { gensiods i, j; for (i = 0; i < len; i++) { if (h->column == 0) fprintf(f, "%*s%4.4x:", h->indent, "", h->pos); fprintf(f, " %2.2x", buf[i]); h->data[h->column++] = buf[i]; h->pos++; if (h->column == 16) { fputs(" ", f); for (j = 0; j < 16; j++) { if (isprint(h->data[j])) fputc(h->data[j], f); else fputc('.', f); } fputc('\n', f); h->column = 0; } } } void gensio_fdump_buf_finish(FILE *f, struct gensio_fdump *h) { gensiods i; if (h->column == 0) return; for (i = h->column; i < 16; i++) fputs(" ", f); fputs(" ", f); for (i = 0; i < h->column; i++) { if (isprint(h->data[i])) fputc(h->data[i], f); else fputc('.', f); } fputc('\n', f); } void gensio_time_add(gensio_time *t, gensio_time *v) { t->secs += v->secs; t->nsecs += v->nsecs; while (t->nsecs >= GENSIO_NSECS_IN_SEC) { t->secs++; t->nsecs -= GENSIO_NSECS_IN_SEC; } } void gensio_time_add_nsecs(gensio_time *t, int64_t v) { t->secs += v / GENSIO_NSECS_IN_SEC; t->nsecs += v % GENSIO_NSECS_IN_SEC; while (t->nsecs > GENSIO_NSECS_IN_SEC) { t->secs++; t->nsecs -= GENSIO_NSECS_IN_SEC; } while (t->nsecs < 0) { t->secs--; t->nsecs += GENSIO_NSECS_IN_SEC; } } int64_t gensio_time_to_msecs(gensio_time *t1) { int64_t v; v = t1->secs * 1000; v += GENSIO_NSECS_TO_MSECS(t1->nsecs); return v; } int64_t gensio_time_to_usecs(gensio_time *t1) { int64_t v; v = t1->secs * 1000000; v += GENSIO_NSECS_TO_USECS(t1->nsecs); return v; } int64_t gensio_time_to_nsecs(gensio_time *t1) { int64_t v; v = t1->secs * GENSIO_NSECS_IN_SEC; v += GENSIO_NSECS_TO_USECS(t1->nsecs); return v; } void gensio_msecs_to_time(gensio_time *t1, int64_t v) { t1->secs = v / 1000; t1->nsecs = GENSIO_MSECS_TO_NSECS(v % 1000); } void gensio_usecs_to_time(gensio_time *t1, int64_t v) { t1->secs = v / 1000000; t1->nsecs = GENSIO_USECS_TO_NSECS(v % 1000000); } void gensio_nsecs_to_time(gensio_time *t1, int64_t v) { t1->secs = v / GENSIO_NSECS_IN_SEC; t1->nsecs = v % GENSIO_NSECS_IN_SEC; } int64_t gensio_time_diff_nsecs(gensio_time *t1, gensio_time *t2) { int64_t v; v = t1->secs - t2->secs; v *= GENSIO_NSECS_IN_SEC; v += (int64_t) t1->nsecs - (int64_t) t2->nsecs; return v; } const char * gensio_parity_to_str(unsigned int ival) { switch(ival) { case 0: return "0"; case GENSIO_SER_PARITY_NONE: return "none"; case GENSIO_SER_PARITY_ODD: return "odd"; case GENSIO_SER_PARITY_EVEN: return "even"; case GENSIO_SER_PARITY_MARK: return "mark"; case GENSIO_SER_PARITY_SPACE: return "space"; default: return "?"; } } int gensio_str_to_parity(const char *sval) { if (strcmp(sval, "none") == 0) return GENSIO_SER_PARITY_NONE; if (strcmp(sval, "odd") == 0) return GENSIO_SER_PARITY_ODD; if (strcmp(sval, "even") == 0) return GENSIO_SER_PARITY_EVEN; if (strcmp(sval, "mark") == 0) return GENSIO_SER_PARITY_MARK; if (strcmp(sval, "space") == 0) return GENSIO_SER_PARITY_SPACE; return -1; } const char * gensio_flowcontrol_to_str(unsigned int ival) { switch (ival) { case 0: return "0"; case GENSIO_SER_FLOWCONTROL_NONE: return "none"; case GENSIO_SER_FLOWCONTROL_XON_XOFF: return "xonxoff"; case GENSIO_SER_FLOWCONTROL_RTS_CTS: return "rtscts"; case GENSIO_SER_FLOWCONTROL_DCD: return "dcd"; case GENSIO_SER_FLOWCONTROL_DTR: return "dtr"; case GENSIO_SER_FLOWCONTROL_DSR: return "dsr"; default: return "?"; } } int gensio_str_to_flowcontrol(const char *sval) { if (strcmp(sval, "none") == 0) return GENSIO_SER_FLOWCONTROL_NONE; if (strcmp(sval, "xonxoff") == 0) return GENSIO_SER_FLOWCONTROL_XON_XOFF; if (strcmp(sval, "rtscts") == 0) return GENSIO_SER_FLOWCONTROL_RTS_CTS; if (strcmp(sval, "dcd") == 0) return GENSIO_SER_FLOWCONTROL_DCD; if (strcmp(sval, "dtr") == 0) return GENSIO_SER_FLOWCONTROL_DTR; if (strcmp(sval, "dsr") == 0) return GENSIO_SER_FLOWCONTROL_DSR; return -1; } const char * gensio_onoff_to_str(unsigned int ival) { switch(ival) { case 0: return "0"; case GENSIO_SER_ON: return "on"; case GENSIO_SER_OFF: return "off"; default: return "?"; } } int gensio_str_to_onoff(const char *sval) { if (strcmp(sval, "on") == 0) return GENSIO_SER_ON; if (strcmp(sval, "off") == 0) return GENSIO_SER_OFF; return -1; } const char * gensio_flush_to_str(unsigned int ival) { switch(ival) { case 0: return "0"; case GENSIO_SER_FLUSH_RECV: return "recv"; case GENSIO_SER_FLUSH_XMIT: return "xmit"; case GENSIO_SER_FLUSH_BOTH: return "both"; default: return "?"; } } int gensio_str_to_flush(const char *sval) { if (strcmp(sval, "recv") == 0) return GENSIO_SER_FLUSH_RECV; if (strcmp(sval, "xmit") == 0) return GENSIO_SER_FLUSH_XMIT; if (strcmp(sval, "both") == 0) return GENSIO_SER_FLUSH_BOTH; return -1; } /* For lack of a better place to put this. */ bool gensio_uucp_locking_enabled = true; gensio-3.0.0/lib/gensio_trace.c0000664000175000017500000003471514747451760012066 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018-2025 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include #include #include enum trace_dir { DIR_NONE, DIR_READ, DIR_WRITE, DIR_BOTH }; struct trace_filter { struct gensio_filter *filter; struct gensio_os_funcs *o; struct gensio_lock *lock; enum trace_dir dir; enum trace_dir b4dir; enum trace_dir block; bool raw; char *filename; bool tr_stdout; bool tr_stderr; const char *modeflag; FILE *tr; }; #define filter_to_trace(v) ((struct trace_filter *) \ gensio_filter_get_user_data(v)) static void trace_lock(struct trace_filter *tfilter) { tfilter->o->lock(tfilter->lock); } static void trace_unlock(struct trace_filter *tfilter) { tfilter->o->unlock(tfilter->lock); } static bool trace_ul_read_pending(struct gensio_filter *filter) { return false; } static bool trace_ll_write_pending(struct gensio_filter *filter) { return false; } static bool trace_ll_read_needed(struct gensio_filter *filter) { return false; } static int trace_check_open_done(struct gensio_filter *filter, struct gensio *io) { return 0; } static int trace_try_connect(struct gensio_filter *filter, gensio_time *timeout) { struct trace_filter *tfilter = filter_to_trace(filter); if (tfilter->tr_stdout) { tfilter->tr = stdout; } else if (tfilter->tr_stderr) { tfilter->tr = stderr; } else if (tfilter->filename) { tfilter->tr = fopen(tfilter->filename, tfilter->modeflag); if (!tfilter->tr) return GE_PERM; } return 0; } static int trace_try_disconnect(struct gensio_filter *filter, gensio_time *timeout) { return 0; } static void trace_data(const char *op, struct trace_filter *tfilter, int err, gensiods written, const struct gensio_sg *sg, gensiods sglen) { struct gensio_fdump h; gensio_time time; struct gensio_os_funcs *o = tfilter->o; FILE *f = tfilter->tr; bool raw = tfilter->raw; if (!f) return; trace_lock(tfilter); o->get_monotonic_time(o, &time); if (err) { if (!raw) { fprintf(f, "%lld:%6.6d %s error: %d %s\n", (long long) time.secs, (time.nsecs + 500) / 1000, op, err, gensio_err_to_str(err)); fflush(f); } } else if (written > 0) { gensiods i, len; gensio_fdump_init(&h, 1); if (!raw) fprintf(f, "%lld:%6.6d %s (%lu):\n", (long long) time.secs, (time.nsecs + 500) / 1000, op, (unsigned long) written); for (i = 0; i < sglen && written > 0; i++, written -= len) { if (sg[i].buflen > written) len = written; else len = sg[i].buflen; if (raw) fwrite(sg[i].buf, 1, len, f); else gensio_fdump_buf(f, sg[i].buf, len, &h); } gensio_fdump_buf_finish(f, &h); fflush(f); } trace_unlock(tfilter); } static int trace_ul_write(struct gensio_filter *filter, gensio_ul_filter_data_handler handler, void *cb_data, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { struct trace_filter *tfilter = filter_to_trace(filter); int err = 0; gensiods count = 0; if (tfilter->b4dir == DIR_WRITE || tfilter->b4dir == DIR_BOTH) { unsigned int i; for (i = 0; i < sglen; i++) count += sg[i].buflen; trace_data("b4Write", tfilter, err, count, sg, sglen); } if (tfilter->block == DIR_WRITE || tfilter->block == DIR_BOTH) { if (rcount) { unsigned int i; for (i = 0; i < sglen; i++) count += sg[i].buflen; *rcount = count; } return 0; } err = handler(cb_data, &count, sg, sglen, auxdata); if (tfilter->dir == DIR_WRITE || tfilter->dir == DIR_BOTH) trace_data("Write", tfilter, err, count, sg, sglen); if (!err && rcount) *rcount = count; return err; } static int trace_ll_write(struct gensio_filter *filter, gensio_ll_filter_data_handler handler, void *cb_data, gensiods *rcount, unsigned char *buf, gensiods buflen, const char *const *auxdata) { struct trace_filter *tfilter = filter_to_trace(filter); int err = 0; gensiods count = 0; if (tfilter->b4dir == DIR_READ || tfilter->b4dir == DIR_BOTH) { struct gensio_sg sg = {buf, buflen}; trace_data("b4Read", tfilter, err, buflen, &sg, 1); } if (tfilter->block == DIR_READ || tfilter->block == DIR_BOTH) { if (rcount) *rcount = buflen; return 0; } err = handler(cb_data, &count, buf, buflen, auxdata); if (tfilter->dir == DIR_READ || tfilter->dir == DIR_BOTH) { struct gensio_sg sg = {buf, buflen}; trace_data("Read", tfilter, err, count, &sg, 1); } if (!err && rcount) *rcount = count; return err; } static int trace_setup(struct gensio_filter *filter) { return 0; } static void trace_filter_cleanup(struct gensio_filter *filter) { struct trace_filter *tfilter = filter_to_trace(filter); if (!tfilter->tr_stdout && !tfilter->tr_stderr && tfilter->tr) fclose(tfilter->tr); tfilter->tr = NULL; } static void tfilter_free(struct trace_filter *tfilter) { if (tfilter->lock) tfilter->o->free_lock(tfilter->lock); if (tfilter->filter) gensio_filter_free_data(tfilter->filter); if (tfilter->filename) tfilter->o->free(tfilter->o, tfilter->filename); tfilter->o->free(tfilter->o, tfilter); } static void trace_free(struct gensio_filter *filter) { struct trace_filter *tfilter = filter_to_trace(filter); tfilter_free(tfilter); } static int gensio_trace_filter_func(struct gensio_filter *filter, int op, void *func, void *data, gensiods *count, void *buf, const void *cbuf, gensiods buflen, const char *const *auxdata) { switch (op) { case GENSIO_FILTER_FUNC_UL_READ_PENDING: return trace_ul_read_pending(filter); case GENSIO_FILTER_FUNC_LL_WRITE_PENDING: return trace_ll_write_pending(filter); case GENSIO_FILTER_FUNC_LL_READ_NEEDED: return trace_ll_read_needed(filter); case GENSIO_FILTER_FUNC_CHECK_OPEN_DONE: return trace_check_open_done(filter, data); case GENSIO_FILTER_FUNC_TRY_CONNECT: return trace_try_connect(filter, data); case GENSIO_FILTER_FUNC_TRY_DISCONNECT: return trace_try_disconnect(filter, data); case GENSIO_FILTER_FUNC_UL_WRITE_SG: return trace_ul_write(filter, func, data, count, cbuf, buflen, auxdata); case GENSIO_FILTER_FUNC_LL_WRITE: return trace_ll_write(filter, func, data, count, buf, buflen, auxdata); case GENSIO_FILTER_FUNC_SETUP: return trace_setup(filter); case GENSIO_FILTER_FUNC_CLEANUP: trace_filter_cleanup(filter); return 0; case GENSIO_FILTER_FUNC_FREE: trace_free(filter); return 0; case GENSIO_FILTER_FUNC_CONTROL: return GE_NOTSUP; default: return GE_NOTSUP; } } static struct gensio_filter * gensio_trace_filter_raw_alloc(struct gensio_os_funcs *o, enum trace_dir dir, enum trace_dir b4dir, enum trace_dir block, bool raw, const char *filename, bool tr_stdout, bool tr_stderr, const char *modeflag) { struct trace_filter *tfilter; if (!filename && !tr_stdout && !tr_stderr) dir = DIR_NONE; tfilter = o->zalloc(o, sizeof(*tfilter)); if (!tfilter) return NULL; tfilter->o = o; tfilter->dir = dir; tfilter->b4dir = b4dir; tfilter->block = block; tfilter->raw = raw; if (filename) { tfilter->filename = gensio_strdup(o, filename); if (!tfilter->filename) goto out_nomem; } tfilter->tr_stdout = tr_stdout; tfilter->tr_stderr = tr_stderr; tfilter->modeflag = modeflag; tfilter->lock = o->alloc_lock(o); if (!tfilter->lock) goto out_nomem; tfilter->filter = gensio_filter_alloc_data(o, gensio_trace_filter_func, tfilter); if (!tfilter->filter) goto out_nomem; return tfilter->filter; out_nomem: tfilter_free(tfilter); return NULL; } static struct gensio_enum_val trace_dir_enum[] = { { "none", DIR_NONE }, { "read", DIR_READ }, { "write", DIR_WRITE }, { "both", DIR_BOTH }, { NULL } }; static int gensio_trace_filter_alloc(struct gensio_pparm_info *p, struct gensio_os_funcs *o, const char * const args[], struct gensio_filter **rfilter) { struct gensio_filter *filter; int dir = DIR_NONE, b4dir = DIR_NONE; int block = DIR_NONE; bool raw = false, tr_stdout = false, tr_stderr = false, tbool; const char *filename = NULL; unsigned int i; const char *modeflag = "a"; for (i = 0; args && args[i]; i++) { if (gensio_pparm_enum(p, args[i], "dir", trace_dir_enum, &dir) > 0) continue; if (gensio_pparm_enum(p, args[i], "b4dir", trace_dir_enum, &b4dir) > 0) continue; if (gensio_pparm_enum(p, args[i], "block", trace_dir_enum, &block) > 0) continue; if (gensio_pparm_bool(p, args[i], "raw", &raw) > 0) continue; if (gensio_pparm_value(p, args[i], "file", &filename) > 0) continue; if (gensio_pparm_bool(p, args[i], "stdout", &tr_stdout) > 0) continue; if (gensio_pparm_bool(p, args[i], "stderr", &tr_stderr) > 0) continue; if (gensio_pparm_bool(p, args[i], "delold", &tbool) > 0) { if (tbool) modeflag = "w"; continue; } gensio_pparm_unknown_parm(p, args[i]); return GE_INVAL; } filter = gensio_trace_filter_raw_alloc(o, dir, b4dir, block, raw, filename, tr_stdout, tr_stderr, modeflag); if (!filter) return GE_NOMEM; *rfilter = filter; return 0; } static int trace_gensio_alloc(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **net) { int err; struct gensio_filter *filter; struct gensio_ll *ll; struct gensio *io; GENSIO_DECLARE_PPGENSIO(p, o, cb, "trace", user_data); err = gensio_trace_filter_alloc(&p, o, args, &filter); if (err) return err; ll = gensio_gensio_ll_alloc(o, child); if (!ll) { gensio_filter_free(filter); return GE_NOMEM; } gensio_ref(child); /* So gensio_ll_free doesn't free the child if fail */ io = base_gensio_alloc(o, ll, filter, child, "trace", cb, user_data); if (!io) { gensio_ll_free(ll); gensio_filter_free(filter); return GE_NOMEM; } gensio_set_attr_from_child(io, child); gensio_free(child); /* Lose the ref we acquired. */ *net = io; return 0; } static int str_to_trace_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct gensio *io2; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio(str, o, cb, user_data, &io2); if (err) return err; err = trace_gensio_alloc(io2, args, o, cb, user_data, new_gensio); if (err) gensio_free(io2); return err; } struct tracena_data { struct gensio_accepter *acc; const char **args; struct gensio_os_funcs *o; gensio_accepter_event cb; void *user_data; }; static void tracena_free(void *acc_data) { struct tracena_data *nadata = acc_data; if (nadata->args) gensio_argv_free(nadata->o, nadata->args); nadata->o->free(nadata->o, nadata); } static int tracena_alloc_gensio(void *acc_data, const char * const *iargs, struct gensio *child, struct gensio **rio) { struct tracena_data *nadata = acc_data; return trace_gensio_alloc(child, iargs, nadata->o, NULL, NULL, rio); } static int tracena_new_child(void *acc_data, void **finish_data, struct gensio_filter **filter) { struct tracena_data *nadata = acc_data; GENSIO_DECLARE_PPACCEPTER(p, nadata->o, nadata->cb, "trace", nadata->user_data); return gensio_trace_filter_alloc(&p, nadata->o, nadata->args, filter); } static int tracena_finish_parent(void *acc_data, void *finish_data, struct gensio *io) { gensio_set_attr_from_child(io, gensio_get_child(io, 0)); return 0; } static int gensio_gensio_acc_trace_cb(void *acc_data, int op, void *data1, void *data2, void *data3, const void *data4) { switch (op) { case GENSIO_GENSIO_ACC_ALLOC_GENSIO: return tracena_alloc_gensio(acc_data, data4, data1, data2); case GENSIO_GENSIO_ACC_NEW_CHILD: return tracena_new_child(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FINISH_PARENT: return tracena_finish_parent(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FREE: tracena_free(acc_data); return 0; default: return GE_NOTSUP; } } static int trace_gensio_accepter_alloc(struct gensio_accepter *child, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { struct tracena_data *nadata; int err; nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) return GE_NOMEM; err = gensio_argv_copy(o, args, NULL, &nadata->args); if (err) { o->free(o, nadata); return err; } nadata->o = o; nadata->cb = cb; nadata->user_data = user_data; err = gensio_gensio_accepter_alloc(child, o, "trace", cb, user_data, gensio_gensio_acc_trace_cb, nadata, &nadata->acc); if (err) goto out_err; gensio_acc_set_is_reliable(nadata->acc, gensio_acc_is_reliable(child)); gensio_acc_set_is_packet(nadata->acc, gensio_acc_is_packet(child)); gensio_acc_set_is_message(nadata->acc, gensio_acc_is_message(child)); *accepter = nadata->acc; return 0; out_err: tracena_free(nadata); return err; } static int str_to_trace_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { int err; struct gensio_accepter *acc2 = NULL; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio_accepter(str, o, cb, user_data, &acc2); if (!err) { err = trace_gensio_accepter_alloc(acc2, args, o, cb, user_data, acc); if (err) gensio_acc_free(acc2); } return err; } int gensio_init_trace(struct gensio_os_funcs *o) { int rv; rv = register_filter_gensio(o, "trace", str_to_trace_gensio, trace_gensio_alloc); if (rv) return rv; rv = register_filter_gensio_accepter(o, "trace", str_to_trace_gensio_accepter, trace_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/seriallock.h0000664000175000017500000000106714664224267011551 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include #include #include void serial_rm_lock(struct gensio_os_funcs *o, struct gensio_ll *ll, bool do_uucp_lock, bool do_flock, int fd, const char *devname); /* Returns gensio errno. */ int serial_mk_lock(struct gensio_os_funcs *o, struct gensio_ll *ll, bool do_uucp_lock, bool do_flock, int fd, const char *devname); gensio-3.0.0/lib/Makefile.in0000664000175000017500000045436715061121660011315 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @HAVE_UNIX_OS_TRUE@am__append_1 = os_unix.c os_unix_selector.c @HAVE_WINDOWS_OS_TRUE@am__append_2 = os_win.c @ENABLE_INTERNAL_TRACE_TRUE@am__append_3 = errtrig.c @HAVE_OPENIPMI_TRUE@am__append_4 = libgensio_openipmi_oshandler.la @BUILTIN_NET_TRUE@am__append_5 = gensio_net.c @BUILTIN_NET_FALSE@am__append_6 = libgensio_net.la @BUILTIN_DGRAM_TRUE@am__append_7 = gensio_dgram.c @BUILTIN_DGRAM_FALSE@am__append_8 = libgensio_dgram.la @BUILTIN_SCTP_TRUE@am__append_9 = gensio_sctp.c @BUILTIN_SCTP_FALSE@am__append_10 = libgensio_sctp.la @BUILTIN_STDIO_TRUE@am__append_11 = gensio_stdio.c @BUILTIN_STDIO_FALSE@am__append_12 = libgensio_stdio.la @BUILTIN_PTY_TRUE@am__append_13 = gensio_pty.c @BUILTIN_PTY_FALSE@am__append_14 = libgensio_pty.la @BUILTIN_DUMMY_TRUE@am__append_15 = gensio_dummy.c @BUILTIN_DUMMY_FALSE@am__append_16 = libgensio_dummy.la @BUILTIN_CONACC_TRUE@am__append_17 = gensio_conacc.c @BUILTIN_CONACC_FALSE@am__append_18 = libgensio_conacc.la @BUILTIN_SERIALDEV_TRUE@am__append_19 = sergensio_serialdev.c seriallock.c @BUILTIN_SERIALDEV_FALSE@am__append_20 = libgensio_serialdev.la @BUILTIN_ECHO_TRUE@am__append_21 = gensio_echo.c @BUILTIN_ECHO_FALSE@am__append_22 = libgensio_echo.la @BUILTIN_FILE_TRUE@am__append_23 = gensio_file.c @BUILTIN_FILE_FALSE@am__append_24 = libgensio_file.la @BUILTIN_IPMISOL_TRUE@am__append_25 = sergensio_ipmisol.c @BUILTIN_IPMISOL_FALSE@am__append_26 = libgensio_ipmisol.la @BUILTIN_MDNS_TRUE@@HAVE_MDNS_TRUE@am__append_27 = gensio_mdns.c @BUILTIN_MDNS_TRUE@@HAVE_MDNS_TRUE@am__append_28 = libgensiomdns.la @BUILTIN_MDNS_FALSE@@HAVE_MDNS_TRUE@am__append_29 = libgensio_mdns.la @HAVE_MDNS_TRUE@am__append_30 = $(DYNAMIC_MDNS) @BUILTIN_SOUND_TRUE@am__append_31 = gensio_sound.c @BUILTIN_SOUND_FALSE@am__append_32 = libgensio_sound.la @BUILTIN_CM108GPIO_TRUE@am__append_33 = gensio_cm108gpio.c @BUILTIN_CM108GPIO_FALSE@am__append_34 = libgensio_cm108gpio.la @BUILTIN_SSL_TRUE@am__append_35 = gensio_ssl.c @BUILTIN_SSL_FALSE@am__append_36 = libgensio_ssl.la @BUILTIN_CERTAUTH_TRUE@am__append_37 = gensio_certauth.c @BUILTIN_CERTAUTH_FALSE@am__append_38 = libgensio_certauth.la @BUILTIN_MUX_TRUE@am__append_39 = gensio_mux.c @BUILTIN_MUX_FALSE@am__append_40 = libgensio_mux.la @BUILTIN_TELNET_TRUE@am__append_41 = sergensio_telnet.c telnet.c @BUILTIN_TELNET_FALSE@am__append_42 = libgensio_telnet.la @BUILTIN_MSGDELIM_TRUE@am__append_43 = gensio_msgdelim.c @BUILTIN_MSGDELIM_FALSE@am__append_44 = libgensio_msgdelim.la @BUILTIN_RELPKT_TRUE@am__append_45 = gensio_relpkt.c @BUILTIN_RELPKT_FALSE@am__append_46 = libgensio_relpkt.la @BUILTIN_TRACE_TRUE@am__append_47 = gensio_trace.c @BUILTIN_TRACE_FALSE@am__append_48 = libgensio_trace.la @BUILTIN_PERF_TRUE@am__append_49 = gensio_perf.c @BUILTIN_PERF_FALSE@am__append_50 = libgensio_perf.la @BUILTIN_KISS_TRUE@am__append_51 = gensio_kiss.c @BUILTIN_KISS_FALSE@am__append_52 = libgensio_kiss.la @BUILTIN_AX25_TRUE@am__append_53 = gensio_ax25.c @BUILTIN_AX25_FALSE@am__append_54 = libgensio_ax25.la @BUILTIN_XLT_TRUE@am__append_55 = gensio_xlt.c @BUILTIN_XLT_FALSE@am__append_56 = libgensio_xlt.la @BUILTIN_KEEPOPEN_TRUE@am__append_57 = gensio_keepopen.c @BUILTIN_KEEPOPEN_FALSE@am__append_58 = libgensio_keepopen.la @BUILTIN_SCRIPT_TRUE@am__append_59 = gensio_script.c @BUILTIN_SCRIPT_FALSE@am__append_60 = libgensio_script.la @BUILTIN_RATELIMIT_TRUE@am__append_61 = gensio_ratelimit.c @BUILTIN_RATELIMIT_FALSE@am__append_62 = libgensio_ratelimit.la @BUILTIN_AFSKMDM_TRUE@am__append_63 = gensio_afskmdm.c @BUILTIN_AFSKMDM_TRUE@am__append_64 = -lm @BUILTIN_AFSKMDM_FALSE@am__append_65 = libgensio_afskmdm.la subdir = lib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = libgensioosh.pc libgensio.pc libgensiomdns.pc CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(gensiolibexecdir)" \ "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigexecdir)" LTLIBRARIES = $(gensiolibexec_LTLIBRARIES) $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = libgensio_la_DEPENDENCIES = libgensioosh.la $(am__append_28) \ $(am__DEPENDENCIES_1) am__libgensio_la_SOURCES_DIST = gensio.c gensio_base.c buffer.c \ ll_fd.c ll_gensio.c acc.c acc_gensio.c gensio_net.c \ gensio_dgram.c gensio_sctp.c gensio_stdio.c gensio_pty.c \ gensio_dummy.c gensio_conacc.c sergensio_serialdev.c \ seriallock.c gensio_echo.c gensio_file.c sergensio_ipmisol.c \ gensio_mdns.c gensio_sound.c gensio_cm108gpio.c gensio_ssl.c \ gensio_certauth.c gensio_mux.c sergensio_telnet.c telnet.c \ gensio_msgdelim.c gensio_relpkt.c gensio_trace.c gensio_perf.c \ gensio_kiss.c gensio_ax25.c gensio_xlt.c gensio_keepopen.c \ gensio_script.c gensio_ratelimit.c gensio_afskmdm.c @BUILTIN_NET_TRUE@am__objects_1 = libgensio_la-gensio_net.lo @BUILTIN_DGRAM_TRUE@am__objects_2 = libgensio_la-gensio_dgram.lo @BUILTIN_SCTP_TRUE@am__objects_3 = libgensio_la-gensio_sctp.lo @BUILTIN_STDIO_TRUE@am__objects_4 = libgensio_la-gensio_stdio.lo @BUILTIN_PTY_TRUE@am__objects_5 = libgensio_la-gensio_pty.lo @BUILTIN_DUMMY_TRUE@am__objects_6 = libgensio_la-gensio_dummy.lo @BUILTIN_CONACC_TRUE@am__objects_7 = libgensio_la-gensio_conacc.lo @BUILTIN_SERIALDEV_TRUE@am__objects_8 = \ @BUILTIN_SERIALDEV_TRUE@ libgensio_la-sergensio_serialdev.lo \ @BUILTIN_SERIALDEV_TRUE@ libgensio_la-seriallock.lo @BUILTIN_ECHO_TRUE@am__objects_9 = libgensio_la-gensio_echo.lo @BUILTIN_FILE_TRUE@am__objects_10 = libgensio_la-gensio_file.lo @BUILTIN_IPMISOL_TRUE@am__objects_11 = \ @BUILTIN_IPMISOL_TRUE@ libgensio_la-sergensio_ipmisol.lo @BUILTIN_MDNS_TRUE@@HAVE_MDNS_TRUE@am__objects_12 = libgensio_la-gensio_mdns.lo @BUILTIN_SOUND_TRUE@am__objects_13 = libgensio_la-gensio_sound.lo @BUILTIN_CM108GPIO_TRUE@am__objects_14 = \ @BUILTIN_CM108GPIO_TRUE@ libgensio_la-gensio_cm108gpio.lo @BUILTIN_SSL_TRUE@am__objects_15 = libgensio_la-gensio_ssl.lo @BUILTIN_CERTAUTH_TRUE@am__objects_16 = \ @BUILTIN_CERTAUTH_TRUE@ libgensio_la-gensio_certauth.lo @BUILTIN_MUX_TRUE@am__objects_17 = libgensio_la-gensio_mux.lo @BUILTIN_TELNET_TRUE@am__objects_18 = \ @BUILTIN_TELNET_TRUE@ libgensio_la-sergensio_telnet.lo \ @BUILTIN_TELNET_TRUE@ libgensio_la-telnet.lo @BUILTIN_MSGDELIM_TRUE@am__objects_19 = \ @BUILTIN_MSGDELIM_TRUE@ libgensio_la-gensio_msgdelim.lo @BUILTIN_RELPKT_TRUE@am__objects_20 = libgensio_la-gensio_relpkt.lo @BUILTIN_TRACE_TRUE@am__objects_21 = libgensio_la-gensio_trace.lo @BUILTIN_PERF_TRUE@am__objects_22 = libgensio_la-gensio_perf.lo @BUILTIN_KISS_TRUE@am__objects_23 = libgensio_la-gensio_kiss.lo @BUILTIN_AX25_TRUE@am__objects_24 = libgensio_la-gensio_ax25.lo @BUILTIN_XLT_TRUE@am__objects_25 = libgensio_la-gensio_xlt.lo @BUILTIN_KEEPOPEN_TRUE@am__objects_26 = \ @BUILTIN_KEEPOPEN_TRUE@ libgensio_la-gensio_keepopen.lo @BUILTIN_SCRIPT_TRUE@am__objects_27 = libgensio_la-gensio_script.lo @BUILTIN_RATELIMIT_TRUE@am__objects_28 = \ @BUILTIN_RATELIMIT_TRUE@ libgensio_la-gensio_ratelimit.lo @BUILTIN_AFSKMDM_TRUE@am__objects_29 = libgensio_la-gensio_afskmdm.lo am_libgensio_la_OBJECTS = libgensio_la-gensio.lo \ libgensio_la-gensio_base.lo libgensio_la-buffer.lo \ libgensio_la-ll_fd.lo libgensio_la-ll_gensio.lo \ libgensio_la-acc.lo libgensio_la-acc_gensio.lo \ $(am__objects_1) $(am__objects_2) $(am__objects_3) \ $(am__objects_4) $(am__objects_5) $(am__objects_6) \ $(am__objects_7) $(am__objects_8) $(am__objects_9) \ $(am__objects_10) $(am__objects_11) $(am__objects_12) \ $(am__objects_13) $(am__objects_14) $(am__objects_15) \ $(am__objects_16) $(am__objects_17) $(am__objects_18) \ $(am__objects_19) $(am__objects_20) $(am__objects_21) \ $(am__objects_22) $(am__objects_23) $(am__objects_24) \ $(am__objects_25) $(am__objects_26) $(am__objects_27) \ $(am__objects_28) $(am__objects_29) libgensio_la_OBJECTS = $(am_libgensio_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libgensio_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libgensio_la_LDFLAGS) $(LDFLAGS) -o $@ libgensio_afskmdm_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_afskmdm_la_OBJECTS = gensio_afskmdm.lo libgensio_afskmdm_la_OBJECTS = $(am_libgensio_afskmdm_la_OBJECTS) libgensio_afskmdm_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_afskmdm_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILTIN_AFSKMDM_FALSE@am_libgensio_afskmdm_la_rpath = libgensio_ax25_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_ax25_la_OBJECTS = gensio_ax25.lo libgensio_ax25_la_OBJECTS = $(am_libgensio_ax25_la_OBJECTS) libgensio_ax25_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_ax25_la_LDFLAGS) $(LDFLAGS) \ -o $@ @BUILTIN_AX25_FALSE@am_libgensio_ax25_la_rpath = libgensio_certauth_la_DEPENDENCIES = $(DYNAMIC_LIBS) \ $(am__DEPENDENCIES_1) am_libgensio_certauth_la_OBJECTS = \ libgensio_certauth_la-gensio_certauth.lo libgensio_certauth_la_OBJECTS = $(am_libgensio_certauth_la_OBJECTS) libgensio_certauth_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_certauth_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILTIN_CERTAUTH_FALSE@am_libgensio_certauth_la_rpath = libgensio_cm108gpio_la_DEPENDENCIES = $(DYNAMIC_LIBS) \ $(am__DEPENDENCIES_1) am_libgensio_cm108gpio_la_OBJECTS = gensio_cm108gpio.lo libgensio_cm108gpio_la_OBJECTS = $(am_libgensio_cm108gpio_la_OBJECTS) libgensio_cm108gpio_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_cm108gpio_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILTIN_CM108GPIO_FALSE@am_libgensio_cm108gpio_la_rpath = libgensio_conacc_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_conacc_la_OBJECTS = gensio_conacc.lo libgensio_conacc_la_OBJECTS = $(am_libgensio_conacc_la_OBJECTS) libgensio_conacc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_conacc_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILTIN_CONACC_FALSE@am_libgensio_conacc_la_rpath = libgensio_dgram_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_dgram_la_OBJECTS = gensio_dgram.lo libgensio_dgram_la_OBJECTS = $(am_libgensio_dgram_la_OBJECTS) libgensio_dgram_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_dgram_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILTIN_DGRAM_FALSE@am_libgensio_dgram_la_rpath = libgensio_dummy_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_dummy_la_OBJECTS = gensio_dummy.lo libgensio_dummy_la_OBJECTS = $(am_libgensio_dummy_la_OBJECTS) libgensio_dummy_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_dummy_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILTIN_DUMMY_FALSE@am_libgensio_dummy_la_rpath = libgensio_echo_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_echo_la_OBJECTS = gensio_echo.lo libgensio_echo_la_OBJECTS = $(am_libgensio_echo_la_OBJECTS) libgensio_echo_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_echo_la_LDFLAGS) $(LDFLAGS) \ -o $@ @BUILTIN_ECHO_FALSE@am_libgensio_echo_la_rpath = libgensio_file_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_file_la_OBJECTS = gensio_file.lo libgensio_file_la_OBJECTS = $(am_libgensio_file_la_OBJECTS) libgensio_file_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_file_la_LDFLAGS) $(LDFLAGS) \ -o $@ @BUILTIN_FILE_FALSE@am_libgensio_file_la_rpath = libgensio_ipmisol_la_DEPENDENCIES = $(DYNAMIC_LIBS) \ $(am__DEPENDENCIES_1) libgensio_openipmi_oshandler.la am_libgensio_ipmisol_la_OBJECTS = \ libgensio_ipmisol_la-sergensio_ipmisol.lo libgensio_ipmisol_la_OBJECTS = $(am_libgensio_ipmisol_la_OBJECTS) libgensio_ipmisol_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libgensio_ipmisol_la_CFLAGS) $(CFLAGS) \ $(libgensio_ipmisol_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILTIN_IPMISOL_FALSE@am_libgensio_ipmisol_la_rpath = libgensio_keepopen_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_keepopen_la_OBJECTS = gensio_keepopen.lo libgensio_keepopen_la_OBJECTS = $(am_libgensio_keepopen_la_OBJECTS) libgensio_keepopen_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_keepopen_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILTIN_KEEPOPEN_FALSE@am_libgensio_keepopen_la_rpath = libgensio_kiss_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_kiss_la_OBJECTS = gensio_kiss.lo libgensio_kiss_la_OBJECTS = $(am_libgensio_kiss_la_OBJECTS) libgensio_kiss_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_kiss_la_LDFLAGS) $(LDFLAGS) \ -o $@ @BUILTIN_KISS_FALSE@am_libgensio_kiss_la_rpath = @HAVE_MDNS_TRUE@libgensio_mdns_la_DEPENDENCIES = $(DYNAMIC_LIBS) \ @HAVE_MDNS_TRUE@ libgensiomdns.la am__libgensio_mdns_la_SOURCES_DIST = gensio_mdns.c @HAVE_MDNS_TRUE@am_libgensio_mdns_la_OBJECTS = gensio_mdns.lo libgensio_mdns_la_OBJECTS = $(am_libgensio_mdns_la_OBJECTS) libgensio_mdns_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_mdns_la_LDFLAGS) $(LDFLAGS) \ -o $@ @BUILTIN_MDNS_FALSE@@HAVE_MDNS_TRUE@am_libgensio_mdns_la_rpath = libgensio_msgdelim_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_msgdelim_la_OBJECTS = gensio_msgdelim.lo libgensio_msgdelim_la_OBJECTS = $(am_libgensio_msgdelim_la_OBJECTS) libgensio_msgdelim_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_msgdelim_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILTIN_MSGDELIM_FALSE@am_libgensio_msgdelim_la_rpath = libgensio_mux_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_mux_la_OBJECTS = gensio_mux.lo libgensio_mux_la_OBJECTS = $(am_libgensio_mux_la_OBJECTS) libgensio_mux_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_mux_la_LDFLAGS) $(LDFLAGS) \ -o $@ @BUILTIN_MUX_FALSE@am_libgensio_mux_la_rpath = libgensio_net_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_net_la_OBJECTS = gensio_net.lo libgensio_net_la_OBJECTS = $(am_libgensio_net_la_OBJECTS) libgensio_net_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_net_la_LDFLAGS) $(LDFLAGS) \ -o $@ @BUILTIN_NET_FALSE@am_libgensio_net_la_rpath = @HAVE_OPENIPMI_TRUE@libgensio_openipmi_oshandler_la_DEPENDENCIES = \ @HAVE_OPENIPMI_TRUE@ $(am__DEPENDENCIES_1) am__libgensio_openipmi_oshandler_la_SOURCES_DIST = \ gensio_openipmi_oshandler.c @HAVE_OPENIPMI_TRUE@am_libgensio_openipmi_oshandler_la_OBJECTS = libgensio_openipmi_oshandler_la-gensio_openipmi_oshandler.lo libgensio_openipmi_oshandler_la_OBJECTS = \ $(am_libgensio_openipmi_oshandler_la_OBJECTS) libgensio_openipmi_oshandler_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) \ $(libgensio_openipmi_oshandler_la_LDFLAGS) $(LDFLAGS) -o $@ @HAVE_OPENIPMI_TRUE@am_libgensio_openipmi_oshandler_la_rpath = -rpath \ @HAVE_OPENIPMI_TRUE@ $(libdir) libgensio_perf_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_perf_la_OBJECTS = gensio_perf.lo libgensio_perf_la_OBJECTS = $(am_libgensio_perf_la_OBJECTS) libgensio_perf_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_perf_la_LDFLAGS) $(LDFLAGS) \ -o $@ @BUILTIN_PERF_FALSE@am_libgensio_perf_la_rpath = libgensio_pty_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_pty_la_OBJECTS = gensio_pty.lo libgensio_pty_la_OBJECTS = $(am_libgensio_pty_la_OBJECTS) libgensio_pty_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_pty_la_LDFLAGS) $(LDFLAGS) \ -o $@ @BUILTIN_PTY_FALSE@am_libgensio_pty_la_rpath = libgensio_ratelimit_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_ratelimit_la_OBJECTS = gensio_ratelimit.lo libgensio_ratelimit_la_OBJECTS = $(am_libgensio_ratelimit_la_OBJECTS) libgensio_ratelimit_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_ratelimit_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILTIN_RATELIMIT_FALSE@am_libgensio_ratelimit_la_rpath = libgensio_relpkt_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_relpkt_la_OBJECTS = gensio_relpkt.lo libgensio_relpkt_la_OBJECTS = $(am_libgensio_relpkt_la_OBJECTS) libgensio_relpkt_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_relpkt_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILTIN_RELPKT_FALSE@am_libgensio_relpkt_la_rpath = libgensio_script_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_script_la_OBJECTS = gensio_script.lo libgensio_script_la_OBJECTS = $(am_libgensio_script_la_OBJECTS) libgensio_script_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_script_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILTIN_SCRIPT_FALSE@am_libgensio_script_la_rpath = libgensio_sctp_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_sctp_la_OBJECTS = gensio_sctp.lo libgensio_sctp_la_OBJECTS = $(am_libgensio_sctp_la_OBJECTS) libgensio_sctp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_sctp_la_LDFLAGS) $(LDFLAGS) \ -o $@ @BUILTIN_SCTP_FALSE@am_libgensio_sctp_la_rpath = libgensio_serialdev_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_serialdev_la_OBJECTS = sergensio_serialdev.lo \ seriallock.lo libgensio_serialdev_la_OBJECTS = $(am_libgensio_serialdev_la_OBJECTS) libgensio_serialdev_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_serialdev_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILTIN_SERIALDEV_FALSE@am_libgensio_serialdev_la_rpath = libgensio_sound_la_DEPENDENCIES = $(DYNAMIC_LIBS) \ $(am__DEPENDENCIES_1) am_libgensio_sound_la_OBJECTS = gensio_sound.lo libgensio_sound_la_OBJECTS = $(am_libgensio_sound_la_OBJECTS) libgensio_sound_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_sound_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILTIN_SOUND_FALSE@am_libgensio_sound_la_rpath = libgensio_ssl_la_DEPENDENCIES = $(DYNAMIC_LIBS) $(am__DEPENDENCIES_1) am_libgensio_ssl_la_OBJECTS = libgensio_ssl_la-gensio_ssl.lo libgensio_ssl_la_OBJECTS = $(am_libgensio_ssl_la_OBJECTS) libgensio_ssl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_ssl_la_LDFLAGS) $(LDFLAGS) \ -o $@ @BUILTIN_SSL_FALSE@am_libgensio_ssl_la_rpath = libgensio_stdio_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_stdio_la_OBJECTS = gensio_stdio.lo libgensio_stdio_la_OBJECTS = $(am_libgensio_stdio_la_OBJECTS) libgensio_stdio_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_stdio_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILTIN_STDIO_FALSE@am_libgensio_stdio_la_rpath = libgensio_telnet_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_telnet_la_OBJECTS = sergensio_telnet.lo telnet.lo libgensio_telnet_la_OBJECTS = $(am_libgensio_telnet_la_OBJECTS) libgensio_telnet_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_telnet_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILTIN_TELNET_FALSE@am_libgensio_telnet_la_rpath = libgensio_trace_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_trace_la_OBJECTS = gensio_trace.lo libgensio_trace_la_OBJECTS = $(am_libgensio_trace_la_OBJECTS) libgensio_trace_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_trace_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILTIN_TRACE_FALSE@am_libgensio_trace_la_rpath = libgensio_xlt_la_DEPENDENCIES = $(DYNAMIC_LIBS) am_libgensio_xlt_la_OBJECTS = gensio_xlt.lo libgensio_xlt_la_OBJECTS = $(am_libgensio_xlt_la_OBJECTS) libgensio_xlt_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensio_xlt_la_LDFLAGS) $(LDFLAGS) \ -o $@ @BUILTIN_XLT_FALSE@am_libgensio_xlt_la_rpath = libgensiomdns_la_DEPENDENCIES = libgensioosh.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am_libgensiomdns_la_OBJECTS = libgensiomdns_la-mdns.lo \ libgensiomdns_la-avahi_watcher.lo libgensiomdns_la_OBJECTS = $(am_libgensiomdns_la_OBJECTS) libgensiomdns_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensiomdns_la_LDFLAGS) $(LDFLAGS) \ -o $@ libgensioosh_la_DEPENDENCIES = am__libgensioosh_la_SOURCES_DIST = os_osops.c circbuf.c os_osops_env.c \ net_addrinfo.c net_stdsock.c net_ax25_addr.c utils.c \ net_addr.c os_unix.c os_unix_selector.c os_win.c errtrig.c @HAVE_UNIX_OS_TRUE@am__objects_30 = libgensioosh_la-os_unix.lo \ @HAVE_UNIX_OS_TRUE@ libgensioosh_la-os_unix_selector.lo @HAVE_WINDOWS_OS_TRUE@am__objects_31 = libgensioosh_la-os_win.lo @ENABLE_INTERNAL_TRACE_TRUE@am__objects_32 = \ @ENABLE_INTERNAL_TRACE_TRUE@ libgensioosh_la-errtrig.lo am_libgensioosh_la_OBJECTS = libgensioosh_la-os_osops.lo \ libgensioosh_la-circbuf.lo libgensioosh_la-os_osops_env.lo \ libgensioosh_la-net_addrinfo.lo libgensioosh_la-net_stdsock.lo \ libgensioosh_la-net_ax25_addr.lo libgensioosh_la-utils.lo \ libgensioosh_la-net_addr.lo $(am__objects_30) \ $(am__objects_31) $(am__objects_32) libgensioosh_la_OBJECTS = $(am_libgensioosh_la_OBJECTS) libgensioosh_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgensioosh_la_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/gensio_afskmdm.Plo \ ./$(DEPDIR)/gensio_ax25.Plo ./$(DEPDIR)/gensio_cm108gpio.Plo \ ./$(DEPDIR)/gensio_conacc.Plo ./$(DEPDIR)/gensio_dgram.Plo \ ./$(DEPDIR)/gensio_dummy.Plo ./$(DEPDIR)/gensio_echo.Plo \ ./$(DEPDIR)/gensio_file.Plo ./$(DEPDIR)/gensio_keepopen.Plo \ ./$(DEPDIR)/gensio_kiss.Plo ./$(DEPDIR)/gensio_mdns.Plo \ ./$(DEPDIR)/gensio_msgdelim.Plo ./$(DEPDIR)/gensio_mux.Plo \ ./$(DEPDIR)/gensio_net.Plo ./$(DEPDIR)/gensio_perf.Plo \ ./$(DEPDIR)/gensio_pty.Plo ./$(DEPDIR)/gensio_ratelimit.Plo \ ./$(DEPDIR)/gensio_relpkt.Plo ./$(DEPDIR)/gensio_script.Plo \ ./$(DEPDIR)/gensio_sctp.Plo ./$(DEPDIR)/gensio_sound.Plo \ ./$(DEPDIR)/gensio_stdio.Plo ./$(DEPDIR)/gensio_trace.Plo \ ./$(DEPDIR)/gensio_xlt.Plo \ ./$(DEPDIR)/libgensio_certauth_la-gensio_certauth.Plo \ ./$(DEPDIR)/libgensio_ipmisol_la-sergensio_ipmisol.Plo \ ./$(DEPDIR)/libgensio_la-acc.Plo \ ./$(DEPDIR)/libgensio_la-acc_gensio.Plo \ ./$(DEPDIR)/libgensio_la-buffer.Plo \ ./$(DEPDIR)/libgensio_la-gensio.Plo \ ./$(DEPDIR)/libgensio_la-gensio_afskmdm.Plo \ ./$(DEPDIR)/libgensio_la-gensio_ax25.Plo \ ./$(DEPDIR)/libgensio_la-gensio_base.Plo \ ./$(DEPDIR)/libgensio_la-gensio_certauth.Plo \ ./$(DEPDIR)/libgensio_la-gensio_cm108gpio.Plo \ ./$(DEPDIR)/libgensio_la-gensio_conacc.Plo \ ./$(DEPDIR)/libgensio_la-gensio_dgram.Plo \ ./$(DEPDIR)/libgensio_la-gensio_dummy.Plo \ ./$(DEPDIR)/libgensio_la-gensio_echo.Plo \ ./$(DEPDIR)/libgensio_la-gensio_file.Plo \ ./$(DEPDIR)/libgensio_la-gensio_keepopen.Plo \ ./$(DEPDIR)/libgensio_la-gensio_kiss.Plo \ ./$(DEPDIR)/libgensio_la-gensio_mdns.Plo \ ./$(DEPDIR)/libgensio_la-gensio_msgdelim.Plo \ ./$(DEPDIR)/libgensio_la-gensio_mux.Plo \ ./$(DEPDIR)/libgensio_la-gensio_net.Plo \ ./$(DEPDIR)/libgensio_la-gensio_perf.Plo \ ./$(DEPDIR)/libgensio_la-gensio_pty.Plo \ ./$(DEPDIR)/libgensio_la-gensio_ratelimit.Plo \ ./$(DEPDIR)/libgensio_la-gensio_relpkt.Plo \ ./$(DEPDIR)/libgensio_la-gensio_script.Plo \ ./$(DEPDIR)/libgensio_la-gensio_sctp.Plo \ ./$(DEPDIR)/libgensio_la-gensio_sound.Plo \ ./$(DEPDIR)/libgensio_la-gensio_ssl.Plo \ ./$(DEPDIR)/libgensio_la-gensio_stdio.Plo \ ./$(DEPDIR)/libgensio_la-gensio_trace.Plo \ ./$(DEPDIR)/libgensio_la-gensio_xlt.Plo \ ./$(DEPDIR)/libgensio_la-ll_fd.Plo \ ./$(DEPDIR)/libgensio_la-ll_gensio.Plo \ ./$(DEPDIR)/libgensio_la-sergensio_ipmisol.Plo \ ./$(DEPDIR)/libgensio_la-sergensio_serialdev.Plo \ ./$(DEPDIR)/libgensio_la-sergensio_telnet.Plo \ ./$(DEPDIR)/libgensio_la-seriallock.Plo \ ./$(DEPDIR)/libgensio_la-telnet.Plo \ ./$(DEPDIR)/libgensio_openipmi_oshandler_la-gensio_openipmi_oshandler.Plo \ ./$(DEPDIR)/libgensio_ssl_la-gensio_ssl.Plo \ ./$(DEPDIR)/libgensiomdns_la-avahi_watcher.Plo \ ./$(DEPDIR)/libgensiomdns_la-mdns.Plo \ ./$(DEPDIR)/libgensioosh_la-circbuf.Plo \ ./$(DEPDIR)/libgensioosh_la-errtrig.Plo \ ./$(DEPDIR)/libgensioosh_la-net_addr.Plo \ ./$(DEPDIR)/libgensioosh_la-net_addrinfo.Plo \ ./$(DEPDIR)/libgensioosh_la-net_ax25_addr.Plo \ ./$(DEPDIR)/libgensioosh_la-net_stdsock.Plo \ ./$(DEPDIR)/libgensioosh_la-os_osops.Plo \ ./$(DEPDIR)/libgensioosh_la-os_osops_env.Plo \ ./$(DEPDIR)/libgensioosh_la-os_unix.Plo \ ./$(DEPDIR)/libgensioosh_la-os_unix_selector.Plo \ ./$(DEPDIR)/libgensioosh_la-os_win.Plo \ ./$(DEPDIR)/libgensioosh_la-utils.Plo \ ./$(DEPDIR)/sergensio_serialdev.Plo \ ./$(DEPDIR)/sergensio_telnet.Plo ./$(DEPDIR)/seriallock.Plo \ ./$(DEPDIR)/telnet.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libgensio_la_SOURCES) $(libgensio_afskmdm_la_SOURCES) \ $(libgensio_ax25_la_SOURCES) $(libgensio_certauth_la_SOURCES) \ $(libgensio_cm108gpio_la_SOURCES) \ $(libgensio_conacc_la_SOURCES) $(libgensio_dgram_la_SOURCES) \ $(libgensio_dummy_la_SOURCES) $(libgensio_echo_la_SOURCES) \ $(libgensio_file_la_SOURCES) $(libgensio_ipmisol_la_SOURCES) \ $(libgensio_keepopen_la_SOURCES) $(libgensio_kiss_la_SOURCES) \ $(libgensio_mdns_la_SOURCES) $(libgensio_msgdelim_la_SOURCES) \ $(libgensio_mux_la_SOURCES) $(libgensio_net_la_SOURCES) \ $(libgensio_openipmi_oshandler_la_SOURCES) \ $(libgensio_perf_la_SOURCES) $(libgensio_pty_la_SOURCES) \ $(libgensio_ratelimit_la_SOURCES) \ $(libgensio_relpkt_la_SOURCES) $(libgensio_script_la_SOURCES) \ $(libgensio_sctp_la_SOURCES) $(libgensio_serialdev_la_SOURCES) \ $(libgensio_sound_la_SOURCES) $(libgensio_ssl_la_SOURCES) \ $(libgensio_stdio_la_SOURCES) $(libgensio_telnet_la_SOURCES) \ $(libgensio_trace_la_SOURCES) $(libgensio_xlt_la_SOURCES) \ $(libgensiomdns_la_SOURCES) $(libgensioosh_la_SOURCES) DIST_SOURCES = $(am__libgensio_la_SOURCES_DIST) \ $(libgensio_afskmdm_la_SOURCES) $(libgensio_ax25_la_SOURCES) \ $(libgensio_certauth_la_SOURCES) \ $(libgensio_cm108gpio_la_SOURCES) \ $(libgensio_conacc_la_SOURCES) $(libgensio_dgram_la_SOURCES) \ $(libgensio_dummy_la_SOURCES) $(libgensio_echo_la_SOURCES) \ $(libgensio_file_la_SOURCES) $(libgensio_ipmisol_la_SOURCES) \ $(libgensio_keepopen_la_SOURCES) $(libgensio_kiss_la_SOURCES) \ $(am__libgensio_mdns_la_SOURCES_DIST) \ $(libgensio_msgdelim_la_SOURCES) $(libgensio_mux_la_SOURCES) \ $(libgensio_net_la_SOURCES) \ $(am__libgensio_openipmi_oshandler_la_SOURCES_DIST) \ $(libgensio_perf_la_SOURCES) $(libgensio_pty_la_SOURCES) \ $(libgensio_ratelimit_la_SOURCES) \ $(libgensio_relpkt_la_SOURCES) $(libgensio_script_la_SOURCES) \ $(libgensio_sctp_la_SOURCES) $(libgensio_serialdev_la_SOURCES) \ $(libgensio_sound_la_SOURCES) $(libgensio_ssl_la_SOURCES) \ $(libgensio_stdio_la_SOURCES) $(libgensio_telnet_la_SOURCES) \ $(libgensio_trace_la_SOURCES) $(libgensio_xlt_la_SOURCES) \ $(libgensiomdns_la_SOURCES) \ $(am__libgensioosh_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(pkgconfigexec_DATA) HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/libgensio.pc.in \ $(srcdir)/libgensiomdns.pc.in $(srcdir)/libgensioosh.pc.in \ $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # libgensio.la can depend on iibgensiomdns if BUILTIN_MDNS is set. # Therefore it must be built after libgensiomdns, so it has to be # added after. lib_LTLIBRARIES = libgensioosh.la libgensiomdns.la libgensio.la \ $(am__append_4) noinst_HEADERS = telnet.h heap.h utils.h seriallock.h crc.h \ errtrig.h avahi_watcher.h gensio_net.h \ gensio_sound_alsa.h gensio_sound_win.h \ gensio_sound_portaudio.h gensio_sound_file.h \ gensio_base_parms.h libgensioosh_la_SOURCES = os_osops.c circbuf.c os_osops_env.c \ net_addrinfo.c net_stdsock.c net_ax25_addr.c utils.c \ net_addr.c $(am__append_1) $(am__append_2) $(am__append_3) libgensioosh_la_CPPFLAGS = -DBUILDING_GENSIOOSH_DLL \ -DPKG_LIBEXEC="\"$(gensiolibexecdir)\"" libgensioosh_la_LDFLAGS = -no-undefined -version-info $(GENSIO_LIB_VERSION) \ -fvisibility=hidden libgensioosh_la_LIBADD = @OSH_LIBS@ libgensiomdns_la_SOURCES = mdns.c avahi_watcher.c libgensiomdns_la_CPPFLAGS = -DBUILDING_GENSIOMDNS_DLL libgensiomdns_la_LDFLAGS = -no-undefined -version-info $(GENSIO_LIB_VERSION) \ -fvisibility=hidden libgensiomdns_la_LIBADD = libgensioosh.la ${MDNS_LIBS} \ ${REGEX_LIB} libgensio_la_SOURCES = gensio.c gensio_base.c buffer.c ll_fd.c \ ll_gensio.c acc.c acc_gensio.c $(am__append_5) $(am__append_7) \ $(am__append_9) $(am__append_11) $(am__append_13) \ $(am__append_15) $(am__append_17) $(am__append_19) \ $(am__append_21) $(am__append_23) $(am__append_25) \ $(am__append_27) $(am__append_31) $(am__append_33) \ $(am__append_35) $(am__append_37) $(am__append_39) \ $(am__append_41) $(am__append_43) $(am__append_45) \ $(am__append_47) $(am__append_49) $(am__append_51) \ $(am__append_53) $(am__append_55) $(am__append_57) \ $(am__append_59) $(am__append_61) $(am__append_63) libgensio_la_CPPFLAGS = -DBUILDING_GENSIO_DLL libgensio_la_LDFLAGS = -no-undefined -version-info $(GENSIO_LIB_VERSION) \ -fvisibility=hidden libgensio_la_LIBADD = libgensioosh.la @BASE_LIBS@ $(am__append_28) \ $(am__append_64) @HAVE_WINDOWS_OS_FALSE@gensiolibexecdir = $(moduleinstalldir)/$(PACKAGE_VERSION) @HAVE_WINDOWS_OS_TRUE@gensiolibexecdir = $(bindir) @HAVE_OPENIPMI_TRUE@libgensio_openipmi_oshandler_la_SOURCES = gensio_openipmi_oshandler.c @HAVE_OPENIPMI_TRUE@libgensio_openipmi_oshandler_la_CPPFLAGS = $(OPENIPMI_CPPFLAGS) @HAVE_OPENIPMI_TRUE@libgensio_openipmi_oshandler_la_LDFLAGS = -no-undefined -version-info \ @HAVE_OPENIPMI_TRUE@ $(GENSIO_LIB_VERSION) -fvisibility=hidden @HAVE_OPENIPMI_TRUE@libgensio_openipmi_oshandler_la_LIBADD = $(OPENIPMI_LIBS) EXTRA_LTLIBRARIES = $(am__append_6) $(am__append_8) $(am__append_10) \ $(am__append_12) $(am__append_14) $(am__append_16) \ $(am__append_18) $(am__append_20) $(am__append_22) \ $(am__append_24) $(am__append_26) $(am__append_29) \ $(am__append_32) $(am__append_34) $(am__append_36) \ $(am__append_38) $(am__append_40) $(am__append_42) \ $(am__append_44) $(am__append_46) $(am__append_48) \ $(am__append_50) $(am__append_52) $(am__append_54) \ $(am__append_56) $(am__append_58) $(am__append_60) \ $(am__append_62) $(am__append_65) gensiolibexec_LTLIBRARIES = $(DYNAMIC_NET) $(DYNAMIC_DGRAM) \ $(DYNAMIC_SCTP) $(DYNAMIC_STDIO) $(DYNAMIC_PTY) \ $(DYNAMIC_DUMMY) $(DYNAMIC_CONACC) $(DYNAMIC_SERIALDEV) \ $(DYNAMIC_ECHO) $(DYNAMIC_FILE) $(DYNAMIC_IPMISOL) \ $(am__append_30) $(DYNAMIC_SOUND) $(DYNAMIC_CM108GPIO) \ $(DYNAMIC_SSL) $(DYNAMIC_CERTAUTH) $(DYNAMIC_MUX) \ $(DYNAMIC_TELNET) $(DYNAMIC_MSGDELIM) $(DYNAMIC_RELPKT) \ $(DYNAMIC_TRACE) $(DYNAMIC_PERF) $(DYNAMIC_KISS) \ $(DYNAMIC_AX25) $(DYNAMIC_XLT) $(DYNAMIC_KEEPOPEN) \ $(DYNAMIC_SCRIPT) $(DYNAMIC_RATELIMIT) $(DYNAMIC_AFSKMDM) DYNAMIC_LDFLAGS = -no-undefined -module -rpath "$(gensiolibexecdir)" -avoid-version DYNAMIC_LIBS = libgensio.la libgensioosh.la libgensio_net_la_SOURCES = gensio_net.c libgensio_net_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_net_la_LIBADD = $(DYNAMIC_LIBS) libgensio_dgram_la_SOURCES = gensio_dgram.c libgensio_dgram_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_dgram_la_LIBADD = $(DYNAMIC_LIBS) libgensio_sctp_la_SOURCES = gensio_sctp.c libgensio_sctp_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_sctp_la_LIBADD = $(DYNAMIC_LIBS) $(SCTP_LIBS) libgensio_stdio_la_SOURCES = gensio_stdio.c libgensio_stdio_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_stdio_la_LIBADD = $(DYNAMIC_LIBS) libgensio_pty_la_SOURCES = gensio_pty.c libgensio_pty_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_pty_la_LIBADD = $(DYNAMIC_LIBS) libgensio_dummy_la_SOURCES = gensio_dummy.c libgensio_dummy_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_dummy_la_LIBADD = $(DYNAMIC_LIBS) libgensio_conacc_la_SOURCES = gensio_conacc.c libgensio_conacc_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_conacc_la_LIBADD = $(DYNAMIC_LIBS) libgensio_serialdev_la_SOURCES = sergensio_serialdev.c seriallock.c libgensio_serialdev_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_serialdev_la_LIBADD = $(DYNAMIC_LIBS) libgensio_echo_la_SOURCES = gensio_echo.c libgensio_echo_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_echo_la_LIBADD = $(DYNAMIC_LIBS) libgensio_file_la_SOURCES = gensio_file.c libgensio_file_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_file_la_LIBADD = $(DYNAMIC_LIBS) libgensio_ipmisol_la_SOURCES = sergensio_ipmisol.c libgensio_ipmisol_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_ipmisol_la_CFLAGS = $(OPENIPMI_CPPFLAGS) libgensio_ipmisol_la_LIBADD = $(DYNAMIC_LIBS) $(OPENIPMI_LIBS) \ libgensio_openipmi_oshandler.la @HAVE_MDNS_TRUE@libgensio_mdns_la_SOURCES = gensio_mdns.c @HAVE_MDNS_TRUE@libgensio_mdns_la_LDFLAGS = $(DYNAMIC_LDFLAGS) @HAVE_MDNS_TRUE@libgensio_mdns_la_LIBADD = $(DYNAMIC_LIBS) libgensiomdns.la libgensio_sound_la_SOURCES = gensio_sound.c libgensio_sound_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_sound_la_LIBADD = $(DYNAMIC_LIBS) $(SOUND_LIBS) libgensio_cm108gpio_la_SOURCES = gensio_cm108gpio.c libgensio_cm108gpio_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_cm108gpio_la_LIBADD = $(DYNAMIC_LIBS) $(CM108GPIO_LIBS) libgensio_ssl_la_SOURCES = gensio_ssl.c libgensio_ssl_la_CPPFLAGS = $(OPENSSL_INCLUDES) libgensio_ssl_la_LDFLAGS = $(DYNAMIC_LDFLAGS) $(OPENSSL_LDFLAGS) libgensio_ssl_la_LIBADD = $(DYNAMIC_LIBS) $(OPENSSL_LIBS) libgensio_certauth_la_SOURCES = gensio_certauth.c libgensio_certauth_la_CPPFLAGS = $(OPENSSL_INCLUDES) libgensio_certauth_la_LDFLAGS = $(DYNAMIC_LDFLAGS) $(OPENSSL_LDFLAGS) libgensio_certauth_la_LIBADD = $(DYNAMIC_LIBS) $(OPENSSL_LIBS) libgensio_mux_la_SOURCES = gensio_mux.c libgensio_mux_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_mux_la_LIBADD = $(DYNAMIC_LIBS) libgensio_telnet_la_SOURCES = sergensio_telnet.c telnet.c libgensio_telnet_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_telnet_la_LIBADD = $(DYNAMIC_LIBS) libgensio_msgdelim_la_SOURCES = gensio_msgdelim.c libgensio_msgdelim_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_msgdelim_la_LIBADD = $(DYNAMIC_LIBS) libgensio_relpkt_la_SOURCES = gensio_relpkt.c libgensio_relpkt_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_relpkt_la_LIBADD = $(DYNAMIC_LIBS) libgensio_trace_la_SOURCES = gensio_trace.c libgensio_trace_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_trace_la_LIBADD = $(DYNAMIC_LIBS) libgensio_perf_la_SOURCES = gensio_perf.c libgensio_perf_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_perf_la_LIBADD = $(DYNAMIC_LIBS) libgensio_kiss_la_SOURCES = gensio_kiss.c libgensio_kiss_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_kiss_la_LIBADD = $(DYNAMIC_LIBS) libgensio_ax25_la_SOURCES = gensio_ax25.c libgensio_ax25_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_ax25_la_LIBADD = $(DYNAMIC_LIBS) libgensio_xlt_la_SOURCES = gensio_xlt.c libgensio_xlt_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_xlt_la_LIBADD = $(DYNAMIC_LIBS) libgensio_keepopen_la_SOURCES = gensio_keepopen.c libgensio_keepopen_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_keepopen_la_LIBADD = $(DYNAMIC_LIBS) libgensio_script_la_SOURCES = gensio_script.c libgensio_script_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_script_la_LIBADD = $(DYNAMIC_LIBS) libgensio_ratelimit_la_SOURCES = gensio_ratelimit.c libgensio_ratelimit_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_ratelimit_la_LIBADD = $(DYNAMIC_LIBS) libgensio_afskmdm_la_SOURCES = gensio_afskmdm.c libgensio_afskmdm_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_afskmdm_la_LIBADD = $(DYNAMIC_LIBS) -lm EXTRA_DIST = README.rst libgensioosh.pc.in libgensio.pc.in libgensiomdns.pc.in DISTCLEANFILES = builtin_gensios.h # This variable must have 'exec' in its name, in order to be installed # by 'install-exec' target (instead of default 'install-data') pkgconfigexecdir = $(libdir)/pkgconfig pkgconfigexec_DATA = libgensioosh.pc libgensio.pc libgensiomdns.pc @HAVE_WINDOWS_OS_FALSE@xgensio_libs = $(gensiolibexec_LTLIBRARIES:.la=.a) @HAVE_WINDOWS_OS_TRUE@xgensio_libs = $(gensiolibexec_LTLIBRARIES:.la=.dll.a) @HAVE_WINDOWS_OS_FALSE@xgensio_solibs = $(gensiolibexec_LTLIBRARIES:.la=.so) @HAVE_WINDOWS_OS_TRUE@xgensio_solibs = $(gensiolibexec_LTLIBRARIES:.la=.dll) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): libgensioosh.pc: $(top_builddir)/config.status $(srcdir)/libgensioosh.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ libgensio.pc: $(top_builddir)/config.status $(srcdir)/libgensio.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ libgensiomdns.pc: $(top_builddir)/config.status $(srcdir)/libgensiomdns.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-gensiolibexecLTLIBRARIES: $(gensiolibexec_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(gensiolibexec_LTLIBRARIES)'; test -n "$(gensiolibexecdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(gensiolibexecdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(gensiolibexecdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(gensiolibexecdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(gensiolibexecdir)"; \ } uninstall-gensiolibexecLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(gensiolibexec_LTLIBRARIES)'; test -n "$(gensiolibexecdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(gensiolibexecdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(gensiolibexecdir)/$$f"; \ done clean-gensiolibexecLTLIBRARIES: -test -z "$(gensiolibexec_LTLIBRARIES)" || rm -f $(gensiolibexec_LTLIBRARIES) @list='$(gensiolibexec_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libgensio.la: $(libgensio_la_OBJECTS) $(libgensio_la_DEPENDENCIES) $(EXTRA_libgensio_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_la_LINK) -rpath $(libdir) $(libgensio_la_OBJECTS) $(libgensio_la_LIBADD) $(LIBS) libgensio_afskmdm.la: $(libgensio_afskmdm_la_OBJECTS) $(libgensio_afskmdm_la_DEPENDENCIES) $(EXTRA_libgensio_afskmdm_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_afskmdm_la_LINK) $(am_libgensio_afskmdm_la_rpath) $(libgensio_afskmdm_la_OBJECTS) $(libgensio_afskmdm_la_LIBADD) $(LIBS) libgensio_ax25.la: $(libgensio_ax25_la_OBJECTS) $(libgensio_ax25_la_DEPENDENCIES) $(EXTRA_libgensio_ax25_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_ax25_la_LINK) $(am_libgensio_ax25_la_rpath) $(libgensio_ax25_la_OBJECTS) $(libgensio_ax25_la_LIBADD) $(LIBS) libgensio_certauth.la: $(libgensio_certauth_la_OBJECTS) $(libgensio_certauth_la_DEPENDENCIES) $(EXTRA_libgensio_certauth_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_certauth_la_LINK) $(am_libgensio_certauth_la_rpath) $(libgensio_certauth_la_OBJECTS) $(libgensio_certauth_la_LIBADD) $(LIBS) libgensio_cm108gpio.la: $(libgensio_cm108gpio_la_OBJECTS) $(libgensio_cm108gpio_la_DEPENDENCIES) $(EXTRA_libgensio_cm108gpio_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_cm108gpio_la_LINK) $(am_libgensio_cm108gpio_la_rpath) $(libgensio_cm108gpio_la_OBJECTS) $(libgensio_cm108gpio_la_LIBADD) $(LIBS) libgensio_conacc.la: $(libgensio_conacc_la_OBJECTS) $(libgensio_conacc_la_DEPENDENCIES) $(EXTRA_libgensio_conacc_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_conacc_la_LINK) $(am_libgensio_conacc_la_rpath) $(libgensio_conacc_la_OBJECTS) $(libgensio_conacc_la_LIBADD) $(LIBS) libgensio_dgram.la: $(libgensio_dgram_la_OBJECTS) $(libgensio_dgram_la_DEPENDENCIES) $(EXTRA_libgensio_dgram_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_dgram_la_LINK) $(am_libgensio_dgram_la_rpath) $(libgensio_dgram_la_OBJECTS) $(libgensio_dgram_la_LIBADD) $(LIBS) libgensio_dummy.la: $(libgensio_dummy_la_OBJECTS) $(libgensio_dummy_la_DEPENDENCIES) $(EXTRA_libgensio_dummy_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_dummy_la_LINK) $(am_libgensio_dummy_la_rpath) $(libgensio_dummy_la_OBJECTS) $(libgensio_dummy_la_LIBADD) $(LIBS) libgensio_echo.la: $(libgensio_echo_la_OBJECTS) $(libgensio_echo_la_DEPENDENCIES) $(EXTRA_libgensio_echo_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_echo_la_LINK) $(am_libgensio_echo_la_rpath) $(libgensio_echo_la_OBJECTS) $(libgensio_echo_la_LIBADD) $(LIBS) libgensio_file.la: $(libgensio_file_la_OBJECTS) $(libgensio_file_la_DEPENDENCIES) $(EXTRA_libgensio_file_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_file_la_LINK) $(am_libgensio_file_la_rpath) $(libgensio_file_la_OBJECTS) $(libgensio_file_la_LIBADD) $(LIBS) libgensio_ipmisol.la: $(libgensio_ipmisol_la_OBJECTS) $(libgensio_ipmisol_la_DEPENDENCIES) $(EXTRA_libgensio_ipmisol_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_ipmisol_la_LINK) $(am_libgensio_ipmisol_la_rpath) $(libgensio_ipmisol_la_OBJECTS) $(libgensio_ipmisol_la_LIBADD) $(LIBS) libgensio_keepopen.la: $(libgensio_keepopen_la_OBJECTS) $(libgensio_keepopen_la_DEPENDENCIES) $(EXTRA_libgensio_keepopen_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_keepopen_la_LINK) $(am_libgensio_keepopen_la_rpath) $(libgensio_keepopen_la_OBJECTS) $(libgensio_keepopen_la_LIBADD) $(LIBS) libgensio_kiss.la: $(libgensio_kiss_la_OBJECTS) $(libgensio_kiss_la_DEPENDENCIES) $(EXTRA_libgensio_kiss_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_kiss_la_LINK) $(am_libgensio_kiss_la_rpath) $(libgensio_kiss_la_OBJECTS) $(libgensio_kiss_la_LIBADD) $(LIBS) libgensio_mdns.la: $(libgensio_mdns_la_OBJECTS) $(libgensio_mdns_la_DEPENDENCIES) $(EXTRA_libgensio_mdns_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_mdns_la_LINK) $(am_libgensio_mdns_la_rpath) $(libgensio_mdns_la_OBJECTS) $(libgensio_mdns_la_LIBADD) $(LIBS) libgensio_msgdelim.la: $(libgensio_msgdelim_la_OBJECTS) $(libgensio_msgdelim_la_DEPENDENCIES) $(EXTRA_libgensio_msgdelim_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_msgdelim_la_LINK) $(am_libgensio_msgdelim_la_rpath) $(libgensio_msgdelim_la_OBJECTS) $(libgensio_msgdelim_la_LIBADD) $(LIBS) libgensio_mux.la: $(libgensio_mux_la_OBJECTS) $(libgensio_mux_la_DEPENDENCIES) $(EXTRA_libgensio_mux_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_mux_la_LINK) $(am_libgensio_mux_la_rpath) $(libgensio_mux_la_OBJECTS) $(libgensio_mux_la_LIBADD) $(LIBS) libgensio_net.la: $(libgensio_net_la_OBJECTS) $(libgensio_net_la_DEPENDENCIES) $(EXTRA_libgensio_net_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_net_la_LINK) $(am_libgensio_net_la_rpath) $(libgensio_net_la_OBJECTS) $(libgensio_net_la_LIBADD) $(LIBS) libgensio_openipmi_oshandler.la: $(libgensio_openipmi_oshandler_la_OBJECTS) $(libgensio_openipmi_oshandler_la_DEPENDENCIES) $(EXTRA_libgensio_openipmi_oshandler_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_openipmi_oshandler_la_LINK) $(am_libgensio_openipmi_oshandler_la_rpath) $(libgensio_openipmi_oshandler_la_OBJECTS) $(libgensio_openipmi_oshandler_la_LIBADD) $(LIBS) libgensio_perf.la: $(libgensio_perf_la_OBJECTS) $(libgensio_perf_la_DEPENDENCIES) $(EXTRA_libgensio_perf_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_perf_la_LINK) $(am_libgensio_perf_la_rpath) $(libgensio_perf_la_OBJECTS) $(libgensio_perf_la_LIBADD) $(LIBS) libgensio_pty.la: $(libgensio_pty_la_OBJECTS) $(libgensio_pty_la_DEPENDENCIES) $(EXTRA_libgensio_pty_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_pty_la_LINK) $(am_libgensio_pty_la_rpath) $(libgensio_pty_la_OBJECTS) $(libgensio_pty_la_LIBADD) $(LIBS) libgensio_ratelimit.la: $(libgensio_ratelimit_la_OBJECTS) $(libgensio_ratelimit_la_DEPENDENCIES) $(EXTRA_libgensio_ratelimit_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_ratelimit_la_LINK) $(am_libgensio_ratelimit_la_rpath) $(libgensio_ratelimit_la_OBJECTS) $(libgensio_ratelimit_la_LIBADD) $(LIBS) libgensio_relpkt.la: $(libgensio_relpkt_la_OBJECTS) $(libgensio_relpkt_la_DEPENDENCIES) $(EXTRA_libgensio_relpkt_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_relpkt_la_LINK) $(am_libgensio_relpkt_la_rpath) $(libgensio_relpkt_la_OBJECTS) $(libgensio_relpkt_la_LIBADD) $(LIBS) libgensio_script.la: $(libgensio_script_la_OBJECTS) $(libgensio_script_la_DEPENDENCIES) $(EXTRA_libgensio_script_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_script_la_LINK) $(am_libgensio_script_la_rpath) $(libgensio_script_la_OBJECTS) $(libgensio_script_la_LIBADD) $(LIBS) libgensio_sctp.la: $(libgensio_sctp_la_OBJECTS) $(libgensio_sctp_la_DEPENDENCIES) $(EXTRA_libgensio_sctp_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_sctp_la_LINK) $(am_libgensio_sctp_la_rpath) $(libgensio_sctp_la_OBJECTS) $(libgensio_sctp_la_LIBADD) $(LIBS) libgensio_serialdev.la: $(libgensio_serialdev_la_OBJECTS) $(libgensio_serialdev_la_DEPENDENCIES) $(EXTRA_libgensio_serialdev_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_serialdev_la_LINK) $(am_libgensio_serialdev_la_rpath) $(libgensio_serialdev_la_OBJECTS) $(libgensio_serialdev_la_LIBADD) $(LIBS) libgensio_sound.la: $(libgensio_sound_la_OBJECTS) $(libgensio_sound_la_DEPENDENCIES) $(EXTRA_libgensio_sound_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_sound_la_LINK) $(am_libgensio_sound_la_rpath) $(libgensio_sound_la_OBJECTS) $(libgensio_sound_la_LIBADD) $(LIBS) libgensio_ssl.la: $(libgensio_ssl_la_OBJECTS) $(libgensio_ssl_la_DEPENDENCIES) $(EXTRA_libgensio_ssl_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_ssl_la_LINK) $(am_libgensio_ssl_la_rpath) $(libgensio_ssl_la_OBJECTS) $(libgensio_ssl_la_LIBADD) $(LIBS) libgensio_stdio.la: $(libgensio_stdio_la_OBJECTS) $(libgensio_stdio_la_DEPENDENCIES) $(EXTRA_libgensio_stdio_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_stdio_la_LINK) $(am_libgensio_stdio_la_rpath) $(libgensio_stdio_la_OBJECTS) $(libgensio_stdio_la_LIBADD) $(LIBS) libgensio_telnet.la: $(libgensio_telnet_la_OBJECTS) $(libgensio_telnet_la_DEPENDENCIES) $(EXTRA_libgensio_telnet_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_telnet_la_LINK) $(am_libgensio_telnet_la_rpath) $(libgensio_telnet_la_OBJECTS) $(libgensio_telnet_la_LIBADD) $(LIBS) libgensio_trace.la: $(libgensio_trace_la_OBJECTS) $(libgensio_trace_la_DEPENDENCIES) $(EXTRA_libgensio_trace_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_trace_la_LINK) $(am_libgensio_trace_la_rpath) $(libgensio_trace_la_OBJECTS) $(libgensio_trace_la_LIBADD) $(LIBS) libgensio_xlt.la: $(libgensio_xlt_la_OBJECTS) $(libgensio_xlt_la_DEPENDENCIES) $(EXTRA_libgensio_xlt_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensio_xlt_la_LINK) $(am_libgensio_xlt_la_rpath) $(libgensio_xlt_la_OBJECTS) $(libgensio_xlt_la_LIBADD) $(LIBS) libgensiomdns.la: $(libgensiomdns_la_OBJECTS) $(libgensiomdns_la_DEPENDENCIES) $(EXTRA_libgensiomdns_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensiomdns_la_LINK) -rpath $(libdir) $(libgensiomdns_la_OBJECTS) $(libgensiomdns_la_LIBADD) $(LIBS) libgensioosh.la: $(libgensioosh_la_OBJECTS) $(libgensioosh_la_DEPENDENCIES) $(EXTRA_libgensioosh_la_DEPENDENCIES) $(AM_V_CCLD)$(libgensioosh_la_LINK) -rpath $(libdir) $(libgensioosh_la_OBJECTS) $(libgensioosh_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_afskmdm.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_ax25.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_cm108gpio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_conacc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_dgram.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_dummy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_echo.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_file.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_keepopen.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_kiss.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_mdns.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_msgdelim.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_mux.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_net.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_perf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_pty.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_ratelimit.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_relpkt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_script.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_sctp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_sound.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_stdio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_trace.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensio_xlt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_certauth_la-gensio_certauth.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_ipmisol_la-sergensio_ipmisol.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-acc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-acc_gensio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-buffer.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_afskmdm.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_ax25.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_base.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_certauth.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_cm108gpio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_conacc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_dgram.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_dummy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_echo.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_file.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_keepopen.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_kiss.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_mdns.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_msgdelim.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_mux.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_net.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_perf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_pty.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_ratelimit.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_relpkt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_script.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_sctp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_sound.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_ssl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_stdio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_trace.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-gensio_xlt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-ll_fd.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-ll_gensio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-sergensio_ipmisol.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-sergensio_serialdev.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-sergensio_telnet.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-seriallock.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_la-telnet.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_openipmi_oshandler_la-gensio_openipmi_oshandler.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensio_ssl_la-gensio_ssl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensiomdns_la-avahi_watcher.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensiomdns_la-mdns.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensioosh_la-circbuf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensioosh_la-errtrig.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensioosh_la-net_addr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensioosh_la-net_addrinfo.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensioosh_la-net_ax25_addr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensioosh_la-net_stdsock.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensioosh_la-os_osops.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensioosh_la-os_osops_env.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensioosh_la-os_unix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensioosh_la-os_unix_selector.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensioosh_la-os_win.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensioosh_la-utils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sergensio_serialdev.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sergensio_telnet.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seriallock.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/telnet.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libgensio_la-gensio.lo: gensio.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio.Tpo -c -o libgensio_la-gensio.lo `test -f 'gensio.c' || echo '$(srcdir)/'`gensio.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio.Tpo $(DEPDIR)/libgensio_la-gensio.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio.c' object='libgensio_la-gensio.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio.lo `test -f 'gensio.c' || echo '$(srcdir)/'`gensio.c libgensio_la-gensio_base.lo: gensio_base.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_base.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_base.Tpo -c -o libgensio_la-gensio_base.lo `test -f 'gensio_base.c' || echo '$(srcdir)/'`gensio_base.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_base.Tpo $(DEPDIR)/libgensio_la-gensio_base.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_base.c' object='libgensio_la-gensio_base.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_base.lo `test -f 'gensio_base.c' || echo '$(srcdir)/'`gensio_base.c libgensio_la-buffer.lo: buffer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-buffer.lo -MD -MP -MF $(DEPDIR)/libgensio_la-buffer.Tpo -c -o libgensio_la-buffer.lo `test -f 'buffer.c' || echo '$(srcdir)/'`buffer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-buffer.Tpo $(DEPDIR)/libgensio_la-buffer.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='buffer.c' object='libgensio_la-buffer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-buffer.lo `test -f 'buffer.c' || echo '$(srcdir)/'`buffer.c libgensio_la-ll_fd.lo: ll_fd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-ll_fd.lo -MD -MP -MF $(DEPDIR)/libgensio_la-ll_fd.Tpo -c -o libgensio_la-ll_fd.lo `test -f 'll_fd.c' || echo '$(srcdir)/'`ll_fd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-ll_fd.Tpo $(DEPDIR)/libgensio_la-ll_fd.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ll_fd.c' object='libgensio_la-ll_fd.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-ll_fd.lo `test -f 'll_fd.c' || echo '$(srcdir)/'`ll_fd.c libgensio_la-ll_gensio.lo: ll_gensio.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-ll_gensio.lo -MD -MP -MF $(DEPDIR)/libgensio_la-ll_gensio.Tpo -c -o libgensio_la-ll_gensio.lo `test -f 'll_gensio.c' || echo '$(srcdir)/'`ll_gensio.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-ll_gensio.Tpo $(DEPDIR)/libgensio_la-ll_gensio.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ll_gensio.c' object='libgensio_la-ll_gensio.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-ll_gensio.lo `test -f 'll_gensio.c' || echo '$(srcdir)/'`ll_gensio.c libgensio_la-acc.lo: acc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-acc.lo -MD -MP -MF $(DEPDIR)/libgensio_la-acc.Tpo -c -o libgensio_la-acc.lo `test -f 'acc.c' || echo '$(srcdir)/'`acc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-acc.Tpo $(DEPDIR)/libgensio_la-acc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='acc.c' object='libgensio_la-acc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-acc.lo `test -f 'acc.c' || echo '$(srcdir)/'`acc.c libgensio_la-acc_gensio.lo: acc_gensio.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-acc_gensio.lo -MD -MP -MF $(DEPDIR)/libgensio_la-acc_gensio.Tpo -c -o libgensio_la-acc_gensio.lo `test -f 'acc_gensio.c' || echo '$(srcdir)/'`acc_gensio.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-acc_gensio.Tpo $(DEPDIR)/libgensio_la-acc_gensio.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='acc_gensio.c' object='libgensio_la-acc_gensio.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-acc_gensio.lo `test -f 'acc_gensio.c' || echo '$(srcdir)/'`acc_gensio.c libgensio_la-gensio_net.lo: gensio_net.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_net.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_net.Tpo -c -o libgensio_la-gensio_net.lo `test -f 'gensio_net.c' || echo '$(srcdir)/'`gensio_net.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_net.Tpo $(DEPDIR)/libgensio_la-gensio_net.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_net.c' object='libgensio_la-gensio_net.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_net.lo `test -f 'gensio_net.c' || echo '$(srcdir)/'`gensio_net.c libgensio_la-gensio_dgram.lo: gensio_dgram.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_dgram.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_dgram.Tpo -c -o libgensio_la-gensio_dgram.lo `test -f 'gensio_dgram.c' || echo '$(srcdir)/'`gensio_dgram.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_dgram.Tpo $(DEPDIR)/libgensio_la-gensio_dgram.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_dgram.c' object='libgensio_la-gensio_dgram.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_dgram.lo `test -f 'gensio_dgram.c' || echo '$(srcdir)/'`gensio_dgram.c libgensio_la-gensio_sctp.lo: gensio_sctp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_sctp.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_sctp.Tpo -c -o libgensio_la-gensio_sctp.lo `test -f 'gensio_sctp.c' || echo '$(srcdir)/'`gensio_sctp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_sctp.Tpo $(DEPDIR)/libgensio_la-gensio_sctp.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_sctp.c' object='libgensio_la-gensio_sctp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_sctp.lo `test -f 'gensio_sctp.c' || echo '$(srcdir)/'`gensio_sctp.c libgensio_la-gensio_stdio.lo: gensio_stdio.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_stdio.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_stdio.Tpo -c -o libgensio_la-gensio_stdio.lo `test -f 'gensio_stdio.c' || echo '$(srcdir)/'`gensio_stdio.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_stdio.Tpo $(DEPDIR)/libgensio_la-gensio_stdio.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_stdio.c' object='libgensio_la-gensio_stdio.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_stdio.lo `test -f 'gensio_stdio.c' || echo '$(srcdir)/'`gensio_stdio.c libgensio_la-gensio_pty.lo: gensio_pty.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_pty.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_pty.Tpo -c -o libgensio_la-gensio_pty.lo `test -f 'gensio_pty.c' || echo '$(srcdir)/'`gensio_pty.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_pty.Tpo $(DEPDIR)/libgensio_la-gensio_pty.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_pty.c' object='libgensio_la-gensio_pty.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_pty.lo `test -f 'gensio_pty.c' || echo '$(srcdir)/'`gensio_pty.c libgensio_la-gensio_dummy.lo: gensio_dummy.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_dummy.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_dummy.Tpo -c -o libgensio_la-gensio_dummy.lo `test -f 'gensio_dummy.c' || echo '$(srcdir)/'`gensio_dummy.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_dummy.Tpo $(DEPDIR)/libgensio_la-gensio_dummy.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_dummy.c' object='libgensio_la-gensio_dummy.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_dummy.lo `test -f 'gensio_dummy.c' || echo '$(srcdir)/'`gensio_dummy.c libgensio_la-gensio_conacc.lo: gensio_conacc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_conacc.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_conacc.Tpo -c -o libgensio_la-gensio_conacc.lo `test -f 'gensio_conacc.c' || echo '$(srcdir)/'`gensio_conacc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_conacc.Tpo $(DEPDIR)/libgensio_la-gensio_conacc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_conacc.c' object='libgensio_la-gensio_conacc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_conacc.lo `test -f 'gensio_conacc.c' || echo '$(srcdir)/'`gensio_conacc.c libgensio_la-sergensio_serialdev.lo: sergensio_serialdev.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-sergensio_serialdev.lo -MD -MP -MF $(DEPDIR)/libgensio_la-sergensio_serialdev.Tpo -c -o libgensio_la-sergensio_serialdev.lo `test -f 'sergensio_serialdev.c' || echo '$(srcdir)/'`sergensio_serialdev.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-sergensio_serialdev.Tpo $(DEPDIR)/libgensio_la-sergensio_serialdev.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sergensio_serialdev.c' object='libgensio_la-sergensio_serialdev.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-sergensio_serialdev.lo `test -f 'sergensio_serialdev.c' || echo '$(srcdir)/'`sergensio_serialdev.c libgensio_la-seriallock.lo: seriallock.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-seriallock.lo -MD -MP -MF $(DEPDIR)/libgensio_la-seriallock.Tpo -c -o libgensio_la-seriallock.lo `test -f 'seriallock.c' || echo '$(srcdir)/'`seriallock.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-seriallock.Tpo $(DEPDIR)/libgensio_la-seriallock.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='seriallock.c' object='libgensio_la-seriallock.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-seriallock.lo `test -f 'seriallock.c' || echo '$(srcdir)/'`seriallock.c libgensio_la-gensio_echo.lo: gensio_echo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_echo.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_echo.Tpo -c -o libgensio_la-gensio_echo.lo `test -f 'gensio_echo.c' || echo '$(srcdir)/'`gensio_echo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_echo.Tpo $(DEPDIR)/libgensio_la-gensio_echo.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_echo.c' object='libgensio_la-gensio_echo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_echo.lo `test -f 'gensio_echo.c' || echo '$(srcdir)/'`gensio_echo.c libgensio_la-gensio_file.lo: gensio_file.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_file.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_file.Tpo -c -o libgensio_la-gensio_file.lo `test -f 'gensio_file.c' || echo '$(srcdir)/'`gensio_file.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_file.Tpo $(DEPDIR)/libgensio_la-gensio_file.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_file.c' object='libgensio_la-gensio_file.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_file.lo `test -f 'gensio_file.c' || echo '$(srcdir)/'`gensio_file.c libgensio_la-sergensio_ipmisol.lo: sergensio_ipmisol.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-sergensio_ipmisol.lo -MD -MP -MF $(DEPDIR)/libgensio_la-sergensio_ipmisol.Tpo -c -o libgensio_la-sergensio_ipmisol.lo `test -f 'sergensio_ipmisol.c' || echo '$(srcdir)/'`sergensio_ipmisol.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-sergensio_ipmisol.Tpo $(DEPDIR)/libgensio_la-sergensio_ipmisol.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sergensio_ipmisol.c' object='libgensio_la-sergensio_ipmisol.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-sergensio_ipmisol.lo `test -f 'sergensio_ipmisol.c' || echo '$(srcdir)/'`sergensio_ipmisol.c libgensio_la-gensio_mdns.lo: gensio_mdns.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_mdns.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_mdns.Tpo -c -o libgensio_la-gensio_mdns.lo `test -f 'gensio_mdns.c' || echo '$(srcdir)/'`gensio_mdns.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_mdns.Tpo $(DEPDIR)/libgensio_la-gensio_mdns.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_mdns.c' object='libgensio_la-gensio_mdns.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_mdns.lo `test -f 'gensio_mdns.c' || echo '$(srcdir)/'`gensio_mdns.c libgensio_la-gensio_sound.lo: gensio_sound.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_sound.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_sound.Tpo -c -o libgensio_la-gensio_sound.lo `test -f 'gensio_sound.c' || echo '$(srcdir)/'`gensio_sound.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_sound.Tpo $(DEPDIR)/libgensio_la-gensio_sound.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_sound.c' object='libgensio_la-gensio_sound.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_sound.lo `test -f 'gensio_sound.c' || echo '$(srcdir)/'`gensio_sound.c libgensio_la-gensio_cm108gpio.lo: gensio_cm108gpio.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_cm108gpio.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_cm108gpio.Tpo -c -o libgensio_la-gensio_cm108gpio.lo `test -f 'gensio_cm108gpio.c' || echo '$(srcdir)/'`gensio_cm108gpio.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_cm108gpio.Tpo $(DEPDIR)/libgensio_la-gensio_cm108gpio.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_cm108gpio.c' object='libgensio_la-gensio_cm108gpio.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_cm108gpio.lo `test -f 'gensio_cm108gpio.c' || echo '$(srcdir)/'`gensio_cm108gpio.c libgensio_la-gensio_ssl.lo: gensio_ssl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_ssl.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_ssl.Tpo -c -o libgensio_la-gensio_ssl.lo `test -f 'gensio_ssl.c' || echo '$(srcdir)/'`gensio_ssl.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_ssl.Tpo $(DEPDIR)/libgensio_la-gensio_ssl.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_ssl.c' object='libgensio_la-gensio_ssl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_ssl.lo `test -f 'gensio_ssl.c' || echo '$(srcdir)/'`gensio_ssl.c libgensio_la-gensio_certauth.lo: gensio_certauth.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_certauth.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_certauth.Tpo -c -o libgensio_la-gensio_certauth.lo `test -f 'gensio_certauth.c' || echo '$(srcdir)/'`gensio_certauth.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_certauth.Tpo $(DEPDIR)/libgensio_la-gensio_certauth.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_certauth.c' object='libgensio_la-gensio_certauth.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_certauth.lo `test -f 'gensio_certauth.c' || echo '$(srcdir)/'`gensio_certauth.c libgensio_la-gensio_mux.lo: gensio_mux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_mux.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_mux.Tpo -c -o libgensio_la-gensio_mux.lo `test -f 'gensio_mux.c' || echo '$(srcdir)/'`gensio_mux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_mux.Tpo $(DEPDIR)/libgensio_la-gensio_mux.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_mux.c' object='libgensio_la-gensio_mux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_mux.lo `test -f 'gensio_mux.c' || echo '$(srcdir)/'`gensio_mux.c libgensio_la-sergensio_telnet.lo: sergensio_telnet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-sergensio_telnet.lo -MD -MP -MF $(DEPDIR)/libgensio_la-sergensio_telnet.Tpo -c -o libgensio_la-sergensio_telnet.lo `test -f 'sergensio_telnet.c' || echo '$(srcdir)/'`sergensio_telnet.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-sergensio_telnet.Tpo $(DEPDIR)/libgensio_la-sergensio_telnet.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sergensio_telnet.c' object='libgensio_la-sergensio_telnet.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-sergensio_telnet.lo `test -f 'sergensio_telnet.c' || echo '$(srcdir)/'`sergensio_telnet.c libgensio_la-telnet.lo: telnet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-telnet.lo -MD -MP -MF $(DEPDIR)/libgensio_la-telnet.Tpo -c -o libgensio_la-telnet.lo `test -f 'telnet.c' || echo '$(srcdir)/'`telnet.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-telnet.Tpo $(DEPDIR)/libgensio_la-telnet.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='telnet.c' object='libgensio_la-telnet.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-telnet.lo `test -f 'telnet.c' || echo '$(srcdir)/'`telnet.c libgensio_la-gensio_msgdelim.lo: gensio_msgdelim.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_msgdelim.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_msgdelim.Tpo -c -o libgensio_la-gensio_msgdelim.lo `test -f 'gensio_msgdelim.c' || echo '$(srcdir)/'`gensio_msgdelim.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_msgdelim.Tpo $(DEPDIR)/libgensio_la-gensio_msgdelim.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_msgdelim.c' object='libgensio_la-gensio_msgdelim.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_msgdelim.lo `test -f 'gensio_msgdelim.c' || echo '$(srcdir)/'`gensio_msgdelim.c libgensio_la-gensio_relpkt.lo: gensio_relpkt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_relpkt.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_relpkt.Tpo -c -o libgensio_la-gensio_relpkt.lo `test -f 'gensio_relpkt.c' || echo '$(srcdir)/'`gensio_relpkt.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_relpkt.Tpo $(DEPDIR)/libgensio_la-gensio_relpkt.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_relpkt.c' object='libgensio_la-gensio_relpkt.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_relpkt.lo `test -f 'gensio_relpkt.c' || echo '$(srcdir)/'`gensio_relpkt.c libgensio_la-gensio_trace.lo: gensio_trace.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_trace.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_trace.Tpo -c -o libgensio_la-gensio_trace.lo `test -f 'gensio_trace.c' || echo '$(srcdir)/'`gensio_trace.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_trace.Tpo $(DEPDIR)/libgensio_la-gensio_trace.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_trace.c' object='libgensio_la-gensio_trace.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_trace.lo `test -f 'gensio_trace.c' || echo '$(srcdir)/'`gensio_trace.c libgensio_la-gensio_perf.lo: gensio_perf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_perf.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_perf.Tpo -c -o libgensio_la-gensio_perf.lo `test -f 'gensio_perf.c' || echo '$(srcdir)/'`gensio_perf.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_perf.Tpo $(DEPDIR)/libgensio_la-gensio_perf.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_perf.c' object='libgensio_la-gensio_perf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_perf.lo `test -f 'gensio_perf.c' || echo '$(srcdir)/'`gensio_perf.c libgensio_la-gensio_kiss.lo: gensio_kiss.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_kiss.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_kiss.Tpo -c -o libgensio_la-gensio_kiss.lo `test -f 'gensio_kiss.c' || echo '$(srcdir)/'`gensio_kiss.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_kiss.Tpo $(DEPDIR)/libgensio_la-gensio_kiss.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_kiss.c' object='libgensio_la-gensio_kiss.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_kiss.lo `test -f 'gensio_kiss.c' || echo '$(srcdir)/'`gensio_kiss.c libgensio_la-gensio_ax25.lo: gensio_ax25.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_ax25.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_ax25.Tpo -c -o libgensio_la-gensio_ax25.lo `test -f 'gensio_ax25.c' || echo '$(srcdir)/'`gensio_ax25.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_ax25.Tpo $(DEPDIR)/libgensio_la-gensio_ax25.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_ax25.c' object='libgensio_la-gensio_ax25.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_ax25.lo `test -f 'gensio_ax25.c' || echo '$(srcdir)/'`gensio_ax25.c libgensio_la-gensio_xlt.lo: gensio_xlt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_xlt.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_xlt.Tpo -c -o libgensio_la-gensio_xlt.lo `test -f 'gensio_xlt.c' || echo '$(srcdir)/'`gensio_xlt.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_xlt.Tpo $(DEPDIR)/libgensio_la-gensio_xlt.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_xlt.c' object='libgensio_la-gensio_xlt.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_xlt.lo `test -f 'gensio_xlt.c' || echo '$(srcdir)/'`gensio_xlt.c libgensio_la-gensio_keepopen.lo: gensio_keepopen.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_keepopen.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_keepopen.Tpo -c -o libgensio_la-gensio_keepopen.lo `test -f 'gensio_keepopen.c' || echo '$(srcdir)/'`gensio_keepopen.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_keepopen.Tpo $(DEPDIR)/libgensio_la-gensio_keepopen.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_keepopen.c' object='libgensio_la-gensio_keepopen.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_keepopen.lo `test -f 'gensio_keepopen.c' || echo '$(srcdir)/'`gensio_keepopen.c libgensio_la-gensio_script.lo: gensio_script.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_script.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_script.Tpo -c -o libgensio_la-gensio_script.lo `test -f 'gensio_script.c' || echo '$(srcdir)/'`gensio_script.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_script.Tpo $(DEPDIR)/libgensio_la-gensio_script.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_script.c' object='libgensio_la-gensio_script.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_script.lo `test -f 'gensio_script.c' || echo '$(srcdir)/'`gensio_script.c libgensio_la-gensio_ratelimit.lo: gensio_ratelimit.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_ratelimit.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_ratelimit.Tpo -c -o libgensio_la-gensio_ratelimit.lo `test -f 'gensio_ratelimit.c' || echo '$(srcdir)/'`gensio_ratelimit.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_ratelimit.Tpo $(DEPDIR)/libgensio_la-gensio_ratelimit.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_ratelimit.c' object='libgensio_la-gensio_ratelimit.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_ratelimit.lo `test -f 'gensio_ratelimit.c' || echo '$(srcdir)/'`gensio_ratelimit.c libgensio_la-gensio_afskmdm.lo: gensio_afskmdm.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_la-gensio_afskmdm.lo -MD -MP -MF $(DEPDIR)/libgensio_la-gensio_afskmdm.Tpo -c -o libgensio_la-gensio_afskmdm.lo `test -f 'gensio_afskmdm.c' || echo '$(srcdir)/'`gensio_afskmdm.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_la-gensio_afskmdm.Tpo $(DEPDIR)/libgensio_la-gensio_afskmdm.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_afskmdm.c' object='libgensio_la-gensio_afskmdm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_la-gensio_afskmdm.lo `test -f 'gensio_afskmdm.c' || echo '$(srcdir)/'`gensio_afskmdm.c libgensio_certauth_la-gensio_certauth.lo: gensio_certauth.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_certauth_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_certauth_la-gensio_certauth.lo -MD -MP -MF $(DEPDIR)/libgensio_certauth_la-gensio_certauth.Tpo -c -o libgensio_certauth_la-gensio_certauth.lo `test -f 'gensio_certauth.c' || echo '$(srcdir)/'`gensio_certauth.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_certauth_la-gensio_certauth.Tpo $(DEPDIR)/libgensio_certauth_la-gensio_certauth.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_certauth.c' object='libgensio_certauth_la-gensio_certauth.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_certauth_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_certauth_la-gensio_certauth.lo `test -f 'gensio_certauth.c' || echo '$(srcdir)/'`gensio_certauth.c libgensio_ipmisol_la-sergensio_ipmisol.lo: sergensio_ipmisol.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgensio_ipmisol_la_CFLAGS) $(CFLAGS) -MT libgensio_ipmisol_la-sergensio_ipmisol.lo -MD -MP -MF $(DEPDIR)/libgensio_ipmisol_la-sergensio_ipmisol.Tpo -c -o libgensio_ipmisol_la-sergensio_ipmisol.lo `test -f 'sergensio_ipmisol.c' || echo '$(srcdir)/'`sergensio_ipmisol.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_ipmisol_la-sergensio_ipmisol.Tpo $(DEPDIR)/libgensio_ipmisol_la-sergensio_ipmisol.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sergensio_ipmisol.c' object='libgensio_ipmisol_la-sergensio_ipmisol.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgensio_ipmisol_la_CFLAGS) $(CFLAGS) -c -o libgensio_ipmisol_la-sergensio_ipmisol.lo `test -f 'sergensio_ipmisol.c' || echo '$(srcdir)/'`sergensio_ipmisol.c libgensio_openipmi_oshandler_la-gensio_openipmi_oshandler.lo: gensio_openipmi_oshandler.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_openipmi_oshandler_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_openipmi_oshandler_la-gensio_openipmi_oshandler.lo -MD -MP -MF $(DEPDIR)/libgensio_openipmi_oshandler_la-gensio_openipmi_oshandler.Tpo -c -o libgensio_openipmi_oshandler_la-gensio_openipmi_oshandler.lo `test -f 'gensio_openipmi_oshandler.c' || echo '$(srcdir)/'`gensio_openipmi_oshandler.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_openipmi_oshandler_la-gensio_openipmi_oshandler.Tpo $(DEPDIR)/libgensio_openipmi_oshandler_la-gensio_openipmi_oshandler.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_openipmi_oshandler.c' object='libgensio_openipmi_oshandler_la-gensio_openipmi_oshandler.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_openipmi_oshandler_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_openipmi_oshandler_la-gensio_openipmi_oshandler.lo `test -f 'gensio_openipmi_oshandler.c' || echo '$(srcdir)/'`gensio_openipmi_oshandler.c libgensio_ssl_la-gensio_ssl.lo: gensio_ssl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_ssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensio_ssl_la-gensio_ssl.lo -MD -MP -MF $(DEPDIR)/libgensio_ssl_la-gensio_ssl.Tpo -c -o libgensio_ssl_la-gensio_ssl.lo `test -f 'gensio_ssl.c' || echo '$(srcdir)/'`gensio_ssl.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensio_ssl_la-gensio_ssl.Tpo $(DEPDIR)/libgensio_ssl_la-gensio_ssl.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gensio_ssl.c' object='libgensio_ssl_la-gensio_ssl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensio_ssl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensio_ssl_la-gensio_ssl.lo `test -f 'gensio_ssl.c' || echo '$(srcdir)/'`gensio_ssl.c libgensiomdns_la-mdns.lo: mdns.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensiomdns_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensiomdns_la-mdns.lo -MD -MP -MF $(DEPDIR)/libgensiomdns_la-mdns.Tpo -c -o libgensiomdns_la-mdns.lo `test -f 'mdns.c' || echo '$(srcdir)/'`mdns.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensiomdns_la-mdns.Tpo $(DEPDIR)/libgensiomdns_la-mdns.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mdns.c' object='libgensiomdns_la-mdns.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensiomdns_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensiomdns_la-mdns.lo `test -f 'mdns.c' || echo '$(srcdir)/'`mdns.c libgensiomdns_la-avahi_watcher.lo: avahi_watcher.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensiomdns_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensiomdns_la-avahi_watcher.lo -MD -MP -MF $(DEPDIR)/libgensiomdns_la-avahi_watcher.Tpo -c -o libgensiomdns_la-avahi_watcher.lo `test -f 'avahi_watcher.c' || echo '$(srcdir)/'`avahi_watcher.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensiomdns_la-avahi_watcher.Tpo $(DEPDIR)/libgensiomdns_la-avahi_watcher.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='avahi_watcher.c' object='libgensiomdns_la-avahi_watcher.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensiomdns_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensiomdns_la-avahi_watcher.lo `test -f 'avahi_watcher.c' || echo '$(srcdir)/'`avahi_watcher.c libgensioosh_la-os_osops.lo: os_osops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensioosh_la-os_osops.lo -MD -MP -MF $(DEPDIR)/libgensioosh_la-os_osops.Tpo -c -o libgensioosh_la-os_osops.lo `test -f 'os_osops.c' || echo '$(srcdir)/'`os_osops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensioosh_la-os_osops.Tpo $(DEPDIR)/libgensioosh_la-os_osops.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os_osops.c' object='libgensioosh_la-os_osops.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensioosh_la-os_osops.lo `test -f 'os_osops.c' || echo '$(srcdir)/'`os_osops.c libgensioosh_la-circbuf.lo: circbuf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensioosh_la-circbuf.lo -MD -MP -MF $(DEPDIR)/libgensioosh_la-circbuf.Tpo -c -o libgensioosh_la-circbuf.lo `test -f 'circbuf.c' || echo '$(srcdir)/'`circbuf.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensioosh_la-circbuf.Tpo $(DEPDIR)/libgensioosh_la-circbuf.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='circbuf.c' object='libgensioosh_la-circbuf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensioosh_la-circbuf.lo `test -f 'circbuf.c' || echo '$(srcdir)/'`circbuf.c libgensioosh_la-os_osops_env.lo: os_osops_env.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensioosh_la-os_osops_env.lo -MD -MP -MF $(DEPDIR)/libgensioosh_la-os_osops_env.Tpo -c -o libgensioosh_la-os_osops_env.lo `test -f 'os_osops_env.c' || echo '$(srcdir)/'`os_osops_env.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensioosh_la-os_osops_env.Tpo $(DEPDIR)/libgensioosh_la-os_osops_env.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os_osops_env.c' object='libgensioosh_la-os_osops_env.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensioosh_la-os_osops_env.lo `test -f 'os_osops_env.c' || echo '$(srcdir)/'`os_osops_env.c libgensioosh_la-net_addrinfo.lo: net_addrinfo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensioosh_la-net_addrinfo.lo -MD -MP -MF $(DEPDIR)/libgensioosh_la-net_addrinfo.Tpo -c -o libgensioosh_la-net_addrinfo.lo `test -f 'net_addrinfo.c' || echo '$(srcdir)/'`net_addrinfo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensioosh_la-net_addrinfo.Tpo $(DEPDIR)/libgensioosh_la-net_addrinfo.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='net_addrinfo.c' object='libgensioosh_la-net_addrinfo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensioosh_la-net_addrinfo.lo `test -f 'net_addrinfo.c' || echo '$(srcdir)/'`net_addrinfo.c libgensioosh_la-net_stdsock.lo: net_stdsock.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensioosh_la-net_stdsock.lo -MD -MP -MF $(DEPDIR)/libgensioosh_la-net_stdsock.Tpo -c -o libgensioosh_la-net_stdsock.lo `test -f 'net_stdsock.c' || echo '$(srcdir)/'`net_stdsock.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensioosh_la-net_stdsock.Tpo $(DEPDIR)/libgensioosh_la-net_stdsock.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='net_stdsock.c' object='libgensioosh_la-net_stdsock.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensioosh_la-net_stdsock.lo `test -f 'net_stdsock.c' || echo '$(srcdir)/'`net_stdsock.c libgensioosh_la-net_ax25_addr.lo: net_ax25_addr.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensioosh_la-net_ax25_addr.lo -MD -MP -MF $(DEPDIR)/libgensioosh_la-net_ax25_addr.Tpo -c -o libgensioosh_la-net_ax25_addr.lo `test -f 'net_ax25_addr.c' || echo '$(srcdir)/'`net_ax25_addr.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensioosh_la-net_ax25_addr.Tpo $(DEPDIR)/libgensioosh_la-net_ax25_addr.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='net_ax25_addr.c' object='libgensioosh_la-net_ax25_addr.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensioosh_la-net_ax25_addr.lo `test -f 'net_ax25_addr.c' || echo '$(srcdir)/'`net_ax25_addr.c libgensioosh_la-utils.lo: utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensioosh_la-utils.lo -MD -MP -MF $(DEPDIR)/libgensioosh_la-utils.Tpo -c -o libgensioosh_la-utils.lo `test -f 'utils.c' || echo '$(srcdir)/'`utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensioosh_la-utils.Tpo $(DEPDIR)/libgensioosh_la-utils.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils.c' object='libgensioosh_la-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensioosh_la-utils.lo `test -f 'utils.c' || echo '$(srcdir)/'`utils.c libgensioosh_la-net_addr.lo: net_addr.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensioosh_la-net_addr.lo -MD -MP -MF $(DEPDIR)/libgensioosh_la-net_addr.Tpo -c -o libgensioosh_la-net_addr.lo `test -f 'net_addr.c' || echo '$(srcdir)/'`net_addr.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensioosh_la-net_addr.Tpo $(DEPDIR)/libgensioosh_la-net_addr.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='net_addr.c' object='libgensioosh_la-net_addr.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensioosh_la-net_addr.lo `test -f 'net_addr.c' || echo '$(srcdir)/'`net_addr.c libgensioosh_la-os_unix.lo: os_unix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensioosh_la-os_unix.lo -MD -MP -MF $(DEPDIR)/libgensioosh_la-os_unix.Tpo -c -o libgensioosh_la-os_unix.lo `test -f 'os_unix.c' || echo '$(srcdir)/'`os_unix.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensioosh_la-os_unix.Tpo $(DEPDIR)/libgensioosh_la-os_unix.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os_unix.c' object='libgensioosh_la-os_unix.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensioosh_la-os_unix.lo `test -f 'os_unix.c' || echo '$(srcdir)/'`os_unix.c libgensioosh_la-os_unix_selector.lo: os_unix_selector.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensioosh_la-os_unix_selector.lo -MD -MP -MF $(DEPDIR)/libgensioosh_la-os_unix_selector.Tpo -c -o libgensioosh_la-os_unix_selector.lo `test -f 'os_unix_selector.c' || echo '$(srcdir)/'`os_unix_selector.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensioosh_la-os_unix_selector.Tpo $(DEPDIR)/libgensioosh_la-os_unix_selector.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os_unix_selector.c' object='libgensioosh_la-os_unix_selector.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensioosh_la-os_unix_selector.lo `test -f 'os_unix_selector.c' || echo '$(srcdir)/'`os_unix_selector.c libgensioosh_la-os_win.lo: os_win.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensioosh_la-os_win.lo -MD -MP -MF $(DEPDIR)/libgensioosh_la-os_win.Tpo -c -o libgensioosh_la-os_win.lo `test -f 'os_win.c' || echo '$(srcdir)/'`os_win.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensioosh_la-os_win.Tpo $(DEPDIR)/libgensioosh_la-os_win.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os_win.c' object='libgensioosh_la-os_win.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensioosh_la-os_win.lo `test -f 'os_win.c' || echo '$(srcdir)/'`os_win.c libgensioosh_la-errtrig.lo: errtrig.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgensioosh_la-errtrig.lo -MD -MP -MF $(DEPDIR)/libgensioosh_la-errtrig.Tpo -c -o libgensioosh_la-errtrig.lo `test -f 'errtrig.c' || echo '$(srcdir)/'`errtrig.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensioosh_la-errtrig.Tpo $(DEPDIR)/libgensioosh_la-errtrig.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='errtrig.c' object='libgensioosh_la-errtrig.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensioosh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgensioosh_la-errtrig.lo `test -f 'errtrig.c' || echo '$(srcdir)/'`errtrig.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkgconfigexecDATA: $(pkgconfigexec_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfigexec_DATA)'; test -n "$(pkgconfigexecdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigexecdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigexecdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigexecdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigexecdir)" || exit $$?; \ done uninstall-pkgconfigexecDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfigexec_DATA)'; test -n "$(pkgconfigexecdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigexecdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) install-EXTRALTLIBRARIES: install-libLTLIBRARIES install-gensiolibexecLTLIBRARIES: install-libLTLIBRARIES installdirs: for dir in "$(DESTDIR)$(gensiolibexecdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigexecdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-gensiolibexecLTLIBRARIES \ clean-libLTLIBRARIES clean-libtool mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/gensio_afskmdm.Plo -rm -f ./$(DEPDIR)/gensio_ax25.Plo -rm -f ./$(DEPDIR)/gensio_cm108gpio.Plo -rm -f ./$(DEPDIR)/gensio_conacc.Plo -rm -f ./$(DEPDIR)/gensio_dgram.Plo -rm -f ./$(DEPDIR)/gensio_dummy.Plo -rm -f ./$(DEPDIR)/gensio_echo.Plo -rm -f ./$(DEPDIR)/gensio_file.Plo -rm -f ./$(DEPDIR)/gensio_keepopen.Plo -rm -f ./$(DEPDIR)/gensio_kiss.Plo -rm -f ./$(DEPDIR)/gensio_mdns.Plo -rm -f ./$(DEPDIR)/gensio_msgdelim.Plo -rm -f ./$(DEPDIR)/gensio_mux.Plo -rm -f ./$(DEPDIR)/gensio_net.Plo -rm -f ./$(DEPDIR)/gensio_perf.Plo -rm -f ./$(DEPDIR)/gensio_pty.Plo -rm -f ./$(DEPDIR)/gensio_ratelimit.Plo -rm -f ./$(DEPDIR)/gensio_relpkt.Plo -rm -f ./$(DEPDIR)/gensio_script.Plo -rm -f ./$(DEPDIR)/gensio_sctp.Plo -rm -f ./$(DEPDIR)/gensio_sound.Plo -rm -f ./$(DEPDIR)/gensio_stdio.Plo -rm -f ./$(DEPDIR)/gensio_trace.Plo -rm -f ./$(DEPDIR)/gensio_xlt.Plo -rm -f ./$(DEPDIR)/libgensio_certauth_la-gensio_certauth.Plo -rm -f ./$(DEPDIR)/libgensio_ipmisol_la-sergensio_ipmisol.Plo -rm -f ./$(DEPDIR)/libgensio_la-acc.Plo -rm -f ./$(DEPDIR)/libgensio_la-acc_gensio.Plo -rm -f ./$(DEPDIR)/libgensio_la-buffer.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_afskmdm.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_ax25.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_base.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_certauth.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_cm108gpio.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_conacc.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_dgram.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_dummy.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_echo.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_file.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_keepopen.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_kiss.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_mdns.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_msgdelim.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_mux.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_net.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_perf.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_pty.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_ratelimit.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_relpkt.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_script.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_sctp.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_sound.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_ssl.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_stdio.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_trace.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_xlt.Plo -rm -f ./$(DEPDIR)/libgensio_la-ll_fd.Plo -rm -f ./$(DEPDIR)/libgensio_la-ll_gensio.Plo -rm -f ./$(DEPDIR)/libgensio_la-sergensio_ipmisol.Plo -rm -f ./$(DEPDIR)/libgensio_la-sergensio_serialdev.Plo -rm -f ./$(DEPDIR)/libgensio_la-sergensio_telnet.Plo -rm -f ./$(DEPDIR)/libgensio_la-seriallock.Plo -rm -f ./$(DEPDIR)/libgensio_la-telnet.Plo -rm -f ./$(DEPDIR)/libgensio_openipmi_oshandler_la-gensio_openipmi_oshandler.Plo -rm -f ./$(DEPDIR)/libgensio_ssl_la-gensio_ssl.Plo -rm -f ./$(DEPDIR)/libgensiomdns_la-avahi_watcher.Plo -rm -f ./$(DEPDIR)/libgensiomdns_la-mdns.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-circbuf.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-errtrig.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-net_addr.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-net_addrinfo.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-net_ax25_addr.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-net_stdsock.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-os_osops.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-os_osops_env.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-os_unix.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-os_unix_selector.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-os_win.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-utils.Plo -rm -f ./$(DEPDIR)/sergensio_serialdev.Plo -rm -f ./$(DEPDIR)/sergensio_telnet.Plo -rm -f ./$(DEPDIR)/seriallock.Plo -rm -f ./$(DEPDIR)/telnet.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-gensiolibexecLTLIBRARIES \ install-libLTLIBRARIES install-pkgconfigexecDATA @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/gensio_afskmdm.Plo -rm -f ./$(DEPDIR)/gensio_ax25.Plo -rm -f ./$(DEPDIR)/gensio_cm108gpio.Plo -rm -f ./$(DEPDIR)/gensio_conacc.Plo -rm -f ./$(DEPDIR)/gensio_dgram.Plo -rm -f ./$(DEPDIR)/gensio_dummy.Plo -rm -f ./$(DEPDIR)/gensio_echo.Plo -rm -f ./$(DEPDIR)/gensio_file.Plo -rm -f ./$(DEPDIR)/gensio_keepopen.Plo -rm -f ./$(DEPDIR)/gensio_kiss.Plo -rm -f ./$(DEPDIR)/gensio_mdns.Plo -rm -f ./$(DEPDIR)/gensio_msgdelim.Plo -rm -f ./$(DEPDIR)/gensio_mux.Plo -rm -f ./$(DEPDIR)/gensio_net.Plo -rm -f ./$(DEPDIR)/gensio_perf.Plo -rm -f ./$(DEPDIR)/gensio_pty.Plo -rm -f ./$(DEPDIR)/gensio_ratelimit.Plo -rm -f ./$(DEPDIR)/gensio_relpkt.Plo -rm -f ./$(DEPDIR)/gensio_script.Plo -rm -f ./$(DEPDIR)/gensio_sctp.Plo -rm -f ./$(DEPDIR)/gensio_sound.Plo -rm -f ./$(DEPDIR)/gensio_stdio.Plo -rm -f ./$(DEPDIR)/gensio_trace.Plo -rm -f ./$(DEPDIR)/gensio_xlt.Plo -rm -f ./$(DEPDIR)/libgensio_certauth_la-gensio_certauth.Plo -rm -f ./$(DEPDIR)/libgensio_ipmisol_la-sergensio_ipmisol.Plo -rm -f ./$(DEPDIR)/libgensio_la-acc.Plo -rm -f ./$(DEPDIR)/libgensio_la-acc_gensio.Plo -rm -f ./$(DEPDIR)/libgensio_la-buffer.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_afskmdm.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_ax25.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_base.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_certauth.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_cm108gpio.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_conacc.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_dgram.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_dummy.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_echo.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_file.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_keepopen.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_kiss.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_mdns.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_msgdelim.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_mux.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_net.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_perf.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_pty.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_ratelimit.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_relpkt.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_script.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_sctp.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_sound.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_ssl.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_stdio.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_trace.Plo -rm -f ./$(DEPDIR)/libgensio_la-gensio_xlt.Plo -rm -f ./$(DEPDIR)/libgensio_la-ll_fd.Plo -rm -f ./$(DEPDIR)/libgensio_la-ll_gensio.Plo -rm -f ./$(DEPDIR)/libgensio_la-sergensio_ipmisol.Plo -rm -f ./$(DEPDIR)/libgensio_la-sergensio_serialdev.Plo -rm -f ./$(DEPDIR)/libgensio_la-sergensio_telnet.Plo -rm -f ./$(DEPDIR)/libgensio_la-seriallock.Plo -rm -f ./$(DEPDIR)/libgensio_la-telnet.Plo -rm -f ./$(DEPDIR)/libgensio_openipmi_oshandler_la-gensio_openipmi_oshandler.Plo -rm -f ./$(DEPDIR)/libgensio_ssl_la-gensio_ssl.Plo -rm -f ./$(DEPDIR)/libgensiomdns_la-avahi_watcher.Plo -rm -f ./$(DEPDIR)/libgensiomdns_la-mdns.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-circbuf.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-errtrig.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-net_addr.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-net_addrinfo.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-net_ax25_addr.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-net_stdsock.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-os_osops.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-os_osops_env.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-os_unix.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-os_unix_selector.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-os_win.Plo -rm -f ./$(DEPDIR)/libgensioosh_la-utils.Plo -rm -f ./$(DEPDIR)/sergensio_serialdev.Plo -rm -f ./$(DEPDIR)/sergensio_telnet.Plo -rm -f ./$(DEPDIR)/seriallock.Plo -rm -f ./$(DEPDIR)/telnet.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-gensiolibexecLTLIBRARIES \ uninstall-libLTLIBRARIES uninstall-pkgconfigexecDATA @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook .MAKE: install-am install-exec-am install-strip uninstall-am .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-gensiolibexecLTLIBRARIES \ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-exec-hook \ install-gensiolibexecLTLIBRARIES install-html install-html-am \ install-info install-info-am install-libLTLIBRARIES \ install-man install-pdf install-pdf-am \ install-pkgconfigexecDATA install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ uninstall-gensiolibexecLTLIBRARIES uninstall-hook \ uninstall-libLTLIBRARIES uninstall-pkgconfigexecDATA .PRECIOUS: Makefile # We need to make sure the main libraries are compiled and ready before # doing the plugins, since the plugins link against them. $(gensiolibexec_LTLIBRARIES): $(lib_LTLIBRARIES) # Same thing as above, but for relinking on installation. We have to # have the main libraries installed before relinking. The rule as # specified below add prerequisites to the targets instead of creating # a rule. install-gensiolibexecLTLIBRARIES gensiolibexec-dummyprereq: install-libLTLIBRARIES .PHONY gensiolibexec-dummyprereq: install-exec-hook: @(cd $(DESTDIR)$(gensiolibexecdir) && $(RM) -f $(gensiolibexec_LTLIBRARIES)) @(cd $(DESTDIR)$(gensiolibexecdir) && $(RM) -f $(xgensio_libs)) # Since we remove the bogus .la and .a files above at install time, # libtool will not remove the .so or .dll files since the .la file is # no longer there. We have to do that by hand. uninstall-hook: @(cd $(DESTDIR)$(gensiolibexecdir) && $(RM) -f $(xgensio_solibs)) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/lib/libgensio.pc.in0000664000175000017500000000046014664224267012150 prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libgensio Description: A library to abstract stream I/O like serial port, TCP, telnet, UDP, SSL, IPMI SOL, etc. Version: @VERSION@ Libs: -L${libdir} -lgensioosh -lgensio Libs.private: @BUILTIN_MDNS_LIBS@ @BASE_LIBS@gensio-3.0.0/lib/avahi_watcher.h0000664000175000017500000000147714664212465012230 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2020 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #ifndef AVAHI_WATCHER_H #define AVAHI_WATCHER_H #include #include /* * You must call these before/after doing any Avahi calls. Avahi is * single-threaded. */ void gensio_avahi_lock(AvahiPoll *ap); void gensio_avahi_unlock(AvahiPoll *ap); /* Allocate an Avahi poll structure. You only need one of these. */ struct AvahiPoll *alloc_gensio_avahi_poll(struct gensio_os_funcs *o); typedef void (*gensio_avahi_done)(AvahiPoll *ap, void *userdata); void gensio_avahi_poll_disable(AvahiPoll *ap); void gensio_avahi_poll_free(AvahiPoll *ap, gensio_avahi_done done, void *userdata); #endif /* AVAHI_WATCHER_H */ gensio-3.0.0/lib/buffer.c0000664000175000017500000000512314664224267010662 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include static int do_write(gensio_buffer_do_write tdo_write, void *cb_data, void *buf, unsigned int buflen, unsigned int *written) { int err = 0; unsigned int write_count; err = tdo_write(cb_data, buf, buflen, &write_count); if (!err) *written = write_count; return err; } int gensio_buffer_write(gensio_buffer_do_write tdo_write, void *cb_data, struct gensio_buffer *buf) { int err; unsigned int write_count; unsigned int towrite1; unsigned int towrite2 = 0; if (buf->pos + buf->cursize > buf->maxsize) { towrite1 = buf->maxsize - buf->pos; towrite2 = buf->cursize - towrite1; } else { towrite1 = buf->cursize; } if (towrite1 > 0) { err = do_write(tdo_write, cb_data, buf->buf + buf->pos, towrite1, &write_count); if (err) return err; buf->pos += write_count; buf->cursize -= write_count; if (write_count < towrite1) return 0; } if (towrite2 > 0) { /* We wrapped */ buf->pos = 0; err = do_write(tdo_write, cb_data, buf->buf, towrite2, &write_count); if (err) return err; buf->pos += write_count; buf->cursize -= write_count; } return 0; } unsigned int gensio_buffer_output(struct gensio_buffer *buf, const unsigned char *data, unsigned int len) { unsigned int end; if (gensio_buffer_left(buf) < len) len = gensio_buffer_left(buf); end = buf->pos + buf->cursize; if (end > buf->maxsize) end -= buf->maxsize; if (end + len > buf->maxsize) { unsigned int availend = buf->maxsize - end; memcpy(buf->buf + end, data, availend); buf->cursize += availend; end = 0; len -= availend; data += availend; } memcpy(buf->buf + end, data, len); buf->cursize += len; return len; } unsigned int gensio_buffer_outchar(struct gensio_buffer *buf, unsigned char data) { unsigned int end; if (gensio_buffer_left(buf) < 1) return 0; end = buf->pos + buf->cursize; if (end >= buf->maxsize) end -= buf->maxsize; buf->buf[end] = data; buf->cursize += 1; return 1; } int gensio_buffer_init(struct gensio_buffer *buf, unsigned char *data, unsigned int datasize) { if (data) { buf->buf = data; } else { buf->buf = malloc(datasize); if (!buf->buf) return GE_NOMEM; } buf->maxsize = datasize; buf->cursize = 0; buf->pos = 0; return 0; } gensio-3.0.0/lib/os_unix.c0000664000175000017500000016265715007164240011077 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include "pthread_handler.h" #include #include #include #include #include #include #include #include "utils.h" #include #include #include #include #include #include #include #include #include #include #include #include "errtrig.h" struct gensio_data { struct selector_s *sel; unsigned int flags; lock_type reflock; unsigned int refcount; bool freesel; int wake_sig; struct gensio_os_proc_data *pdata; struct gensio_memtrack *mtrack; }; static void * gensio_unix_zalloc(struct gensio_os_funcs *o, gensiods size) { struct gensio_data *d = o->user_data; TRACE_MEM; return gensio_i_zalloc(d->mtrack, size, TRACE_MEM_CALLERS, TRACE_MEM_CALLERS_SIZE); } static void gensio_unix_free(struct gensio_os_funcs *o, void *v) { struct gensio_data *d = o->user_data; TRACE_MEM; gensio_i_free(d->mtrack, v, TRACE_MEM_CALLERS, TRACE_MEM_CALLERS_SIZE); } static void add_to_timeval(struct timeval *tv1, gensio_time *t2) { tv1->tv_sec += t2->secs; tv1->tv_usec += (t2->nsecs + 500) / 1000; while (tv1->tv_usec > 1000000) { tv1->tv_usec -= 1000000; tv1->tv_sec += 1; } while (tv1->tv_usec < 0) { tv1->tv_usec += 1000000; tv1->tv_sec -= 1; } } static struct timeval * gensio_time_to_timeval(struct timeval *tv, gensio_time *t) { if (!t) return NULL; tv->tv_sec = t->secs; tv->tv_usec = (t->nsecs + 500) / 1000; return tv; } static void timeval_to_gensio_time(gensio_time *t, struct timeval *tv) { if (tv) { t->secs = tv->tv_sec; t->nsecs = tv->tv_usec * 1000; } } #ifdef USE_PTHREADS #include static int init_mutex(unsigned int flags, lock_type *mutex) { pthread_mutexattr_t mattr; pthread_mutexattr_init(&mattr); if (flags & GENSIO_OS_FUNCS_FLAG_PRIO_INHERIT) { #ifdef PTHREAD_PRIO_INHERIT int rv = pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT); if (rv) return rv; #else return GE_NOTSUP; #endif } pthread_mutex_init(mutex, &mattr); return 0; } struct waiter_data { pthread_t tid; int wake_sig; unsigned int count; struct waiter_data *prev; struct waiter_data *next; }; typedef struct waiter_s { struct gensio_os_funcs *o; struct selector_s *sel; int wake_sig; unsigned int count; pthread_mutex_t lock; struct waiter_data wts; } waiter_t; static waiter_t * alloc_waiter(struct gensio_os_funcs *o, struct selector_s *sel, int wake_sig) { waiter_t *waiter; struct gensio_data *d = o->user_data; waiter = o->zalloc(o, sizeof(waiter_t)); if (waiter) { waiter->o = o; waiter->wake_sig = wake_sig; waiter->sel = sel; init_mutex(d->flags, &waiter->lock); waiter->wts.next = &waiter->wts; waiter->wts.prev = &waiter->wts; } return waiter; } static void free_waiter(waiter_t *waiter) { assert(waiter); assert(waiter->wts.next == waiter->wts.prev); pthread_mutex_destroy(&waiter->lock); waiter->o->free(waiter->o, waiter); } static void wake_thread_send_sig_waiter(long thread_id, void *cb_data) { struct waiter_data *w = cb_data; pthread_kill(w->tid, w->wake_sig); } static void i_wake_waiter(waiter_t *waiter, unsigned int count) { struct waiter_data *w; w = waiter->wts.next; while (w != &waiter->wts && count > 0) { if (w->count > 0) { if (w->count >= count) { w->count -= count; count = 0; } else { count -= w->count; w->count = 0; } if (w->count == 0) { #ifdef BROKEN_PSELECT sel_wake_one(waiter->sel, (long) w->tid, wake_thread_send_sig_waiter, w); #else pthread_kill(w->tid, w->wake_sig); #endif } } w = w->next; } waiter->count += count; } static int i_wait_for_waiter_timeout(waiter_t *waiter, unsigned int count, gensio_time *timeout, bool intr, sigset_t *sigmask) { struct waiter_data w; struct timeval tv, *rtv; int err = 0; w.tid = pthread_self(); w.wake_sig = waiter->wake_sig; w.next = NULL; w.prev = NULL; w.count = count; LOCK(&waiter->lock); waiter->wts.next->prev = &w; w.next = waiter->wts.next; waiter->wts.next = &w; w.prev = &waiter->wts; rtv = gensio_time_to_timeval(&tv, timeout); if (waiter->count > 0) { if (waiter->count >= w.count) { waiter->count -= w.count; w.count = 0; } else { w.count -= waiter->count; waiter->count = 0; } } while (w.count > 0) { UNLOCK(&waiter->lock); if (intr) err = sel_select_intr_sigmask(waiter->sel, wake_thread_send_sig_waiter, (long) w.tid, &w, rtv, sigmask); else err = sel_select(waiter->sel, wake_thread_send_sig_waiter, (long) w.tid, &w, rtv); if (err < 0) err = errno; else if (err == 0) err = ETIMEDOUT; else err = 0; /* lock may affect errno, delay it until here. */ LOCK(&waiter->lock); if (err) break; } timeval_to_gensio_time(timeout, rtv); w.next->prev = w.prev; w.prev->next = w.next; if (w.count == 0) { err = 0; /* If our count was decremented to zero, ignore errors. */ } else if (err) { /* * If there was an error, re-add whatever was decremented to the * waiter. */ i_wake_waiter(waiter, count - w.count); } UNLOCK(&waiter->lock); return err; } static void wake_waiter(waiter_t *waiter) { LOCK(&waiter->lock); i_wake_waiter(waiter, 1); UNLOCK(&waiter->lock); } #else /* USE_PTHREADS */ static int init_mutex(unsigned int flags, lock_type *mutex) { LOCK_INIT(mutex); return 0; } typedef struct waiter_s { struct gensio_os_funcs *o; unsigned int count; struct selector_s *sel; } waiter_t; static waiter_t * alloc_waiter(struct gensio_os_funcs *o, struct selector_s *sel, int wake_sig) { waiter_t *waiter; waiter = o->zalloc(o, sizeof(waiter_t)); if (waiter) { waiter->o = o; waiter->sel = sel; } return waiter; } static void free_waiter(waiter_t *waiter) { assert(waiter); waiter->o->free(waiter->o, waiter); } static int i_wait_for_waiter_timeout(waiter_t *waiter, unsigned int count, gensio_time *timeout, bool intr, sigset_t *sigmask) { struct timeval tv, *rtv; int err = 0; rtv = gensio_time_to_timeval(&tv, timeout); while (waiter->count < count) { if (intr) err = sel_select_intr_sigmask(waiter->sel, 0, 0, NULL, rtv, sigmask); else err = sel_select(waiter->sel, 0, 0, NULL, rtv); if (err < 0) { err = errno; break; } else if (err == 0) { err = ETIMEDOUT; break; } err = 0; } timeval_to_gensio_time(timeout, rtv); if (!err) waiter->count -= count; return err; } static void wake_waiter(waiter_t *waiter) { waiter->count++; } #endif /* USE_PTHREADS */ static int wait_for_waiter_timeout_intr_sigmask(waiter_t *waiter, unsigned int count, gensio_time *timeout, sigset_t *sigmask) { return i_wait_for_waiter_timeout(waiter, count, timeout, true, sigmask); } struct gensio_lock { struct gensio_os_funcs *f; lock_type lock; }; static struct gensio_lock * gensio_unix_alloc_lock(struct gensio_os_funcs *f) { struct gensio_lock *lock = f->zalloc(f, sizeof(*lock)); struct gensio_data *d = f->user_data; if (lock) { lock->f = f; if (init_mutex(d->flags, &lock->lock)) { f->free(f, lock); return NULL; } } return lock; } static void gensio_unix_free_lock(struct gensio_lock *lock) { LOCK_DESTROY(&lock->lock); lock->f->free(lock->f, lock); } static void gensio_unix_lock(struct gensio_lock *lock) { LOCK(&lock->lock); } static void gensio_unix_unlock(struct gensio_lock *lock) { UNLOCK(&lock->lock); } struct gensio_iod_file { struct gensio_lock *lock; struct gensio_runner *runner; bool read_enabled; bool write_enabled; bool do_clear; bool in_handler; }; struct gensio_iod_socket { void *sockinfo; }; struct gensio_iod_pty { const char **argv; const char **env; pid_t pid; char *start_dir; }; struct gensio_iod_unix { struct gensio_iod r; int orig_fd; int fd; int sfd; enum gensio_iod_type type; bool handlers_set; bool is_stdio; void *cb_data; void (*read_handler)(struct gensio_iod *iod, void *cb_data); void (*write_handler)(struct gensio_iod *iod, void *cb_data); void (*except_handler)(struct gensio_iod *iod, void *cb_data); void (*cleared_handler)(struct gensio_iod *iod, void *cb_data); struct stdio_mode *mode; /* Used by dev and pty. */ struct gensio_unix_termios *termios; union { struct gensio_iod_file file; struct gensio_iod_socket socket; struct gensio_iod_pty pty; } u; }; #define i_to_sel(i) gensio_container_of(i, struct gensio_iod_unix, r); static void iod_read_handler(int fd, void *cb_data) { struct gensio_iod_unix *iod = cb_data; iod->read_handler(&iod->r, iod->cb_data); } static void iod_write_handler(int fd, void *cb_data) { struct gensio_iod_unix *iod = cb_data; iod->write_handler(&iod->r, iod->cb_data); } static void iod_except_handler(int fd, void *cb_data) { struct gensio_iod_unix *iod = cb_data; iod->except_handler(&iod->r, iod->cb_data); } static void iod_cleared_handler(int fd, void *cb_data) { struct gensio_iod_unix *iod = cb_data; iod->handlers_set = false; iod->cleared_handler(&iod->r, iod->cb_data); } static int gensio_unix_set_fd_handlers(struct gensio_iod *iiod, void *cb_data, void (*read_handler)(struct gensio_iod *iod, void *cb_data), void (*write_handler)(struct gensio_iod *iod, void *cb_data), void (*except_handler)(struct gensio_iod *iod, void *cb_data), void (*cleared_handler)(struct gensio_iod *iod, void *cb_data)) { struct gensio_iod_unix *iod = i_to_sel(iiod); struct gensio_os_funcs *f = iiod->f; struct gensio_data *d = f->user_data; int rv = 0; if (iod->handlers_set) return GE_INUSE; iod->cb_data = cb_data; iod->read_handler = read_handler; iod->write_handler = write_handler; iod->except_handler = except_handler; iod->cleared_handler = cleared_handler; if (iod->type != GENSIO_IOD_FILE) rv = sel_set_fd_handlers(d->sel, iod->fd, iod, read_handler ? iod_read_handler : NULL, write_handler ? iod_write_handler : NULL, except_handler ? iod_except_handler : NULL, cleared_handler ? iod_cleared_handler : NULL); if (!rv) iod->handlers_set = true; return gensio_os_err_to_err(f, rv); } static void gensio_unix_clear_fd_handlers(struct gensio_iod *iiod) { struct gensio_iod_unix *iod = i_to_sel(iiod); struct gensio_os_funcs *f = iiod->f; struct gensio_data *d = f->user_data; if (!iod->handlers_set) return; if (iod->type == GENSIO_IOD_FILE) { f->lock(iod->u.file.lock); if (!iod->u.file.do_clear) { iod->u.file.do_clear = true; f->run(iod->u.file.runner); } f->unlock(iod->u.file.lock); } else { sel_clear_fd_handlers(d->sel, iod->fd); } } static void gensio_unix_clear_fd_handlers_norpt(struct gensio_iod *iiod) { struct gensio_iod_unix *iod = i_to_sel(iiod); struct gensio_os_funcs *f = iiod->f; struct gensio_data *d = f->user_data; if (iod->handlers_set) { iod->handlers_set = false; if (iod->type != GENSIO_IOD_FILE) sel_clear_fd_handlers_norpt(d->sel, iod->fd); } } static void file_runner(struct gensio_runner *r, void *cb_data) { struct gensio_iod_unix *iod = cb_data; struct gensio_os_funcs *f = iod->r.f; f->lock(iod->u.file.lock); while (iod->u.file.read_enabled || iod->u.file.write_enabled) { if (iod->u.file.read_enabled) { f->unlock(iod->u.file.lock); iod->read_handler(&iod->r, iod->cb_data); f->lock(iod->u.file.lock); } if (iod->u.file.write_enabled) { f->unlock(iod->u.file.lock); iod->write_handler(&iod->r, iod->cb_data); f->lock(iod->u.file.lock); } } iod->u.file.in_handler = false; if (iod->u.file.do_clear) { iod->u.file.do_clear = false; iod->handlers_set = false; f->unlock(iod->u.file.lock); iod->cleared_handler(&iod->r, iod->cb_data); } else { f->unlock(iod->u.file.lock); } } static void gensio_unix_set_read_handler(struct gensio_iod *iiod, bool enable) { struct gensio_iod_unix *iod = i_to_sel(iiod); struct gensio_os_funcs *f = iiod->f; struct gensio_data *d = f->user_data; int op; if (iod->type == GENSIO_IOD_FILE) { if (iod->u.file.read_enabled == enable || iod->u.file.do_clear) return; f->lock(iod->u.file.lock); iod->u.file.read_enabled = enable; if (enable && !iod->u.file.in_handler) { f->run(iod->u.file.runner); iod->u.file.in_handler = true; } f->unlock(iod->u.file.lock); return; } if (enable) op = SEL_FD_HANDLER_ENABLED; else op = SEL_FD_HANDLER_DISABLED; sel_set_fd_read_handler(d->sel, iod->fd, op); } static void gensio_unix_set_write_handler(struct gensio_iod *iiod, bool enable) { struct gensio_iod_unix *iod = i_to_sel(iiod); struct gensio_os_funcs *f = iiod->f; struct gensio_data *d = f->user_data; int op; if (iod->type == GENSIO_IOD_FILE) { if (iod->u.file.write_enabled == enable || iod->u.file.do_clear) return; f->lock(iod->u.file.lock); iod->u.file.write_enabled = enable; if (enable && !iod->u.file.in_handler) { f->run(iod->u.file.runner); iod->u.file.in_handler = true; } f->unlock(iod->u.file.lock); return; } if (enable) op = SEL_FD_HANDLER_ENABLED; else op = SEL_FD_HANDLER_DISABLED; sel_set_fd_write_handler(d->sel, iod->fd, op); } static void gensio_unix_set_except_handler(struct gensio_iod *iiod, bool enable) { struct gensio_iod_unix *iod = i_to_sel(iiod); struct gensio_os_funcs *f = iiod->f; struct gensio_data *d = f->user_data; int op; if (iod->type == GENSIO_IOD_FILE) return; if (enable) op = SEL_FD_HANDLER_ENABLED; else op = SEL_FD_HANDLER_DISABLED; sel_set_fd_except_handler(d->sel, iod->fd, op); } struct gensio_timer { struct gensio_os_funcs *f; void (*handler)(struct gensio_timer *t, void *cb_data); void *cb_data; sel_timer_t *sel_timer; lock_type lock; void (*done_handler)(struct gensio_timer *t, void *cb_data); void *done_cb_data; }; static void gensio_timeout_handler(struct selector_s *sel, struct sel_timer_s *sel_timer, void *cb_data) { struct gensio_timer *timer = cb_data; timer->handler(timer, timer->cb_data); } static struct gensio_timer * gensio_unix_alloc_timer(struct gensio_os_funcs *f, void (*handler)(struct gensio_timer *t, void *cb_data), void *cb_data) { struct gensio_data *d = f->user_data; struct gensio_timer *timer; int rv; timer = f->zalloc(f, sizeof(*timer)); if (!timer) return NULL; timer->f = f; timer->handler = handler; timer->cb_data = cb_data; if (init_mutex(d->flags, &timer->lock)) { f->free(f, timer); return NULL; } rv = sel_alloc_timer(d->sel, gensio_timeout_handler, timer, &timer->sel_timer); if (rv) { f->free(f, timer); return NULL; } return timer; } static void gensio_unix_free_timer(struct gensio_timer *timer) { sel_free_timer(timer->sel_timer); timer->f->free(timer->f, timer); } static int gensio_unix_start_timer(struct gensio_timer *timer, gensio_time *timeout) { struct timeval tv; int rv; sel_get_monotonic_time(&tv); add_to_timeval(&tv, timeout); rv = sel_start_timer(timer->sel_timer, &tv); return gensio_os_err_to_err(timer->f, rv); } static int gensio_unix_start_timer_abs(struct gensio_timer *timer, gensio_time *timeout) { int rv; struct timeval tv, *rtv; rtv = gensio_time_to_timeval(&tv, timeout); rv = sel_start_timer(timer->sel_timer, rtv); return gensio_os_err_to_err(timer->f, rv); } static int gensio_unix_stop_timer(struct gensio_timer *timer) { int rv; rv = sel_stop_timer(timer->sel_timer); return gensio_os_err_to_err(timer->f, rv); } static void gensio_stop_timer_done(struct selector_s *sel, struct sel_timer_s *sel_timer, void *cb_data) { struct gensio_timer *timer = cb_data; void (*done_handler)(struct gensio_timer *t, void *cb_data); void *done_cb_data; LOCK(&timer->lock); done_handler = timer->done_handler; done_cb_data = timer->done_cb_data; timer->done_handler = NULL; UNLOCK(&timer->lock); done_handler(timer, done_cb_data); } static int gensio_unix_stop_timer_with_done(struct gensio_timer *timer, void (*done_handler)(struct gensio_timer *t, void *cb_data), void *cb_data) { int rv; LOCK(&timer->lock); if (timer->done_handler) { UNLOCK(&timer->lock); return GE_INUSE; } rv = sel_stop_timer_with_done(timer->sel_timer, gensio_stop_timer_done, timer); if (!rv) { timer->done_handler = done_handler; timer->done_cb_data = cb_data; } UNLOCK(&timer->lock); return gensio_os_err_to_err(timer->f, rv); } struct gensio_runner { struct gensio_os_funcs *f; struct sel_runner_s *sel_runner; void (*handler)(struct gensio_runner *r, void *cb_data); void *cb_data; }; static struct gensio_runner * gensio_unix_alloc_runner(struct gensio_os_funcs *f, void (*handler)(struct gensio_runner *r, void *cb_data), void *cb_data) { struct gensio_data *d = f->user_data; struct gensio_runner *runner; int rv; runner = f->zalloc(f, sizeof(*runner)); if (!runner) return NULL; runner->f = f; runner->handler = handler; runner->cb_data = cb_data; rv = sel_alloc_runner(d->sel, &runner->sel_runner); if (rv) { f->free(f, runner); return NULL; } return runner; } static void gensio_unix_free_runner(struct gensio_runner *runner) { sel_free_runner(runner->sel_runner); runner->f->free(runner->f, runner); } static void gensio_runner_handler(sel_runner_t *sel_runner, void *cb_data) { struct gensio_runner *runner = cb_data; runner->handler(runner, runner->cb_data); } static int gensio_unix_run(struct gensio_runner *runner) { return sel_run(runner->sel_runner, gensio_runner_handler, runner); } struct gensio_waiter { struct gensio_os_funcs *f; struct waiter_s *sel_waiter; }; static struct gensio_waiter * gensio_unix_alloc_waiter(struct gensio_os_funcs *f) { struct gensio_data *d = f->user_data; struct gensio_waiter *waiter = f->zalloc(f, sizeof(*waiter)); if (!waiter) return NULL; waiter->f = f; waiter->sel_waiter = alloc_waiter(f, d->sel, d->wake_sig); if (!waiter->sel_waiter) { f->free(f, waiter); return NULL; } return waiter; } static void gensio_unix_free_waiter(struct gensio_waiter *waiter) { free_waiter(waiter->sel_waiter); waiter->f->free(waiter->f, waiter); } static int gensio_unix_wait_intr_sigmask(struct gensio_waiter *waiter, unsigned int count, gensio_time *timeout, struct gensio_os_proc_data *proc_data) { int err; sigset_t *wait_sigs = NULL; if (proc_data) wait_sigs = gensio_os_proc_unix_get_wait_sigset(proc_data); err = wait_for_waiter_timeout_intr_sigmask(waiter->sel_waiter, count, timeout, wait_sigs); if (proc_data) gensio_os_proc_check_handlers(proc_data); return gensio_os_err_to_err(waiter->f, err); } static int gensio_unix_wait(struct gensio_waiter *waiter, unsigned int count, gensio_time *timeout) { struct gensio_data *d = waiter->f->user_data; int err = GE_INTERRUPTED; while (err == GE_INTERRUPTED) err = gensio_unix_wait_intr_sigmask(waiter, count, timeout, d->pdata); return err; } static int gensio_unix_wait_intr(struct gensio_waiter *waiter, unsigned int count, gensio_time *timeout) { struct gensio_data *d = waiter->f->user_data; return gensio_unix_wait_intr_sigmask(waiter, count, timeout, d->pdata); } static void gensio_unix_wake(struct gensio_waiter *waiter) { wake_waiter(waiter->sel_waiter); } #ifdef USE_PTHREADS #include #include struct wait_data { pthread_t id; int wake_sig; }; static void wake_thread_send_sig(long thread_id, void *cb_data) { struct wait_data *w = cb_data; pthread_kill(w->id, w->wake_sig); } static int gensio_unix_service(struct gensio_os_funcs *f, gensio_time *timeout) { struct gensio_data *d = f->user_data; struct wait_data w; struct timeval tv, *rtv; int err; w.id = pthread_self(); w.wake_sig = d->wake_sig; rtv = gensio_time_to_timeval(&tv, timeout); err = sel_select_intr(d->sel, wake_thread_send_sig, (long) w.id, &w, rtv); if (err < 0) err = gensio_os_err_to_err(f, errno); else if (err == 0) err = GE_TIMEDOUT; else err = 0; timeval_to_gensio_time(timeout, rtv); return err; } #else static int gensio_unix_service(struct gensio_os_funcs *f, gensio_time *timeout) { struct gensio_data *d = f->user_data; struct timeval tv, *rtv; int err; rtv = gensio_time_to_timeval(&tv, timeout); err = sel_select_intr(d->sel, NULL, 0, NULL, rtv); if (err < 0) err = gensio_os_err_to_err(f, errno); else if (err == 0) err = GE_TIMEDOUT; else err = 0; timeval_to_gensio_time(timeout, rtv); return err; } #endif static int gensio_unix_get_wake_sig(struct gensio_os_funcs *f) { struct gensio_data *d = f->user_data; return d->wake_sig; } static lock_type defos_lock = LOCK_INITIALIZER; static struct gensio_os_funcs *defoshnd; static int defoshnd_wake_sig = -1; static bool proc_setup; static struct gensio_os_funcs * gensio_unix_get_funcs(struct gensio_os_funcs *f) { struct gensio_data *d = f->user_data; LOCK(&d->reflock); assert(d->refcount > 0); d->refcount++; UNLOCK(&d->reflock); return f; } static void gensio_unix_free_funcs(struct gensio_os_funcs *f) { struct gensio_data *d = f->user_data; LOCK(&defos_lock); LOCK(&d->reflock); assert(d->refcount > 0); if (d->refcount > 1) { d->refcount--; UNLOCK(&d->reflock); UNLOCK(&defos_lock); return; } UNLOCK(&d->reflock); if (f == defoshnd) defoshnd = NULL; UNLOCK(&defos_lock); gensio_stdsock_cleanup(f); gensio_memtrack_cleanup(d->mtrack); if (d->freesel) sel_free_selector(d->sel); free(f->user_data); free(f); } static void gensio_unix_get_monotonic_time(struct gensio_os_funcs *f, gensio_time *time) { struct timeval tv; sel_get_monotonic_time(&tv); timeval_to_gensio_time(time, &tv); } static int gensio_handle_fork(struct gensio_os_funcs *f) { struct gensio_data *d = f->user_data; return sel_setup_forked_process(d->sel); } static int gensio_unix_add_iod(struct gensio_os_funcs *o, enum gensio_iod_type type, intptr_t ofd, struct gensio_iod **riod, ...) { struct gensio_iod_unix *iod = NULL; bool closefd = false; int err = GE_NOMEM, fd = ofd, sfd = -1; if (type >= NR_GENSIO_IOD_TYPES) return GE_INVAL; if (type == GENSIO_IOD_CONSOLE) { if (fd == 0) fd = open("/dev/tty", O_RDONLY); else if (fd == 1) fd = open("/dev/tty", O_WRONLY); else return GE_INVAL; if (fd == -1) return gensio_os_err_to_err(o, errno); closefd = true; } else if (type == GENSIO_IOD_PTY) { err = gensio_unix_pty_alloc(o, &fd, &sfd); if (err) return err; closefd = true; } iod = o->zalloc(o, sizeof(*iod)); if (!iod) { err = GE_NOMEM; goto out_err; } iod->r.f = o; iod->fd = fd; iod->sfd = sfd; iod->orig_fd = ofd; if (type == GENSIO_IOD_STDIO) { struct stat statb; iod->is_stdio = true; err = fstat(fd, &statb); if (err == -1) { err = gensio_os_err_to_err(o, errno); goto out_err; } switch (statb.st_mode & S_IFMT) { case S_IFREG: type = GENSIO_IOD_FILE; break; case S_IFCHR: type = GENSIO_IOD_DEV; break; case S_IFIFO: type = GENSIO_IOD_PIPE; break; case S_IFSOCK: type = GENSIO_IOD_SOCKET; break; default: err = GE_INVAL; goto out_err; } } else if (type == GENSIO_IOD_PTY) { iod->u.pty.pid = -1; } iod->type = type; if (type == GENSIO_IOD_FILE) { iod->u.file.lock = o->alloc_lock(o); if (!iod->u.file.lock) goto out_err; iod->u.file.runner = o->alloc_runner(o, file_runner, iod); if (!iod->u.file.runner) { o->free_lock(iod->u.file.lock); goto out_err; } } *riod = &iod->r; return 0; out_err: if (iod) o->free(o, iod); else if (closefd) { close(fd); if (sfd != -1) close(sfd); } return err; } static void gensio_unix_release_iod(struct gensio_iod *iiod) { struct gensio_iod_unix *iod = i_to_sel(iiod); struct gensio_os_funcs *o = iod->r.f; assert(!iod->handlers_set); if (iod->type == GENSIO_IOD_FILE) { o->free_runner(iod->u.file.runner); o->free_lock(iod->u.file.lock); } if (iod->type == GENSIO_IOD_PTY) { if (iod->u.pty.argv) gensio_argv_free(o, iod->u.pty.argv); if (iod->u.pty.env) gensio_argv_free(o, iod->u.pty.env); if (iod->u.pty.start_dir) o->free(o, iod->u.pty.start_dir); } o->free(o, iod); } static int gensio_unix_iod_get_type(struct gensio_iod *iiod) { struct gensio_iod_unix *iod = i_to_sel(iiod); return iod->type; } static int gensio_unix_iod_get_fd(struct gensio_iod *iiod) { struct gensio_iod_unix *iod = i_to_sel(iiod); return iod->fd; } #define ERRHANDLE() \ do { \ int err = 0; \ if (rv < 0) { \ if (errno == EINTR) \ goto retry; \ if (errno == EWOULDBLOCK || errno == EAGAIN) \ rv = 0; /* Handle like a zero-byte write. */ \ else { \ err = errno; \ assert(err); \ } \ } else if (rv == 0) { \ err = EPIPE; \ } \ if (!err && rcount) \ *rcount = rv; \ if (err) \ rv = gensio_os_err_to_err(o, err); \ else \ rv = 0; \ } while(0) static int gensio_unix_write(struct gensio_iod *iiod, const struct gensio_sg *sg, gensiods sglen, gensiods *rcount) { struct gensio_iod_unix *iod = i_to_sel(iiod); struct gensio_os_funcs *o = iiod->f; ssize_t rv; if (do_errtrig()) return GE_NOMEM; if (sglen == 0) { if (rcount) *rcount = 0; return 0; } retry: rv = writev(iod->fd, (struct iovec *) sg, sglen); ERRHANDLE(); return rv; } static int gensio_unix_read(struct gensio_iod *iiod, void *buf, gensiods buflen, gensiods *rcount) { struct gensio_iod_unix *iod = i_to_sel(iiod); struct gensio_os_funcs *o = iiod->f; ssize_t rv; if (do_errtrig()) return GE_NOMEM; if (buflen == 0) { if (rcount) *rcount = 0; return 0; } retry: rv = read(iod->fd, buf, buflen); ERRHANDLE(); return rv; } static int gensio_unix_read_flags(struct gensio_iod *iiod, unsigned char *buf, unsigned char *flags, gensiods buflen, gensiods *rcount) { gensiods count; struct gensio_iod_unix *iod = i_to_sel(iiod); int rv; if (do_errtrig()) return GE_NOMEM; if (buflen == 0) { if (rcount) *rcount = 0; return 0; } if (iod->type == GENSIO_IOD_DEV) { rv = gensio_unix_termios_read_flags(iiod->f, buf, flags, buflen, rcount, iod->termios, iod->fd); } else { rv = gensio_unix_read(iiod, buf, buflen, &count); if (!rv) { memset(flags, 0, count); if (rcount) *rcount = count; } } return rv; } static int gensio_unix_close(struct gensio_iod **iodp) { struct gensio_iod *iiod = *iodp; struct gensio_iod_unix *iod = i_to_sel(iiod); struct gensio_os_funcs *o = iiod->f; int err = 0; /* Don't do errtrig on close, it can fail and not cause any issues. */ assert(iodp); assert(!iod->handlers_set); if (iod->type != GENSIO_IOD_FILE) gensio_unix_do_cleanup_nonblock(o, iod->fd, &iod->mode); if (iod->termios) gensio_unix_cleanup_termios(o, &iod->termios, iod->fd); if (iod->type == GENSIO_IOD_SOCKET) { err = o->close_socket(iiod, false, true); } else if (!iod->is_stdio && iod->fd != -1) { err = close(iod->fd); iod->fd = -1; #ifdef ENABLE_INTERNAL_TRACE /* Close should never fail, but don't crash in production builds. */ assert(err == 0); #endif } if (iod->sfd != -1) { close(iod->sfd); iod->sfd = -1; } o->release_iod(iiod); *iodp = NULL; if (err == -1) return gensio_os_err_to_err(o, errno); return 0; } static int gensio_unix_set_non_blocking(struct gensio_iod *iiod) { struct gensio_iod_unix *iod = i_to_sel(iiod); if (do_errtrig()) return GE_NOMEM; if (iod->type == GENSIO_IOD_FILE) return 0; return gensio_unix_do_nonblock(iiod->f, iod->fd, &iod->mode); } static int gensio_unix_bufcount(struct gensio_iod *iiod, int whichbuf, gensiods *rcount) { struct gensio_iod_unix *iod = i_to_sel(iiod); return gensio_unix_get_bufcount(iiod->f, iod->fd, whichbuf, rcount); } static bool gensio_unix_is_regfile(struct gensio_os_funcs *o, intptr_t fd) { int err; struct stat statb; err = fstat(fd, &statb); if (err == -1) return false; return (statb.st_mode & S_IFMT) == S_IFREG; } static void gensio_unix_flush(struct gensio_iod *iiod, int whichbuf) { struct gensio_iod_unix *iod = i_to_sel(iiod); gensio_unix_do_flush(iiod->f, iod->fd, whichbuf); } static int gensio_unix_makeraw(struct gensio_iod *iiod) { struct gensio_iod_unix *iod = i_to_sel(iiod); if (iod->type == GENSIO_IOD_DEV || iod->type == GENSIO_IOD_PTY || (iod->type == GENSIO_IOD_CONSOLE && iod->orig_fd == 0)) /* Only set this for stdin or other files. */ return gensio_unix_setup_termios(iiod->f, iod->fd, &iod->termios); return 0; } static int gensio_unix_open_dev(struct gensio_os_funcs *o, const char *name, int options, struct gensio_iod **riod) { int flags, fd, err; flags = O_NONBLOCK | O_NOCTTY; if (options & (GENSIO_OPEN_OPTION_READABLE | GENSIO_OPEN_OPTION_WRITEABLE)) flags |= O_RDWR; else if (options & GENSIO_OPEN_OPTION_READABLE) flags |= O_RDONLY; else if (options & GENSIO_OPEN_OPTION_WRITEABLE) flags |= O_WRONLY; fd = open(name, flags); if (fd == -1) return gensio_os_err_to_err(o, errno); err = o->add_iod(o, GENSIO_IOD_DEV, fd, riod); if (err) close(fd); return err; } static int gensio_unix_exec_subprog(struct gensio_os_funcs *o, const char *argv[], const char **env, const char *start_dir, unsigned int flags, intptr_t *rpid, struct gensio_iod **rstdin, struct gensio_iod **rstdout, struct gensio_iod **rstderr) { int err; int infd = -1, outfd = -1, errfd = -1; struct gensio_iod *stdiniod = NULL, *stdoutiod = NULL, *stderriod = NULL; int pid = -1; err = gensio_unix_do_exec(o, argv, env, start_dir, flags, &pid, &infd, &outfd, rstderr ? &errfd : NULL); if (err) return err; err = o->add_iod(o, GENSIO_IOD_PIPE, infd, &stdiniod); if (err) goto out_err; infd = -1; err = o->add_iod(o, GENSIO_IOD_PIPE, outfd, &stdoutiod); if (err) goto out_err; outfd = -1; err = o->set_non_blocking(stdiniod); if (err) goto out_err; err = o->set_non_blocking(stdoutiod); if (err) goto out_err; if (rstderr) { err = o->add_iod(o, GENSIO_IOD_PIPE, errfd, &stderriod); if (err) goto out_err; errfd = -1; err = o->set_non_blocking(stderriod); if (err) goto out_err; } *rpid = pid; *rstdin = stdiniod; *rstdout = stdoutiod; if (rstderr) *rstderr = stderriod; return 0; out_err: if (stderriod) o->close(&stderriod); else if (errfd != -1) close(errfd); if (stdiniod) o->close(&stdiniod); else if (infd != -1) close(infd); if (stdoutiod) o->close(&stdoutiod); else if (outfd != -1) close(outfd); return err; } static int gensio_unix_pty_control(struct gensio_iod_unix *iod, int op, bool get, intptr_t val) { struct gensio_os_funcs *o = iod->r.f; int err = 0; const char **nargv; if (get) { if (op == GENSIO_IOD_CONTROL_PID) { if (iod->u.pty.pid == -1) return GE_NOTREADY; *((intptr_t *) val) = iod->u.pty.pid; return 0; } return GE_NOTSUP; } switch (op) { case GENSIO_IOD_CONTROL_ARGV: err = gensio_argv_copy(o, (const char **) val, NULL, &nargv); if (err) return err; if (iod->u.pty.argv) gensio_argv_free(o, iod->u.pty.argv); iod->u.pty.argv = nargv; return 0; case GENSIO_IOD_CONTROL_ENV: err = gensio_argv_copy(o, (const char **) val, NULL, &nargv); if (err) return err; if (iod->u.pty.env) gensio_argv_free(o, iod->u.pty.env); iod->u.pty.env = nargv; return 0; case GENSIO_IOD_CONTROL_START: return gensio_unix_pty_start(o, iod->fd, &iod->sfd, iod->u.pty.argv, iod->u.pty.env, iod->u.pty.start_dir, &iod->u.pty.pid); case GENSIO_IOD_CONTROL_STOP: if (iod->fd != -1) { close(iod->fd); iod->fd = -1; } return 0; case GENSIO_IOD_CONTROL_WIN_SIZE: { struct winsize win; struct gensio_winsize *gwin = (struct gensio_winsize *) val; win.ws_row = gwin->ws_row; win.ws_col = gwin->ws_col; win.ws_xpixel = gwin->ws_xpixel; win.ws_ypixel = gwin->ws_ypixel; if (ioctl(iod->fd, TIOCSWINSZ, &win) == -1) err = gensio_os_err_to_err(o, errno); return err; } case GENSIO_IOD_CONTROL_START_DIR: { char *dir = (char *) val; if (dir) { dir = gensio_strdup(o, dir); if (!dir) return GE_NOMEM; } if (iod->u.pty.start_dir) o->free(o, iod->u.pty.start_dir); iod->u.pty.start_dir = dir; return 0; } default: return GE_NOTSUP; } } static int gensio_unix_iod_control(struct gensio_iod *iiod, int op, bool get, intptr_t val) { struct gensio_iod_unix *iod = i_to_sel(iiod); if (iod->type == GENSIO_IOD_SOCKET) { if (op != GENSIO_IOD_CONTROL_SOCKINFO) return GE_NOTSUP; if (get) *((void **) val) = iod->u.socket.sockinfo; else iod->u.socket.sockinfo = (void *) val; return 0; } if (iod->type == GENSIO_IOD_PTY) return gensio_unix_pty_control(iod, op, get, val); if (iod->type != GENSIO_IOD_DEV) return GE_NOTSUP; return gensio_unix_termios_control(iiod->f, op, get, val, &iod->termios, iod->fd); } static int gensio_unix_kill_subprog(struct gensio_os_funcs *o, intptr_t pid, bool force) { int rv; rv = kill(pid, force ? SIGKILL : SIGTERM); if (rv < 0) return gensio_os_err_to_err(o, errno); return 0; } static int gensio_unix_wait_subprog(struct gensio_os_funcs *o, intptr_t pid, int *retcode) { pid_t rv; rv = waitpid(pid, retcode, WNOHANG); if (rv < 0) return gensio_os_err_to_err(o, errno); if (rv == 0) return GE_INPROGRESS; return 0; } static int gensio_unix_get_random(struct gensio_os_funcs *o, void *data, unsigned int len) { int fd; int rv; if (do_errtrig()) return GE_NOMEM; fd = open("/dev/urandom", O_RDONLY); if (fd == -1) return gensio_os_err_to_err(o, errno); while (len > 0) { rv = read(fd, data, len); if (rv < 0) { rv = errno; goto out; } len -= rv; data += rv; } rv = 0; out: close(fd); return gensio_os_err_to_err(o, rv); } static int gensio_unix_control(struct gensio_os_funcs *o, int func, void *data, gensiods *datalen) { struct gensio_data *d = o->user_data; switch (func) { case GENSIO_CONTROL_SET_PROC_DATA: d->pdata = data; return 0; default: return GE_NOTSUP; } } static struct gensio_os_funcs * gensio_unix_alloc_sel(struct selector_s *sel, int wake_sig, unsigned int flags) { struct gensio_data *d; struct gensio_os_funcs *o; o = malloc(sizeof(*o)); if (!o) return NULL; memset(o, 0, sizeof(*o)); d = malloc(sizeof(*d)); if (!d) { free(o); return NULL; } memset(d, 0, sizeof(*d)); d->flags = flags; if (init_mutex(d->flags, &d->reflock)) { free(d); free(o); return NULL; } d->refcount = 1; o->user_data = d; d->sel = sel; d->wake_sig = wake_sig; d->mtrack = gensio_memtrack_alloc(); o->zalloc = gensio_unix_zalloc; o->free = gensio_unix_free; o->alloc_lock = gensio_unix_alloc_lock; o->free_lock = gensio_unix_free_lock; o->lock = gensio_unix_lock; o->unlock = gensio_unix_unlock; o->set_fd_handlers = gensio_unix_set_fd_handlers; o->clear_fd_handlers = gensio_unix_clear_fd_handlers; o->clear_fd_handlers_norpt = gensio_unix_clear_fd_handlers_norpt; o->set_read_handler = gensio_unix_set_read_handler; o->set_write_handler = gensio_unix_set_write_handler; o->set_except_handler = gensio_unix_set_except_handler; o->alloc_timer = gensio_unix_alloc_timer; o->free_timer = gensio_unix_free_timer; o->start_timer = gensio_unix_start_timer; o->start_timer_abs = gensio_unix_start_timer_abs; o->stop_timer = gensio_unix_stop_timer; o->stop_timer_with_done = gensio_unix_stop_timer_with_done; o->alloc_runner = gensio_unix_alloc_runner; o->free_runner = gensio_unix_free_runner; o->run = gensio_unix_run; o->alloc_waiter = gensio_unix_alloc_waiter; o->free_waiter = gensio_unix_free_waiter; o->wait = gensio_unix_wait; o->wait_intr = gensio_unix_wait_intr; o->wait_intr_sigmask = gensio_unix_wait_intr_sigmask; o->wake = gensio_unix_wake; o->service = gensio_unix_service; o->get_wake_sig = gensio_unix_get_wake_sig; o->get_funcs = gensio_unix_get_funcs; o->free_funcs = gensio_unix_free_funcs; o->call_once = gensio_call_once; o->get_monotonic_time = gensio_unix_get_monotonic_time; o->handle_fork = gensio_handle_fork; o->add_iod = gensio_unix_add_iod; o->release_iod = gensio_unix_release_iod; o->iod_get_type = gensio_unix_iod_get_type; o->iod_get_fd = gensio_unix_iod_get_fd; o->set_non_blocking = gensio_unix_set_non_blocking; o->close = gensio_unix_close; o->graceful_close = gensio_unix_close; o->write = gensio_unix_write; o->read = gensio_unix_read; o->is_regfile = gensio_unix_is_regfile; o->bufcount = gensio_unix_bufcount; o->flush = gensio_unix_flush; o->makeraw = gensio_unix_makeraw; o->open_dev = gensio_unix_open_dev; o->exec_subprog = gensio_unix_exec_subprog; o->kill_subprog = gensio_unix_kill_subprog; o->wait_subprog = gensio_unix_wait_subprog; o->get_random = gensio_unix_get_random; o->iod_control = gensio_unix_iod_control; o->control = gensio_unix_control; o->read_flags = gensio_unix_read_flags; gensio_addr_addrinfo_set_os_funcs(o); if (gensio_stdsock_set_os_funcs(o)) { free(d); free(o); return NULL; } return o; } struct gensio_os_proc_data { struct gensio_os_funcs *o; int wake_sig; sigset_t old_sigs; /* Original signal mask. */ sigset_t wait_sigs; /* Signal mask to use when waiting. */ sigset_t check_sigs; /* Signals we are checking for. */ #define MAX_HANDLE_SIGS 10 int handle_sigs[MAX_HANDLE_SIGS]; unsigned int num_handle_sigs; struct sigaction old_wakesig; struct sigaction old_sigchld; bool got_sigchld; lock_type handler_lock; bool term_sig_set; bool got_term_sig; struct sigaction old_sigint; struct sigaction old_sigquit; struct sigaction old_sigterm; void (*term_handler)(void *handler_data); void *term_handler_data; bool reload_sig_set; bool got_reload_sig; struct sigaction old_sighup; void (*reload_handler)(void *handler_data); void *reload_handler_data; #if HAVE_DECL_SIGWINCH bool winch_sig_set; bool got_winch_sig; struct sigaction old_sigwinch; void (*winch_handler)(int x_chrs, int y_chrs, int x_bits, int y_bits, void *handler_data); void *winch_handler_data; int winch_fd; #endif struct gensio_os_cleanup_handler *cleanup_handlers; }; /* We only have one of these per process, so it's global. */ static struct gensio_os_proc_data proc_data; static void handle_sigchld(int sig) { proc_data.got_sigchld = true; } static void handle_wakesig(int sig) { } static void term_sig_handler(int sig) { proc_data.got_term_sig = true; } static void reload_sig_handler(int sig) { proc_data.got_reload_sig = true; } #if HAVE_DECL_SIGWINCH static void winch_sig_handler(int sig) { proc_data.got_winch_sig = true; } #endif int gensio_os_thread_setup(struct gensio_os_funcs *o) { int rv = 0; #ifdef USE_PTHREADS sigset_t sigs, old_sigs; int wake_sig = o->get_wake_sig(o); struct sigaction sigdo; sigemptyset(&sigs); if (wake_sig) sigaddset(&sigs, wake_sig); sigaddset(&sigs, SIGCHLD); /* Ignore SIGCHLD in normal operation. */ sigaddset(&sigs, SIGPIPE); /* Ignore broken pipes. */ #if HAVE_DECL_SIGWINCH /* * SIGWINCH is set here, not in the register_winsize_handler call, because * we can't modify the signal set after initial startup. */ sigaddset(&sigs, SIGWINCH); #endif rv = pthread_sigmask(SIG_BLOCK, &sigs, &old_sigs); if (rv) { rv = gensio_os_err_to_err(o, errno); goto out; } if (wake_sig) { memset(&sigdo, 0, sizeof(sigdo)); sigdo.sa_handler = handle_wakesig; sigdo.sa_flags = 0; rv = sigaction(wake_sig, &sigdo, NULL); if (rv) { rv = gensio_os_err_to_err(o, errno); pthread_sigmask(SIG_SETMASK, &old_sigs, NULL); goto out; } } out: #endif return rv; } static void gensio_os_proc_handle_sig(int sig, void *sdata) { struct gensio_os_proc_data *data = sdata; switch(sig) { case SIGCHLD: data->got_sigchld = true; break; case SIGQUIT: case SIGTERM: case SIGINT: data->got_term_sig = true; break; case SIGHUP: data->got_reload_sig = true; break; #if HAVE_DECL_SIGWINCH case SIGWINCH: data->got_winch_sig = true; break; #endif default: assert(0); } } int gensio_os_proc_setup(struct gensio_os_funcs *o, struct gensio_os_proc_data **rdata) { struct gensio_os_proc_data *data; sigset_t sigs; struct sigaction sigdo; int rv = GE_INUSE; LOCK(&defos_lock); if (proc_setup) goto out; data = &proc_data; data->o = o; if (o->get_wake_sig) data->wake_sig = o->get_wake_sig(o); sigemptyset(&sigs); sigemptyset(&data->check_sigs); if (data->wake_sig) sigaddset(&sigs, data->wake_sig); sigaddset(&sigs, SIGCHLD); /* Ignore SIGCHLD in normal operation. */ sigaddset(&sigs, SIGPIPE); /* Ignore broken pipes. */ #if HAVE_DECL_SIGWINCH /* * SIGWINCH is set here, not in the register_winsize_handler call, because * we can't modify the signal set after initial startup. */ sigaddset(&sigs, SIGWINCH); #endif rv = sigprocmask(SIG_BLOCK, &sigs, &data->old_sigs); if (rv) { rv = gensio_os_err_to_err(o, errno); goto out; } data->wait_sigs = data->old_sigs; if (data->wake_sig) sigdelset(&data->wait_sigs, data->wake_sig); sigdelset(&data->wait_sigs, SIGCHLD); /* Allow SIGCHLD while waiting. */ sigaddset(&data->check_sigs, SIGCHLD); sigaddset(&data->wait_sigs, SIGPIPE); /* No SIGPIPE ever. */ #if HAVE_DECL_SIGWINCH sigdelset(&data->wait_sigs, SIGWINCH); /* See note above on SIGWINCH */ #endif memset(&sigdo, 0, sizeof(sigdo)); sigdo.sa_handler = handle_sigchld; sigdo.sa_flags = SA_NOCLDSTOP; rv = sigaction(SIGCHLD, &sigdo, &data->old_sigchld); if (rv) { rv = gensio_os_err_to_err(o, errno); sigprocmask(SIG_SETMASK, &data->old_sigs, NULL); goto out; } if (data->wake_sig) { sigdo.sa_handler = handle_wakesig; sigdo.sa_flags = 0; rv = sigaction(data->wake_sig, &sigdo, &data->old_wakesig); if (rv) { rv = gensio_os_err_to_err(o, errno); sigaction(SIGCHLD, &data->old_sigchld, NULL); sigprocmask(SIG_SETMASK, &data->old_sigs, NULL); goto out; } } rv = data->o->control(o, GENSIO_CONTROL_SET_PROC_DATA, data, NULL); if (rv) { sigaction(SIGCHLD, &data->old_sigchld, NULL); sigprocmask(SIG_SETMASK, &data->old_sigs, NULL); if (data->wake_sig) sigaction(data->wake_sig, &data->old_wakesig, NULL); goto out; } LOCK_INIT(&data->handler_lock); data->handle_sigs[data->num_handle_sigs++] = SIGCHLD; sel_set_handle_sig(data->handle_sigs, gensio_os_proc_handle_sig, data); *rdata = data; proc_setup = true; out: UNLOCK(&defos_lock); return rv; } void gensio_register_os_cleanup_handler(struct gensio_os_funcs *o, struct gensio_os_cleanup_handler *h) { struct gensio_data *d = o->user_data; struct gensio_os_proc_data *data = d->pdata; LOCK(&data->handler_lock); h->next = data->cleanup_handlers; data->cleanup_handlers = h; UNLOCK(&data->handler_lock); } static int check_for_sigpending(sigset_t *check_for) { #ifdef HAVE_SIGTIMEDWAIT static struct timespec zerotime = { 0, 0 }; int rv; retry: rv = sigtimedwait(check_for, NULL, &zerotime); if (rv < 0) { if (errno == EINTR) goto retry; if (errno == EAGAIN) return 0; assert(0); } return rv; #else return 0; #endif #if 0 /* * The below code doesn't work, it can race with a signal handler * and lock up. This is only an issue on MacOS, whose lack of * sigtimedwait is ridiculous. You might be able to do this with * kevent, but that would be expensive. Maybe it's not necessary * on MacOS, maybe pselect will handle signals on all calls, even * if there's no wait. */ #ifdef NSIG /* Nothing to do */ #elif defined(_NSIG) #define NSIG _NSIG #elif defined(SIGRTMAX) #define NSIG SIGRTMAX #else #define NSIG 64 #endif int rsig = 0, sig; sigset_t pending; sigpending(&pending); for (sig = 0; sig < NSIG; sig++) { if (sigismember(&pending, sig) && sigismember(check_for, sig)) { rsig = sig; sigwait(check_for, &sig); break; } } return rsig; #endif } void gensio_os_proc_cleanup(struct gensio_os_proc_data *data) { LOCK(&defos_lock); if (!proc_setup) goto out; proc_setup = false; /* We should be single-threaded here. */ while (data->cleanup_handlers) { struct gensio_os_cleanup_handler *h = data->cleanup_handlers; data->cleanup_handlers = h->next; h->cleanup(h); } LOCK_DESTROY(&data->handler_lock); if (data->wake_sig) sigaction(data->wake_sig, &data->old_wakesig, NULL); if (data->term_sig_set) { data->term_sig_set = false; sigaction(SIGINT, &data->old_sigint, NULL); sigaction(SIGQUIT, &data->old_sigquit, NULL); sigaction(SIGTERM, &data->old_sigterm, NULL); } if (data->reload_sig_set) { data->reload_sig_set = false; sigaction(SIGHUP, &data->old_sighup, NULL); } #if HAVE_DECL_SIGWINCH if (data->winch_sig_set) { data->winch_sig_set = false; sigaction(SIGWINCH, &data->old_sigwinch, NULL); } #endif sigaction(SIGCHLD, &data->old_sigchld, NULL); /* Clear out any pending signals before we restore the mask. */ while (check_for_sigpending(&data->check_sigs) > 0) ; sigprocmask(SIG_SETMASK, &data->old_sigs, NULL); out: UNLOCK(&defos_lock); return; } void gensio_os_proc_check_handlers(struct gensio_os_proc_data *data) { int sig; LOCK(&data->handler_lock); /* * Poll implementations (at least epoll) will not necessarily * check for signals if they return immediately. So to avoid * missing a signal on a really busy system, check for signals * here. */ while ((sig = check_for_sigpending(&data->check_sigs)) > 0) gensio_os_proc_handle_sig(sig, data); if (data->got_term_sig) { data->got_term_sig = false; data->term_handler(data->term_handler_data); } if (data->got_reload_sig) { data->got_reload_sig = false; data->reload_handler(data->reload_handler_data); } #if HAVE_DECL_SIGWINCH if (data->got_winch_sig) { struct winsize win; int err; data->got_winch_sig = false; err = ioctl(data->winch_fd, TIOCGWINSZ, &win); if (err == 0) data->winch_handler(win.ws_col, win.ws_row, win.ws_xpixel, win.ws_ypixel, data->winch_handler_data); } #endif UNLOCK(&data->handler_lock); } int gensio_os_proc_register_term_handler(struct gensio_os_proc_data *data, void (*handler)(void *handler_data), void *handler_data) { int err; struct sigaction act; sigset_t sigs, old_sigs; if (data->term_sig_set) { data->term_sig_set = false; sigaction(SIGINT, &data->old_sigint, NULL); sigaction(SIGQUIT, &data->old_sigquit, NULL); sigaction(SIGTERM, &data->old_sigterm, NULL); } if (!handler) return 0; sigemptyset(&sigs); sigaddset(&sigs, SIGINT); sigaddset(&sigs, SIGQUIT); sigaddset(&sigs, SIGTERM); err = sigprocmask(SIG_BLOCK, &sigs, &old_sigs); if (err) return gensio_os_err_to_err(data->o, errno); data->term_handler = handler; data->term_handler_data = handler_data; memset(&act, 0, sizeof(act)); act.sa_handler = term_sig_handler; act.sa_flags |= SA_RESETHAND; err = sigaction(SIGINT, &act, &data->old_sigint); if (err) { err = errno; goto out_err; } err = sigaction(SIGQUIT, &act, &data->old_sigquit); if (err) { err = errno; sigaction(SIGINT, &data->old_sigint, NULL); goto out_err; } err = sigaction(SIGTERM, &act, &data->old_sigterm); if (err) { err = errno; sigaction(SIGINT, &data->old_sigint, NULL); sigaction(SIGQUIT, &data->old_sigquit, NULL); goto out_err; } data->handle_sigs[data->num_handle_sigs++] = SIGINT; data->handle_sigs[data->num_handle_sigs++] = SIGQUIT; data->handle_sigs[data->num_handle_sigs++] = SIGTERM; sigdelset(&data->wait_sigs, SIGINT); sigdelset(&data->wait_sigs, SIGQUIT); sigdelset(&data->wait_sigs, SIGTERM); sigaddset(&data->check_sigs, SIGINT); sigaddset(&data->check_sigs, SIGQUIT); sigaddset(&data->check_sigs, SIGTERM); data->term_sig_set = true; return 0; out_err: sigprocmask(SIG_SETMASK, &old_sigs, NULL); return gensio_os_err_to_err(data->o, err); } int gensio_os_proc_register_reload_handler(struct gensio_os_proc_data *data, void (*handler)(void *handler_data), void *handler_data) { int err; struct sigaction act; sigset_t sigs, old_sigs; if (data->reload_sig_set) { data->reload_sig_set = false; sigaction(SIGHUP, &data->old_sighup, NULL); } if (!handler) return 0; sigemptyset(&sigs); sigaddset(&sigs, SIGHUP); err = sigprocmask(SIG_BLOCK, &sigs, &old_sigs); if (err) return gensio_os_err_to_err(data->o, errno); data->reload_handler = handler; data->reload_handler_data = handler_data; memset(&act, 0, sizeof(act)); act.sa_handler = reload_sig_handler; err = sigaction(SIGHUP, &act, &data->old_sighup); if (err) { err = errno; goto out_err; } data->handle_sigs[data->num_handle_sigs++] = SIGHUP; sigdelset(&data->wait_sigs, SIGHUP); sigaddset(&data->check_sigs, SIGHUP); data->reload_sig_set = true; return 0; out_err: sigprocmask(SIG_SETMASK, &old_sigs, NULL); return gensio_os_err_to_err(data->o, err); } int gensio_os_proc_register_winsize_handler(struct gensio_os_proc_data *data, struct gensio_iod *console_iod, void (*handler)(int x_chrs, int y_chrs, int x_bits, int y_bits, void *handler_data), void *handler_data) { #if HAVE_DECL_SIGWINCH struct gensio_iod_unix *iod = i_to_sel(console_iod); int err = 0; struct sigaction act; struct winsize win; LOCK(&data->handler_lock); if (data->winch_sig_set) { data->winch_sig_set = false; sigaction(SIGWINCH, &data->old_sigwinch, NULL); } if (!handler) { data->got_winch_sig = false; goto out_unlock; } err = ioctl(iod->fd, TIOCGWINSZ, &win); if (err == -1) { err = GE_NOTSUP; goto out_unlock; } data->winch_handler = handler; data->winch_handler_data = handler_data; data->winch_fd = iod->fd; memset(&act, 0, sizeof(act)); act.sa_handler = winch_sig_handler; err = sigaction(SIGWINCH, &act, &data->old_sigwinch); if (err) { err = gensio_os_err_to_err(data->o, errno); goto out_unlock; } data->handle_sigs[data->num_handle_sigs++] = SIGWINCH; sigdelset(&data->wait_sigs, SIGWINCH); data->winch_sig_set = true; /* * For at least MacOS, using kill() to self doesn't seem to work * properly. pthread_kill() seems to work ok. */ #ifdef USE_PTHREADS pthread_kill(pthread_self(), SIGWINCH); #else kill(getpid(), SIGWINCH); #endif out_unlock: UNLOCK(&data->handler_lock); return err; #else return GE_NOTSUP; #endif } sigset_t * gensio_os_proc_unix_get_wait_sigset(struct gensio_os_proc_data *data) { return &data->wait_sigs; } struct gensio_thread { struct gensio_os_funcs *o; #ifdef USE_PTHREADS pthread_t id; #endif void (*start_func)(void *data); void *data; }; static void * gensio_os_thread_func(void *info) { struct gensio_thread *tid = info; tid->start_func(tid->data); return NULL; } int gensio_os_new_thread(struct gensio_os_funcs *o, void (*start_func)(void *data), void *data, struct gensio_thread **thread_id) { #ifdef USE_PTHREADS struct gensio_thread *tid; int rv; tid = o->zalloc(o, sizeof(*tid)); if (!tid) return GE_NOMEM; tid->o = o; tid->start_func = start_func; tid->data = data; rv = pthread_create(&tid->id, NULL, gensio_os_thread_func, tid); if (rv) { o->free(o, tid); return gensio_os_err_to_err(o, rv); } *thread_id = tid; return 0; #else return GE_NOTSUP; #endif } int gensio_os_wait_thread(struct gensio_thread *tid) { #ifdef USE_PTHREADS int rv; rv = pthread_join(tid->id, NULL); if (rv) return gensio_os_err_to_err(tid->o, rv); tid->o->free(tid->o, tid); return 0; #else return GE_NOTSUP; #endif } int gensio_i_os_err_to_err(struct gensio_os_funcs *o, int oserr, const char *caller, const char *file, unsigned int lineno) { int err; if (oserr == 0) return 0; switch(oserr) { case ENOMEM: err = GE_NOMEM; break; case EINVAL: err = GE_INVAL; break; case ENOENT: err = GE_NOTFOUND; break; case EEXIST: err = GE_EXISTS; break; case EBUSY: err = GE_INUSE; break; case EAGAIN: err = GE_INPROGRESS; break; #if EAGAIN != EINPROGRESS case EINPROGRESS: err = GE_INPROGRESS; break; #endif case ETIMEDOUT: err = GE_TIMEDOUT; break; case EPIPE: err = GE_REMCLOSE; break; case ECONNRESET: err = GE_REMCLOSE; break; case EHOSTUNREACH: err = GE_HOSTDOWN; break; case ECONNREFUSED: err = GE_CONNREFUSE; break; case EIO: err = GE_IOERR; break; case EADDRINUSE: err = GE_ADDRINUSE; break; case EINTR: err = GE_INTERRUPTED; break; case ESHUTDOWN: err = GE_SHUTDOWN; break; case EMSGSIZE: err = GE_TOOBIG; break; case EPERM: err = GE_PERM; break; case EACCES: err = GE_PERM; break; default: err = GE_OSERR; } if (err == GE_OSERR) { gensio_log(o, GENSIO_LOG_INFO, "Unhandled OS error in %s:%d: %s (%d)", caller, lineno, strerror(oserr), oserr); } return err; } #ifdef USE_PTHREADS struct sel_lock_s { lock_type lock; }; static sel_lock_t * defsel_lock_alloc(void *cb_data) { sel_lock_t *l; unsigned int flags = (intptr_t) cb_data; l = malloc(sizeof(*l)); if (!l) return NULL; init_mutex(flags, &l->lock); return l; } static void defsel_lock_free(sel_lock_t *l) { LOCK_DESTROY(&l->lock); free(l); } static void defsel_lock(sel_lock_t *l) { LOCK(&l->lock); } static void defsel_unlock(sel_lock_t *l) { UNLOCK(&l->lock); } #endif static int i_gensio_unix_funcs_alloc(struct selector_s *sel, int wake_sig, unsigned int flags, struct gensio_os_funcs **ro) { struct gensio_os_funcs *o; bool freesel = false; int rv; if (flags & ~GENSIO_OS_FUNCS_FLAG_PRIO_INHERIT) return GE_NOTSUP; #ifndef USE_PTHREADS if (flags & GENSIO_OS_FUNCS_FLAG_PRIO_INHERIT) return GE_NOTSUP; #endif if (!sel) { #ifdef USE_PTHREADS rv = sel_alloc_selector_thread(&sel, wake_sig, defsel_lock_alloc, defsel_lock_free, defsel_lock, defsel_unlock, (void *) (intptr_t) flags); #else rv = sel_alloc_selector_nothread(&sel); #endif if (rv) return GE_NOMEM; freesel = true; } o = gensio_unix_alloc_sel(sel, wake_sig, flags); if (o) { struct gensio_data *d = o->user_data; d->freesel = freesel; } else if (freesel) { sel_free_selector(sel); } *ro = o; return 0; } int gensio_unix_funcs_alloc(struct selector_s *sel, int wake_sig, struct gensio_os_funcs **ro) { return i_gensio_unix_funcs_alloc(sel, wake_sig, 0, ro); } struct gensio_os_funcs * gensio_selector_alloc(struct selector_s *sel, int wake_sig) { struct gensio_os_funcs *o = NULL; gensio_unix_funcs_alloc(sel, wake_sig, &o); return o; } static void defoshnd_init(void) { gensio_unix_funcs_alloc(NULL, defoshnd_wake_sig, &defoshnd); } int gensio_default_os_hnd(int wake_sig, struct gensio_os_funcs **o) { int err = 0; if (wake_sig == GENSIO_OS_FUNCS_DEFAULT_THREAD_SIGNAL) wake_sig = SIGUSR1; LOCK(&defos_lock); if (!defoshnd) { defoshnd_wake_sig = wake_sig; defoshnd_init(); if (!defoshnd) { defoshnd_wake_sig = -1; err = GE_NOMEM; } } else if (wake_sig != defoshnd_wake_sig) { err = GE_INVAL; } else { gensio_unix_get_funcs(defoshnd); } UNLOCK(&defos_lock); if (!err) *o = defoshnd; return err; } int gensio_valloc_os_funcs(int wake_sig, struct gensio_os_funcs **o, unsigned int flags, va_list ap) { if (wake_sig == GENSIO_OS_FUNCS_DEFAULT_THREAD_SIGNAL) wake_sig = SIGUSR1; if (flags) return GE_NOTSUP; return gensio_unix_funcs_alloc(NULL, wake_sig, o); } int gensio_alloc_os_funcs(int wake_sig, struct gensio_os_funcs **o, unsigned int flags, ...) { va_list ap; int rv; va_start(ap, flags); rv = gensio_valloc_os_funcs(wake_sig, o, flags, ap); va_end(ap); return rv; } void gensio_osfunc_exit(int rv) { errtrig_exit(rv); } gensio-3.0.0/lib/net_addrinfo.c0000664000175000017500000007055514747451760012062 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2019 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #define _GNU_SOURCE /* Get extended getaddrinfo errors. */ #include "config.h" #include #ifdef _WIN32 #include #include #include #include #else #include #include #include #include #include #include #include #endif #include #include #include #if HAVE_UNIX #include #endif #define SIZEOF_SOCKADDR_UN_HEADER \ (sizeof(struct sockaddr_un) - \ sizeof(((struct sockaddr_un *) 0)->sun_path)) #include #include #include #include #include #include /* For older systems that don't have this. */ #ifndef AI_V4MAPPED #define AI_V4MAPPED 0 #endif struct gensio_addr_addrinfo { struct gensio_addr r; struct gensio_os_funcs *o; struct addrinfo *a; struct addrinfo *curr; gensio_refcount *refcount; bool is_getaddrinfo; /* Allocated with getaddrinfo()? */ }; static struct gensio_addr_funcs addrinfo_funcs; static void gensio_addr_addrinfo_free(struct gensio_addr *addr); #define a_to_info(a) gensio_container_of(a, struct gensio_addr_addrinfo, r); struct addrinfo * gensio_addr_addrinfo_get(const struct gensio_addr *aaddr) { struct gensio_addr_addrinfo *addr = a_to_info(aaddr); return addr->a; } struct addrinfo * gensio_addr_addrinfo_get_curr(const struct gensio_addr *aaddr) { struct gensio_addr_addrinfo *addr = a_to_info(aaddr); return addr->curr; } void gensio_addr_addrinfo_set(struct gensio_addr *aaddr, struct addrinfo *ai) { struct gensio_addr_addrinfo *addr = a_to_info(aaddr); assert(addr->a == NULL); addr->a = ai; addr->curr = ai; } static struct gensio_addr_addrinfo * gensio_addrinfo_make(struct gensio_os_funcs *o, unsigned int size, bool is_recvfrom) { struct gensio_addr_addrinfo *addr = o->zalloc(o, sizeof(*addr)); struct addrinfo *ai = NULL, *nai; if (!addr) return NULL; if (!is_recvfrom) { addr->refcount = o->zalloc(o, sizeof(*addr->refcount)); if (!addr->refcount) goto out_err; if (gensio_refcount_init(o, addr->refcount, 1) != 0) { o->free(o, addr->refcount); addr->refcount = NULL; goto out_err; } } if (size > 0) { ai = o->zalloc(o, sizeof(*ai)); if (!ai) goto out_err; ai->ai_addr = o->zalloc(o, size); if (!ai->ai_addr) goto out_err; ai->ai_addrlen = size; } if (is_recvfrom && ai) { /* Tack on two more for room for ifindex and dest addr. */ unsigned int i; nai = ai; for (i = 0; i < 2; i++) { nai->ai_next = o->zalloc(o, sizeof(*ai)); if (!nai->ai_next) goto out_err; nai->ai_next->ai_addr = o->zalloc(o, size); if (!nai->ai_next->ai_addr) goto out_err; nai = nai->ai_next; } } addr->o = o; addr->r.funcs = &addrinfo_funcs; addr->a = ai; addr->curr = ai; return addr; out_err: if (addr->refcount) { gensio_refcount_cleanup(addr->refcount); o->free(o, addr->refcount); } while (ai) { nai = ai->ai_next; if (ai->ai_addr) o->free(o, ai->ai_addr); o->free(o, ai); ai = nai; } o->free(o, addr); return NULL; } struct gensio_addr * gensio_addr_addrinfo_make(struct gensio_os_funcs *o, unsigned int size, bool is_recvfrom) { struct gensio_addr_addrinfo *addr = gensio_addrinfo_make(o, size, is_recvfrom); if (addr) return &addr->r; else return NULL; } static int gensio_addr_addrinfo_create(struct gensio_os_funcs *o, int nettype, const void *iaddr, gensiods len, unsigned int port, struct gensio_addr **newaddr) { struct sockaddr_in s4 = { .sin_family = AF_INET }; #ifdef AF_INET6 struct sockaddr_in6 s6 = { .sin6_family = AF_INET6 }; #endif struct sockaddr_un su = { .sun_family = AF_UNIX }; struct sockaddr *s; unsigned int slen; struct gensio_addr_addrinfo *a; switch (nettype) { case GENSIO_NETTYPE_IPV4: if (len != sizeof(struct in_addr)) return GE_INVAL; s4.sin_port = htons(port); memcpy(&s4.sin_addr, iaddr, len); s = (struct sockaddr *) &s4; slen = sizeof(s4); break; case GENSIO_NETTYPE_IPV6: #ifdef AF_INET6 if (len == sizeof(struct in6_addr)) { memcpy(&s6.sin6_addr, iaddr, len); } else if (len == sizeof(s6)) { /* Full sockaddr_in6, so we can get scope. */ const struct sockaddr_in6 *is6 = iaddr; memcpy(&s6.sin6_addr, &is6->sin6_addr, sizeof(struct in6_addr)); s6.sin6_scope_id = is6->sin6_scope_id; } else { return GE_INVAL; } s6.sin6_port = htons(port); s = (struct sockaddr *) &s6; slen = sizeof(s6); break; #else return GE_NOTSUP; #endif case GENSIO_NETTYPE_UNIX: if (len > sizeof(su.sun_path) - 1) return GE_TOOBIG; memcpy(su.sun_path, iaddr, len); s = (struct sockaddr *) &su; slen = sizeof(su); break; default: return GE_INVAL; } a = gensio_addrinfo_make(o, slen, false); if (!a) return GE_NOMEM; a->a->ai_family = s->sa_family; memcpy(a->a->ai_addr, s, slen); *newaddr = &a->r; return 0; } int gensio_sockaddr_get_port(const struct sockaddr *s, unsigned int *port) { switch (s->sa_family) { case AF_INET: *port = ntohs(((struct sockaddr_in *) s)->sin_port); break; #ifdef AF_INET6 case AF_INET6: *port = ntohs(((struct sockaddr_in6 *) s)->sin6_port); break; #endif default: return GE_INVAL; } return 0; } int gensio_sockaddr_set_port(const struct sockaddr *s, unsigned int port) { switch (s->sa_family) { case AF_INET: ((struct sockaddr_in *) s)->sin_port = htons(port); break; #ifdef AF_INET6 case AF_INET6: ((struct sockaddr_in6 *) s)->sin6_port = htons(port); break; #endif default: return GE_INVAL; } return 0; } static int gensio_addr_addrinfo_get_port(const struct gensio_addr *aaddr) { struct gensio_addr_addrinfo *addr = a_to_info(aaddr); unsigned int port; int rv = gensio_sockaddr_get_port(addr->curr->ai_addr, &port); if (rv) return -1; return port; } static void gensio_addr_addrinfo_get_data(const struct gensio_addr *aaddr, void *oaddr, gensiods *olen) { struct gensio_addr_addrinfo *addr = a_to_info(aaddr); char dummy; void *data; gensiods len, ilen = *olen; switch (addr->curr->ai_addr->sa_family) { case AF_INET: { struct sockaddr_in *s4 = (struct sockaddr_in *) addr->curr->ai_addr; data = &s4->sin_addr; len = sizeof(s4->sin_addr); break; } case AF_INET6: { struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) addr->curr->ai_addr; data = &s6->sin6_addr; len = sizeof(s6->sin6_addr); break; } case AF_UNIX: { struct sockaddr_un *su = (struct sockaddr_un *) addr->curr->ai_addr; data = su->sun_path; len = strlen(data) + 1; break; } default: data = &dummy; len = 0; break; } *olen = len; if (len > ilen) len = ilen; memcpy(oaddr, data, len); } #ifdef AF_INET6 static bool sockaddr_inet6_inet4_equal(const struct sockaddr *a1, socklen_t l1, const struct sockaddr *a2, socklen_t l2, bool compare_ports) { struct sockaddr_in6 *s1 = (struct sockaddr_in6 *) a1; struct sockaddr_in *s2 = (struct sockaddr_in *) a2; /* a1 is an IF_NET6 address. */ if (a2->sa_family != AF_INET) return false; if (!IN6_IS_ADDR_V4MAPPED(&s1->sin6_addr)) return false; if (compare_ports && s1->sin6_port != s2->sin_port) return false; return ((const uint32_t *) &s1->sin6_addr)[3] == s2->sin_addr.s_addr; } #endif bool sockaddr_equal(const struct sockaddr *a1, socklen_t l1, const struct sockaddr *a2, socklen_t l2, bool compare_ports) { if (a1->sa_family != a2->sa_family) { #ifdef AF_INET6 if (a1->sa_family == AF_INET6) return sockaddr_inet6_inet4_equal(a1, l1, a2, l2, compare_ports); else if (a2->sa_family == AF_INET6) return sockaddr_inet6_inet4_equal(a2, l2, a1, l1, compare_ports); #endif return false; } if (l1 != l2) return false; switch (a1->sa_family) { case AF_INET: { struct sockaddr_in *s1 = (struct sockaddr_in *) a1; struct sockaddr_in *s2 = (struct sockaddr_in *) a2; if (compare_ports && s1->sin_port != s2->sin_port) return false; if (s1->sin_addr.s_addr != s2->sin_addr.s_addr) return false; } break; #ifdef AF_INET6 case AF_INET6: { struct sockaddr_in6 *s1 = (struct sockaddr_in6 *) a1; struct sockaddr_in6 *s2 = (struct sockaddr_in6 *) a2; if (compare_ports && s1->sin6_port != s2->sin6_port) return false; if (memcmp(s1->sin6_addr.s6_addr, s2->sin6_addr.s6_addr, sizeof(s1->sin6_addr.s6_addr)) != 0) return false; } break; #endif case AF_UNIX: { struct sockaddr_un *s1 = (struct sockaddr_un *) a1; struct sockaddr_un *s2 = (struct sockaddr_un *) a2; if (strncmp(s1->sun_path, s2->sun_path, sizeof(s1->sun_path)) != 0) return false; } break; default: /* Unknown family. */ return false; } return true; } static bool gensio_addr_addrinfo_equal(const struct gensio_addr *aa1, const struct gensio_addr *aa2, bool compare_ports, bool compare_all) { struct gensio_addr_addrinfo *a1 = a_to_info(aa1); struct gensio_addr_addrinfo *a2 = a_to_info(aa2); struct addrinfo *ai1, *ai2; if (compare_all) { ai1 = a1->a; ai2 = a2->a; } else { ai1 = a1->curr; ai2 = a2->curr; } while (ai1 && ai2) { if (!sockaddr_equal(ai1->ai_addr, ai1->ai_addrlen, ai2->ai_addr, ai2->ai_addrlen, compare_ports)) return false; if (!compare_all) return true; ai1 = ai1->ai_next; ai2 = ai2->ai_next; } if (ai1 != NULL || ai2 != NULL) return false; return true; } static int gensio_sockaddr_to_str(const struct sockaddr *addr, int flags, char *buf, gensiods *pos, gensiods buflen) { if (addr->sa_family == AF_INET) { struct sockaddr_in *a4 = (struct sockaddr_in *) addr; char ibuf[INET_ADDRSTRLEN]; gensio_pos_snprintf(buf, buflen, pos, "ipv4,%s,%d", inet_ntop(AF_INET, &a4->sin_addr, ibuf, sizeof(ibuf)), ntohs(a4->sin_port)); #ifdef AF_INET6 } else if (addr->sa_family == AF_INET6) { struct sockaddr_in6 *a6 = (struct sockaddr_in6 *) addr; char ibuf[INET6_ADDRSTRLEN]; char ifbuf[IF_NAMESIZE + 1]; if (IN6_IS_ADDR_LINKLOCAL(&a6->sin6_addr) && if_indextoname(a6->sin6_scope_id, &(ifbuf[1])) != NULL) ifbuf[0] = '%'; else ifbuf[0] = '\0'; gensio_pos_snprintf(buf, buflen, pos, "%s,%s%s,%d", flags & AI_V4MAPPED ? "ipv6n4" : "ipv6", inet_ntop(AF_INET6, &a6->sin6_addr, ibuf, sizeof(ibuf)), ifbuf, ntohs(a6->sin6_port)); #endif } else if (addr->sa_family == AF_UNIX) { struct sockaddr_un *au = (struct sockaddr_un *) addr; gensio_pos_snprintf(buf, buflen, pos, "unix,%s", au->sun_path); } else if (addr->sa_family == GENSIO_AF_IFINDEX) { struct sockaddr *as = (struct sockaddr *) addr; unsigned int *iptr = (unsigned int *) as->sa_data; gensio_pos_snprintf(buf, buflen, pos, "ifidx:%u", *iptr); } else { if (*pos < buflen) buf[*pos] = '\0'; return GE_INVAL; } return 0; } static int gensio_addr_addrinfo_to_str(const struct gensio_addr *aaddr, char *buf, gensiods *pos, gensiods buflen) { struct gensio_addr_addrinfo *addr = a_to_info(aaddr); gensiods tmppos = 0; if (!pos) pos = &tmppos; return gensio_sockaddr_to_str(addr->curr->ai_addr, addr->curr->ai_flags, buf, pos, buflen); } static int gensio_addr_addrinfo_to_str_all(const struct gensio_addr *aaddr, char *buf, gensiods *pos, gensiods buflen) { struct gensio_addr_addrinfo *addr = a_to_info(aaddr); struct gensio_addr_addrinfo a = *addr; bool first = true; int rv; gensiods tmppos = 0; if (!pos) pos = &tmppos; for (a.curr = a.a; a.curr; a.curr = a.curr->ai_next) { if (!first) /* Add the semicolons between the addresses. */ gensio_pos_snprintf(buf, buflen, pos, ";"); first = false; rv = gensio_addr_to_str(&a.r, buf, pos, buflen); if (rv) return rv; } return 0; } static int gensio_scan_unixaddr(struct gensio_os_funcs *o, int socktype, const char *str, struct gensio_addr **raddr) { struct sockaddr_un *saddr; struct gensio_addr *addr = NULL; struct addrinfo *ai; size_t len; len = strlen(str); if (len >= sizeof(saddr->sun_path) - 1) return GE_TOOBIG; addr = gensio_addr_addrinfo_make(o, SIZEOF_SOCKADDR_UN_HEADER + len + 1, false); if (!addr) return GE_NOMEM; ai = gensio_addr_addrinfo_get(addr); saddr = (struct sockaddr_un *) ai->ai_addr; saddr->sun_family = AF_UNIX; memcpy(saddr->sun_path, str, len); ai->ai_family = AF_UNIX; ai->ai_socktype = socktype; ai->ai_addrlen = SIZEOF_SOCKADDR_UN_HEADER + len + 1; ai->ai_addr = (struct sockaddr *) saddr; *raddr = addr; return 0; } #ifdef _MSC_VER /* On Windows, strtok is thread-safe. */ static char * strtok_r(char *str, const char *delim, char **saveptr) { return strtok(str, delim); } #endif static void addrinfo_item_free(struct gensio_os_funcs *o, struct addrinfo *ai) { if (ai->ai_addr) o->free(o, ai->ai_addr); if (ai->ai_canonname) o->free(o, ai->ai_canonname); o->free(o, ai); } static void addrinfo_list_free(struct gensio_os_funcs *o, struct addrinfo *ai) { struct addrinfo *tai; while (ai) { tai = ai->ai_next; addrinfo_item_free(o, ai); ai = tai; } } static struct addrinfo * addrinfo_dup(struct gensio_os_funcs *o, struct addrinfo *iai) { struct addrinfo *aic; aic = o->zalloc(o, sizeof(*aic)); if (!aic) return NULL; memcpy(aic, iai, sizeof(*aic)); aic->ai_next = NULL; aic->ai_addr = o->zalloc(o, iai->ai_addrlen); if (!aic->ai_addr) goto err; memcpy(aic->ai_addr, iai->ai_addr, iai->ai_addrlen); if (iai->ai_canonname) { aic->ai_canonname = gensio_strdup(o, iai->ai_canonname); if (!aic->ai_canonname) goto err; } return aic; err: addrinfo_item_free(o, aic); return NULL; } /* * Duplicate list ai. If rpai is set, it is a pointer to the last * element of another list, add the duplicated list onto the end of * that list. Return the duplicated list in rai if it is set. */ static int addrinfo_list_dup(struct gensio_os_funcs *o, struct addrinfo *ai, struct addrinfo **rai, struct addrinfo **rpai) { struct addrinfo *cai, *pai = NULL, *tai = NULL; if (!rpai && !rai) return GE_INVAL; while (ai) { cai = addrinfo_dup(o, ai); if (!cai) goto out_nomem; if (!tai) tai = cai; else pai->ai_next = cai; pai = cai; ai = ai->ai_next; } if (rai) *rai = tai; if (rpai) { if (*rpai) (*rpai)->ai_next = tai; *rpai = pai; } return 0; out_nomem: addrinfo_list_free(o, tai); return GE_NOMEM; } static int gensio_addr_dedup(struct gensio_os_funcs *o, struct gensio_addr_addrinfo **iaddr) { struct gensio_addr_addrinfo *addr = *iaddr; struct addrinfo *ai, *ai2, *pai; restart: for (ai = addr->a; ai; ai = ai->ai_next) { for (ai2 = ai->ai_next, pai = ai; ai2; pai = ai2, ai2 = ai2->ai_next) { if (sockaddr_equal(ai->ai_addr, ai->ai_addrlen, ai2->ai_addr, ai2->ai_addrlen, true)) { if (addr->is_getaddrinfo) { int err; /* * To delete the dup, we need to convert it into a * list not allocated by getaddrinfo so we can * modify it. */ err = addrinfo_list_dup(o, addr->a, &ai, NULL); if (err) return err; freeaddrinfo(addr->a); addr->is_getaddrinfo = false; addr->a = ai; addr->curr = ai; goto restart; } pai->ai_next = ai2->ai_next; addrinfo_item_free(o, ai2); ai2 = pai; } } } *iaddr = addr; return 0; } static int gensio_addr_addrinfo_scan_ips(struct gensio_os_funcs *o, const char *str, bool listen, int ifamily, int gprotocol, bool *is_port_set, bool scan_port, struct gensio_addr **raddr) { char *strtok_data, *strtok_buffer; struct gensio_addr_addrinfo *addr; struct addrinfo hints, *ai = NULL, *ai2, *pai = NULL; char *ip; char *port; unsigned int portnum; bool first = true, portset = false; int rv = 0, socktype, protocol; int bflags = AI_ADDRCONFIG; struct sockaddr_storage iaddr; char *end; switch (gprotocol) { case GENSIO_NET_PROTOCOL_UNSPEC: socktype = 0; protocol = 0; break; case GENSIO_NET_PROTOCOL_TCP: socktype = SOCK_STREAM; protocol = IPPROTO_TCP; break; case GENSIO_NET_PROTOCOL_UDP: socktype = SOCK_DGRAM; protocol = IPPROTO_UDP; break; case GENSIO_NET_PROTOCOL_SCTP: #if HAVE_LIBSCTP socktype = SOCK_SEQPACKET; protocol = IPPROTO_SCTP; break; #else return GE_NOTSUP; #endif case GENSIO_NET_PROTOCOL_UNIX_DGRAM: socktype = SOCK_DGRAM; goto do_unix; #ifdef SOCK_SEQPACKET case GENSIO_NET_PROTOCOL_UNIX_SEQPACKET: socktype = SOCK_SEQPACKET; goto do_unix; #endif case GENSIO_NET_PROTOCOL_UNIX: socktype = SOCK_STREAM; do_unix: rv = gensio_scan_unixaddr(o, socktype, str, raddr); if (!rv && is_port_set) *is_port_set = false; return rv; default: return GE_INVAL; } if (listen) bflags |= AI_PASSIVE; strtok_buffer = gensio_strdup(o, str); if (!strtok_buffer) return GE_NOMEM; addr = gensio_addrinfo_make(o, 0, false); if (!addr) { o->free(o, strtok_buffer); return GE_NOMEM; } ip = strtok_r(strtok_buffer, ",", &strtok_data); while (ip) { int family = ifamily, rflags = 0; bool notype = false, gotaddr = false; if (strcmp(ip, "ipv4") == 0) { if (family != AF_UNSPEC && family != AF_INET) { rv = GE_INVAL; goto out_err; } family = AF_INET; ip = strtok_r(NULL, ",", &strtok_data); } else if (strcmp(ip, "ipv6") == 0) { #ifdef AF_INET6 if (family != AF_UNSPEC && family != AF_INET6) { rv = GE_INVAL; goto out_err; } family = AF_INET6; ip = strtok_r(NULL, ",", &strtok_data); #else rv = GE_NOTSUP; goto out_err; #endif } else if (strcmp(ip, "ipv6n4") == 0) { #ifdef AF_INET6 if (family != AF_UNSPEC && family != AF_INET6) { rv = GE_INVAL; goto out_err; } family = AF_INET6; rflags |= AI_V4MAPPED; ip = strtok_r(NULL, ",", &strtok_data); #else rv = GE_NOTSUP; goto out_err; #endif } else { #ifdef AF_INET6 /* * If IPV6 is present, we will try both IPV6 and IPV4 * addresses if an address is specified, or use * AI_V4MAPPED if no ip is specified. * * This is a bit strange. My reading of the getaddrinfo() * man page says that if family == AF_UNSPEC, it's * supposed to return IPV4 and IPV6 addresses. It's not, * even if AI_V4MAPPED is not set or AI_ALL is set, at * least for localhost. * * It only matters if the user specifies an IP address (or * host). If the user does not specify an IP address, use * AF_INET6 and AI_V4MAPPED and it works fine. If the * user specifies an IP address, pull the V6 addresses * then the V4 addresses. Do this for TCP connect * sockets, too, as the connection will be tried on each * address. */ if (family == AF_UNSPEC) { notype = true; family = AF_INET6; } #endif } if (ip == NULL) { rv = GE_INVAL; goto out_err; } if (scan_port) { port = strtok_r(NULL, ",", &strtok_data); if (port == NULL) { port = ip; ip = NULL; } if (ip && *ip == '\0') ip = NULL; } else { port = "0"; } #ifdef AF_INET6 /* * If the user specified something like "tcp,0", ip will be * NULL and getaddrinfo will return IPv4 and IPv6 addresses if * they are available. AI_V4MAPPED will be set, so we really * only want IPv6 addresses (if any are available) as once you * open the IPv6 address you can't open the IPv4 address. */ if (!ip && notype) rflags |= AI_V4MAPPED; #endif /* * If the host address is a valid IP address, skip the * nameserver lookup and just tell getaddrinfo to convert the * numeric value. */ if (ip) { if (family == AF_INET && inet_pton(AF_INET, ip, &iaddr) == 1) rflags |= AI_NUMERICHOST; #ifdef AF_INET6 else if (family == AF_INET6) { if (inet_pton(AF_INET6, ip, &iaddr) == 1) rflags |= AI_NUMERICHOST; else if (rflags & AI_V4MAPPED && inet_pton(AF_INET, ip, &iaddr) == 1) rflags |= AI_NUMERICHOST; } #endif } /* * If the port string is a number, just use the number and don't * do the nameserver lookup for the service. */ if (port && strtoul(port, &end, 10) < 65536 && *end == '\0') rflags |= AI_NUMERICSERV; #ifdef AF_INET6 redo_getaddrinfo: #endif memset(&hints, 0, sizeof(hints)); hints.ai_flags = bflags | rflags; hints.ai_family = family; hints.ai_socktype = socktype; hints.ai_protocol = protocol; rv = getaddrinfo(ip, port, &hints, &ai); if (rv) { #ifdef AF_INET6 if (notype && family == AF_INET6) { /* No IPV6, try just IPV4. */ family = AF_INET; goto redo_getaddrinfo; } #endif if (gotaddr) /* We got some address earlier, go with it. */ goto ignore_getaddr_error; switch (rv) { #ifdef EAI_INTR case EAI_INTR: goto redo_getaddrinfo; #endif case EAI_AGAIN: rv = GE_RETRY; break; #ifdef EAI_ADDRFAMILY case EAI_ADDRFAMILY: rv = GE_NAME_NET_NOT_UP; break; #endif case EAI_BADFLAGS: case EAI_FAMILY: case EAI_SOCKTYPE: /* These mean the code here did something wrong. */ rv = GE_NAME_INVALID; break; case EAI_FAIL: rv = GE_NAME_SERVER_FAILURE; break; case EAI_MEMORY: rv = GE_NOMEM; break; #ifdef EAI_ADDRFAMILY case EAI_NODATA: #endif case EAI_NONAME: rv = GE_NAME_ERROR; break; #ifdef EAI_SYSTEM case EAI_SYSTEM: rv = gensio_os_err_to_err(o, errno); break; #endif default: rv = GE_UNKNOWN_NAME_ERROR; break; } goto out_err; } gotaddr = true; /* * If a port was/was not set, this must be consistent for all * addresses. */ rv = gensio_sockaddr_get_port(ai->ai_addr, &portnum); if (rv) goto out_err; if (first) { portset = portnum != 0; } else { if ((portnum != 0) != portset) { /* One port was set and the other wasn't. */ rv = GE_INCONSISTENT; goto out_err; } } for (ai2 = ai; ai2; ai2 = ai2->ai_next) ai2->ai_flags = rflags; if (!addr->a) { addr->a = ai; ai = NULL; addr->is_getaddrinfo = true; } else { if (!pai) { rv = addrinfo_list_dup(o, addr->a, &ai2, &pai); if (rv) goto out_err; freeaddrinfo(addr->a); addr->is_getaddrinfo = false; addr->a = ai2; } rv = addrinfo_list_dup(o, ai, NULL, &pai); freeaddrinfo(ai); ai = NULL; if (rv) goto out_err; } #ifdef AF_INET6 if (ip && notype && ifamily == AF_UNSPEC && family == AF_INET6) { /* See comments above on why this is done. Yes, it's strange. */ family = AF_INET; goto redo_getaddrinfo; } #endif ignore_getaddr_error: ip = strtok_r(NULL, ",", &strtok_data); first = false; } if (!addr->a) { rv = GE_NOTFOUND; goto out_err; } addr->curr = addr->a; if (is_port_set) *is_port_set = portset; rv = gensio_addr_dedup(o, &addr); if (!rv) *raddr = &addr->r; out_err: if (ai) freeaddrinfo(ai); if (rv) gensio_addr_addrinfo_free(&addr->r); o->free(o, strtok_buffer); return rv; } static struct gensio_addr * gensio_addr_addrinfo_dup(const struct gensio_addr *iaaddr) { struct gensio_addr_addrinfo *iaddr; struct gensio_os_funcs *o; struct gensio_addr_addrinfo *addr; if (!iaaddr) return NULL; iaddr = a_to_info(iaaddr); o = iaddr->o; addr = o->zalloc(o, sizeof(*addr)); if (!addr) return NULL; addr->o = o; addr->r.funcs = &addrinfo_funcs; if (iaddr->refcount) { addr->refcount = iaddr->refcount; addr->a = iaddr->a; addr->is_getaddrinfo = iaddr->is_getaddrinfo; gensio_refcount_inc(addr->refcount); } else { int rv; rv = addrinfo_list_dup(o, iaddr->a, &addr->a, NULL); if (rv) { addrinfo_list_free(o, addr->a); o->free(o, addr); return NULL; } addr->refcount = o->zalloc(o, sizeof(*addr->refcount)); if (!addr->refcount) { addrinfo_list_free(o, addr->a); o->free(o, addr); return NULL; } gensio_refcount_init(o, addr->refcount, 1); } addr->curr = addr->a; return &addr->r; } static struct gensio_addr * gensio_addr_addrinfo_cat(const struct gensio_addr *aaddr1, const struct gensio_addr *aaddr2) { struct gensio_addr_addrinfo *addr1 = a_to_info(aaddr1); struct gensio_addr_addrinfo *addr2 = a_to_info(aaddr2); struct gensio_os_funcs *o = addr1->o; struct gensio_addr_addrinfo *addr; struct addrinfo *aip = NULL; int rv; addr = gensio_addrinfo_make(o, 0, false); if (!addr) return NULL; rv = addrinfo_list_dup(o, addr1->a, &addr->a, &aip); if (rv) goto out_err; rv = addrinfo_list_dup(o, addr2->a, NULL, &aip); if (rv) goto out_err; rv = gensio_addr_dedup(o, &addr); if (rv) goto out_err; addr->curr = addr->a; return &addr->r; out_err: addrinfo_list_free(o, addr->a); o->free(o, addr); return NULL; } static bool gensio_addr_addrinfo_addr_present(const struct gensio_addr *agai, const void *addr, gensiods addrlen, bool compare_ports) { struct gensio_addr_addrinfo *gai = a_to_info(agai); struct addrinfo *ai = gai->a; while (ai) { if (sockaddr_equal(addr, addrlen, ai->ai_addr, ai->ai_addrlen, compare_ports)) return true; ai = ai->ai_next; } return false; } static void gensio_addr_addrinfo_free(struct gensio_addr *aaddr) { struct gensio_addr_addrinfo *addr = a_to_info(aaddr); struct gensio_os_funcs *o = addr->o; if (addr->refcount) { int newval = gensio_refcount_dec(addr->refcount); if (newval != 0) /* Others are using addr->a, just free this address data. */ goto out_free_addr; gensio_refcount_cleanup(addr->refcount); o->free(o, addr->refcount); } if (addr->a) { if (addr->is_getaddrinfo) freeaddrinfo(addr->a); else addrinfo_list_free(o, addr->a); } out_free_addr: o->free(o, addr); } bool gensio_addr_addrinfo_next(struct gensio_addr *aaddr) { struct gensio_addr_addrinfo *addr = a_to_info(aaddr); if (!addr->curr->ai_next) return false; addr->curr = addr->curr->ai_next; return true; } void gensio_addr_addrinfo_rewind(struct gensio_addr *aaddr) { struct gensio_addr_addrinfo *addr = a_to_info(aaddr); addr->curr = addr->a; } static int gensio_addr_addrinfo_get_nettype(const struct gensio_addr *aaddr) { struct gensio_addr_addrinfo *addr = a_to_info(aaddr); switch (addr->curr->ai_addr->sa_family) { case AF_INET: return GENSIO_NETTYPE_IPV4; case AF_INET6: return GENSIO_NETTYPE_IPV6; case AF_UNIX: return GENSIO_NETTYPE_UNIX; default: return GENSIO_NETTYPE_UNSPEC; } } static bool gensio_addr_addrinfo_family_supports(const struct gensio_addr *aaddr, int family, int flags) { struct gensio_addr_addrinfo *addr = a_to_info(aaddr); if (addr->curr->ai_addr->sa_family == family) return true; #ifdef AF_INET6 if (addr->curr->ai_addr->sa_family == AF_INET && family == AF_INET6 && flags & AI_V4MAPPED) return true; #endif return false; } static void gensio_addr_addrinfo_getaddr(const struct gensio_addr *aaddr, void *oaddr, gensiods *rlen) { struct gensio_addr_addrinfo *addr = a_to_info(aaddr); gensiods len; len = *rlen; if (len > addr->curr->ai_addrlen) len = addr->curr->ai_addrlen; memcpy(oaddr, addr->curr->ai_addr, len); *rlen = addr->curr->ai_addrlen; } static struct gensio_addr_funcs addrinfo_funcs = { .addr_equal = gensio_addr_addrinfo_equal, .addr_to_str = gensio_addr_addrinfo_to_str, .addr_to_str_all = gensio_addr_addrinfo_to_str_all, .addr_dup = gensio_addr_addrinfo_dup, .addr_cat = gensio_addr_addrinfo_cat, .addr_addr_present = gensio_addr_addrinfo_addr_present, .addr_free = gensio_addr_addrinfo_free, .addr_next = gensio_addr_addrinfo_next, .addr_rewind = gensio_addr_addrinfo_rewind, .addr_get_nettype = gensio_addr_addrinfo_get_nettype, .addr_family_supports = gensio_addr_addrinfo_family_supports, .addr_getaddr = gensio_addr_addrinfo_getaddr, .addr_get_port = gensio_addr_addrinfo_get_port, .addr_get_data = gensio_addr_addrinfo_get_data }; void gensio_addr_addrinfo_set_os_funcs(struct gensio_os_funcs *o) { o->addr_create = gensio_addr_addrinfo_create; o->addr_scan_ips = gensio_addr_addrinfo_scan_ips; } gensio-3.0.0/lib/sergensio_ipmisol.c0000664000175000017500000012336015045153771013142 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include "utils.h" #include #include #include #include #include #include #include #include "utils.h" #include #include #include #include #include #include #include #define GENSIO_SOL_LL_FREE GENSIO_EVENT_USER_MIN /* * op is client values from sergenio.h serial callbacks, plus * GENSIO_SOL_LL_FREE to tell the user that it can free its data. */ typedef void (*gensio_ll_ipmisol_cb)(void *handler_data, int op, void *data); enum sol_state { SOL_CLOSED, SOL_IN_OPEN, SOL_IN_SOL_OPEN, SOL_OPEN, SOL_IN_CLOSE }; struct sol_ll; struct sol_xlat_str { const char *sval; int ival; }; struct sol_op_done { struct sol_ll *solll; bool started; bool use_runner; gensio_control_done cdone; struct sol_xlat_str *xlatstr; int done_val; int val; void *cb_data; int (*func)(ipmi_sol_conn_t *, int, ipmi_sol_transmit_complete_cb, void *); struct sol_op_done *next; }; struct sol_ll { struct gensio_ll *ll; struct gensio_os_funcs *o; struct gensio *io; struct gensio_lock *lock; unsigned int refcount; /* Callbacks set by gensio_base. */ gensio_ll_cb cb; void *cb_data; /* Serial callbacks. */ gensio_ll_ipmisol_cb ser_cbs; void *ser_cbs_data; char *devname; ipmi_args_t *args; ipmi_con_t *ipmi; ipmi_sol_conn_t *sol; enum sol_state state; bool read_enabled; bool write_enabled; gensio_ll_open_done open_done; void *open_data; int open_err; gensio_ll_close_done close_done; void *close_data; struct gensio_buffer read_data; gensiods max_write_size; /* * If the connection is closed or goes down from the remote end, * this hold the error to return (if non-zero); */ int read_err; bool in_read; bool in_write; gensiods write_outstanding; bool deferred_op_pending; struct gensio_runner *deferred_op_runner; bool deferred_read; bool deferred_write; /* The last report from the SOL connection whether it's up or not. */ int last_any_port_up; unsigned int nacks_sent; /* SOL parms */ int speed; bool authenticated; bool disablebreak; bool encrypted; unsigned int ack_timeout; unsigned int ack_retries; bool deassert_CTS_DCD_DSR_on_connect; bool shared_serial_alert_behavior; /* Pending transmit done handling. */ bool xmit_dones_pending; struct gensio_list xmit_dones; struct gensio_lock *xmit_done_lock; struct gensio_runner *xmit_done_runner; /* * We got a flush/break while one was still pending, do these when * it finishes. */ int pending_flush; int pending_break; struct sol_op_done *cts_done; struct sol_op_done *dcd_dsr_done; struct sol_op_done *ri_done; }; /* Used to hold information about pending transmits. */ struct sol_tc { unsigned int size; struct sol_ll *solll; int err; struct gensio_link link; }; static os_handler_t *gensio_os_handler; #define ll_to_sol(v) ((struct sol_ll *) gensio_ll_get_user_data(v)) static void sol_lock(struct sol_ll *solll) { solll->o->lock(solll->lock); } static void sol_unlock(struct sol_ll *solll) { solll->o->unlock(solll->lock); } static void sol_ref(struct sol_ll *solll) { solll->refcount++; } static void sol_finish_free(struct sol_ll *solll) { if (solll->sol) { ipmi_sol_close(solll->sol); ipmi_sol_free(solll->sol); } if (solll->ipmi) solll->ipmi->close_connection(solll->ipmi); if (solll->ll) gensio_ll_free_data(solll->ll); if (solll->lock) solll->o->free_lock(solll->lock); if (solll->xmit_done_lock) solll->o->free_lock(solll->xmit_done_lock); if (solll->xmit_done_runner) solll->o->free_runner(solll->xmit_done_runner); if (solll->read_data.buf) solll->o->free(solll->o, solll->read_data.buf); if (solll->deferred_op_runner) solll->o->free_runner(solll->deferred_op_runner); if (solll->ser_cbs) solll->ser_cbs(solll->ser_cbs_data, GENSIO_SOL_LL_FREE, NULL); if (solll->args) ipmi_free_args(solll->args); if (solll->devname) solll->o->free(solll->o, solll->devname); solll->o->free(solll->o, solll); } static void sol_deref_and_unlock(struct sol_ll *solll) { unsigned int count; assert(solll->refcount > 0); count = --solll->refcount; sol_unlock(solll); if (count == 0) sol_finish_free(solll); } static int sol_xlat_ipmi_err(struct gensio_os_funcs *o, int err) { if (IPMI_IS_OS_ERR(err)) { return gensio_os_err_to_err(o, IPMI_OS_ERR_VAL(err)); } else if (IPMI_IS_SOL_ERR(err)) { err = IPMI_GET_SOL_ERR(err); if (err == IPMI_SOL_DISCONNECTED) err = GE_REMCLOSE; else if (err == IPMI_SOL_NOT_AVAILABLE) err = GE_COMMERR; else if (err == IPMI_SOL_DEACTIVATED) err = GE_HOSTDOWN; else err = GE_COMMERR; } else if (IPMI_IS_RMCPP_ERR(err)) { err = IPMI_GET_RMCPP_ERR(err); if (err == IPMI_RMCPP_INVALID_PAYLOAD_TYPE) err = GE_CONNREFUSE; else err = GE_COMMERR; } else { err = GE_COMMERR; } return err; } static int sol_do_read_send(void *cb_data, void *buf, unsigned int buflen, unsigned int *written) { struct sol_ll *solll = cb_data; gensiods count; solll->in_read = true; sol_unlock(solll); count = solll->cb(solll->cb_data, GENSIO_LL_CB_READ, 0, buf, buflen, NULL); sol_lock(solll); solll->in_read = false; *written = count; return 0; } static void check_for_read_delivery(struct sol_ll *solll) { while (solll->read_enabled && (gensio_buffer_cursize(&solll->read_data) || solll->read_err) && !solll->in_read) { if (solll->read_err) { sol_unlock(solll); solll->cb(solll->cb_data, GENSIO_LL_CB_READ, solll->read_err, NULL, 0, NULL); sol_lock(solll); } else { gensio_buffer_write(sol_do_read_send, solll, &solll->read_data); /* Maybe we consumed some data, let the other end send if so. */ while (solll->nacks_sent > 0 && gensio_buffer_left(&solll->read_data) > 128) { /* FIXME - magic */ if (ipmi_sol_release_nack(solll->sol)) break; solll->nacks_sent--; } } } } static void check_for_write_ready(struct sol_ll *solll) { while (!solll->in_write && solll->write_enabled && solll->write_outstanding < solll->max_write_size) { solll->in_write = true; sol_unlock(solll); solll->cb(solll->cb_data, GENSIO_LL_CB_WRITE_READY, 0, NULL, 0, NULL); sol_lock(solll); solll->in_write = false; } } static void sol_op_done(struct sol_ll *solll, int err, struct sol_op_done **op_done); static void sol_deferred_op(struct gensio_runner *runner, void *cbdata) { struct sol_ll *solll = cbdata; sol_lock(solll); while (solll->deferred_op_pending) { solll->deferred_op_pending = false; if (solll->cts_done && solll->cts_done->use_runner) sol_op_done(solll, 0, &solll->cts_done); if (solll->dcd_dsr_done && solll->dcd_dsr_done->use_runner) sol_op_done(solll, 0, &solll->dcd_dsr_done); if (solll->ri_done && solll->ri_done->use_runner) sol_op_done(solll, 0, &solll->ri_done); while (solll->deferred_read) { solll->deferred_read = false; check_for_read_delivery(solll); } while (solll->deferred_write) { solll->deferred_write = false; check_for_write_ready(solll); } } sol_deref_and_unlock(solll); } static void sol_sched_deferred_op(struct sol_ll *solll) { if (!solll->deferred_op_pending) { /* Call the read from the selector to avoid lock nesting issues. */ sol_ref(solll); solll->deferred_op_pending = true; solll->o->run(solll->deferred_op_runner); } } static void sol_set_callbacks(struct gensio_ll *ll, gensio_ll_cb cb, void *cb_data) { struct sol_ll *solll = ll_to_sol(ll); solll->cb = cb; solll->cb_data = cb_data; } static void connection_closed(ipmi_con_t *ipmi, void *cb_data); static void handle_xmit_dones(struct gensio_runner *runner, void *cbdata) { struct sol_ll *solll = cbdata; struct gensio_os_funcs *o = solll->o; unsigned int deref_count = 0; sol_lock(solll); o->lock(solll->xmit_done_lock); solll->xmit_dones_pending = false; while (!gensio_list_empty(&solll->xmit_dones)) { struct gensio_link *l = gensio_list_first(&solll->xmit_dones); struct sol_tc *tc = gensio_container_of(l, struct sol_tc, link); gensio_list_rm(&solll->xmit_dones, l); o->unlock(solll->xmit_done_lock); if (tc->err && solll->state != SOL_IN_CLOSE) { solll->read_err = tc->err; check_for_read_delivery(solll); } else { solll->write_outstanding -= tc->size; if (solll->state == SOL_IN_CLOSE) { if (solll->write_outstanding == 0) { tc->err = ipmi_sol_close(solll->sol); if (tc->err) tc->err = solll->ipmi->close_connection_done( solll->ipmi, connection_closed, solll); if (tc->err) { solll->state = SOL_CLOSED; solll->ipmi = NULL; if (solll->close_done) solll->close_done(solll->cb_data, solll->open_data); } } } else { check_for_write_ready(solll); } } o->free(o, tc); deref_count++; o->lock(solll->xmit_done_lock); } o->unlock(solll->xmit_done_lock); if (deref_count >= 1) { assert(solll->refcount >= deref_count); solll->refcount -= deref_count - 1; sol_deref_and_unlock(solll); } else { sol_unlock(solll); } } static void transmit_complete(ipmi_sol_conn_t *conn, int err, void *cb_data) { struct sol_tc *tc = cb_data; struct sol_ll *solll = tc->solll; struct gensio_os_funcs *o = solll->o; if (err) err = sol_xlat_ipmi_err(o, err); tc->err = err; /* * Unfortunately, OpenIPMI isn't quite as nice as gensio, you can * get callbacks from user function calls. So we need to run the * transmit complete handling in a runner. */ o->lock(solll->xmit_done_lock); gensio_list_add_tail(&solll->xmit_dones, &tc->link); if (!solll->xmit_dones_pending) { solll->xmit_dones_pending = true; o->run(solll->xmit_done_runner); } o->unlock(solll->xmit_done_lock); } static int sol_write(struct gensio_ll *ll, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen) { struct sol_ll *solll = ll_to_sol(ll); int err = 0; struct sol_tc *tc; gensiods left, i, total_write = 0, pos = 0; unsigned char *buf = NULL; sol_lock(solll); if (solll->state != SOL_OPEN) { err = GE_NOTREADY; goto out_unlock; } left = solll->max_write_size - solll->write_outstanding; for (i = 0; i < sglen; i++) total_write += sg[i].buflen; if (total_write > left) total_write = left; if (total_write == 0) { pos = 0; goto out_finish; } buf = solll->o->zalloc(solll->o, total_write); if (!buf) { err = GE_NOMEM; goto out_unlock; } for (i = 0; i < sglen; i++) { if (sg[i].buflen >= total_write - pos) { memcpy(buf + pos, sg[i].buf, total_write - pos); break; } else { memcpy(buf + pos, sg[i].buf, sg[i].buflen); pos += sg[i].buflen; } } pos = 0; while (pos < total_write) { tc = solll->o->zalloc(solll->o, sizeof(*tc)); if (!tc) { if (pos == 0) { /* Nothing transmitted, return an error. */ err = GE_NOMEM; goto out_unlock; } goto out_finish; } if (total_write - pos > 255) tc->size = 255; else tc->size = total_write - pos; tc->solll = solll; err = ipmi_sol_write(solll->sol, buf + pos, tc->size, transmit_complete, tc); if (err) { solll->o->free(solll->o, tc); if (pos == 0 && err != EAGAIN) { /* * Nothing transmitted and it's not full buffers, * return an error. */ err = sol_xlat_ipmi_err(solll->o, err); goto out_unlock; } err = 0; goto out_finish; } else { solll->write_outstanding += tc->size; sol_ref(solll); pos += tc->size; } } out_finish: if (rcount) *rcount = pos; out_unlock: if (buf) solll->o->free(solll->o, buf); sol_unlock(solll); return err; } static int sol_data_received(ipmi_sol_conn_t *conn, const void *idata, size_t count, void *user_data) { struct sol_ll *solll = user_data; int rv = 0; sol_lock(solll); if (count <= gensio_buffer_left(&solll->read_data)) { gensio_buffer_output(&solll->read_data, idata, count); check_for_read_delivery(solll); } else { solll->nacks_sent++; rv = 1; } sol_unlock(solll); return rv; } static void sol_break_detected(ipmi_sol_conn_t *conn, void *user_data) { } static void bmc_transmit_overrun(ipmi_sol_conn_t *conn, void *user_data) { } static void connection_closed(ipmi_con_t *ipmi, void *cb_data) { struct sol_ll *solll = cb_data; enum sol_state old_state; sol_lock(solll); old_state = solll->state; solll->state = SOL_CLOSED; solll->ipmi = NULL; sol_unlock(solll); if (old_state == SOL_IN_SOL_OPEN) { if (solll->open_done) solll->open_done(solll->cb_data, solll->read_err, solll->open_data); } else { if (solll->close_done) solll->close_done(solll->cb_data, solll->open_data); } } static void sol_connection_state(ipmi_sol_conn_t *conn, ipmi_sol_state state, int err, void *cb_data) { struct sol_ll *solll = cb_data; if (err) err = sol_xlat_ipmi_err(solll->o, err); sol_lock(solll); switch (state) { case ipmi_sol_state_closed: if (solll->state == SOL_IN_SOL_OPEN) { solll->read_err = GE_CONNREFUSE; if (solll->sol) { ipmi_sol_free(solll->sol); solll->sol = NULL; sol_unlock(solll); solll->ipmi->close_connection_done(solll->ipmi, connection_closed, solll); return; } } else if (solll->state == SOL_IN_CLOSE) { if (solll->sol) { ipmi_sol_free(solll->sol); solll->sol = NULL; sol_unlock(solll); solll->ipmi->close_connection_done(solll->ipmi, connection_closed, solll); return; } } else if (solll->state == SOL_OPEN && !solll->read_err) { if (err) solll->read_err = err; else solll->read_err = GE_NOTREADY; check_for_read_delivery(solll); } break; case ipmi_sol_state_connecting: break; case ipmi_sol_state_connected: if (solll->state == SOL_IN_SOL_OPEN) { solll->state = SOL_OPEN; sol_unlock(solll); solll->open_done(solll->cb_data, err, solll->open_data); sol_lock(solll); } break; case ipmi_sol_state_connected_ctu: break; case ipmi_sol_state_closing: break; } sol_unlock(solll); } static void conn_changed(ipmi_con_t *ipmi, int err, unsigned int port_num, int any_port_up, void *cb_data) { struct sol_ll *solll = cb_data; if (err) err = sol_xlat_ipmi_err(solll->o, err); sol_lock(solll); if (any_port_up == solll->last_any_port_up) goto out_unlock; solll->last_any_port_up = any_port_up; if (solll->state == SOL_IN_OPEN || solll->state == SOL_IN_SOL_OPEN) { if (any_port_up && solll->state == SOL_IN_OPEN) { solll->state = SOL_IN_SOL_OPEN; err = ipmi_sol_open(solll->sol); if (!err) { sol_unlock(solll); return; } any_port_up = 0; err = sol_xlat_ipmi_err(solll->o, err); } if (!any_port_up && (err || solll->read_err)) { solll->state = SOL_CLOSED; if (solll->read_err) err = solll->read_err; /* Prefer the first error we got. */ if (solll->sol) { ipmi_sol_free(solll->sol); solll->sol = NULL; } if (solll->ipmi) { solll->ipmi->close_connection(solll->ipmi); solll->ipmi = NULL; } sol_unlock(solll); solll->open_done(solll->cb_data, err, solll->open_data); return; } } else if (solll->state == SOL_IN_CLOSE) { if (!any_port_up) { solll->state = SOL_CLOSED; sol_unlock(solll); solll->close_done(solll->cb_data, solll->open_data); return; } } else if (err) { solll->read_err = err; check_for_read_delivery(solll); } else if (!any_port_up) { solll->read_err = GE_NOTREADY; check_for_read_delivery(solll); } out_unlock: sol_unlock(solll); } static int sol_open(struct gensio_ll *ll, gensio_ll_open_done done, void *open_data) { struct sol_ll *solll = ll_to_sol(ll); int err; sol_lock(solll); if (solll->state != SOL_CLOSED) { err = GE_INUSE; goto out_unlock; } solll->in_read = false; solll->write_outstanding = 0; solll->read_err = 0; solll->deferred_read = false; solll->deferred_write = false; gensio_buffer_reset(&solll->read_data); solll->nacks_sent = 0; err = ipmi_args_setup_con(solll->args, gensio_os_handler, NULL, &solll->ipmi); if (err) goto out_unlock; err = ipmi_sol_create(solll->ipmi, &solll->sol); if (err) goto out_err; err = ipmi_sol_register_data_received_callback(solll->sol, sol_data_received, solll); if (err) goto out_err; err = ipmi_sol_register_break_detected_callback(solll->sol, sol_break_detected, solll); if (err) goto out_err; err = ipmi_sol_register_bmc_transmit_overrun_callback(solll->sol, bmc_transmit_overrun, solll); if (err) goto out_err; err = ipmi_sol_register_connection_state_callback(solll->sol, sol_connection_state, solll); if (err) goto out_err; ipmi_sol_set_ACK_retries(solll->sol, solll->ack_retries); ipmi_sol_set_ACK_timeout(solll->sol, solll->ack_timeout); ipmi_sol_set_use_authentication(solll->sol, solll->authenticated); ipmi_sol_set_use_encryption(solll->sol, solll->encrypted); ipmi_sol_set_shared_serial_alert_behavior(solll->sol, solll->shared_serial_alert_behavior); ipmi_sol_set_deassert_CTS_DCD_DSR_on_connect(solll->sol, solll->deassert_CTS_DCD_DSR_on_connect); ipmi_sol_set_bit_rate(solll->sol, solll->speed); err = solll->ipmi->add_con_change_handler(solll->ipmi, conn_changed, solll); if (err) goto out_err; solll->last_any_port_up = 0; solll->state = SOL_IN_OPEN; solll->open_done = done; solll->open_data = open_data; err = solll->ipmi->start_con(solll->ipmi); if (err) goto out_err; sol_unlock(solll); return GE_INPROGRESS; out_err: if (solll->sol) { ipmi_sol_close(solll->sol); ipmi_sol_free(solll->sol); solll->sol = NULL; } if (solll->ipmi) { solll->ipmi->close_connection(solll->ipmi); solll->ipmi = NULL; } out_unlock: sol_unlock(solll); if (err) err = sol_xlat_ipmi_err(solll->o, err); return err; } static int sol_close(struct gensio_ll *ll, gensio_ll_close_done done, void *close_data) { struct sol_ll *solll = ll_to_sol(ll); int err = GE_NOTREADY; sol_lock(solll); if (solll->state == SOL_OPEN || solll->state == SOL_IN_OPEN || solll->state == SOL_IN_SOL_OPEN) { solll->read_enabled = false; solll->write_enabled = false; solll->close_done = done; solll->close_data = close_data; solll->state = SOL_IN_CLOSE; if (solll->sol) { if (solll->write_outstanding == 0) err = ipmi_sol_close(solll->sol); else err = 0; } else { err = solll->ipmi->close_connection_done(solll->ipmi, connection_closed, solll); } if (err) err = sol_xlat_ipmi_err(solll->o, err); } sol_unlock(solll); return err; } static void sol_set_read_callback_enable(struct gensio_ll *ll, bool enabled) { struct sol_ll *solll = ll_to_sol(ll); sol_lock(solll); if (solll->read_enabled != enabled) { solll->read_enabled = enabled; if (enabled && solll->state == SOL_OPEN) { solll->deferred_read = true; sol_sched_deferred_op(solll); } } sol_unlock(solll); } static void sol_set_write_callback_enable(struct gensio_ll *ll, bool enabled) { struct sol_ll *solll = ll_to_sol(ll); sol_lock(solll); if (solll->write_enabled != enabled) { solll->write_enabled = enabled; if (enabled && solll->state == SOL_OPEN && solll->write_outstanding < solll->max_write_size) { solll->deferred_write = true; sol_sched_deferred_op(solll); } } sol_unlock(solll); } static void sol_free(struct gensio_ll *ll) { struct sol_ll *solll = ll_to_sol(ll); sol_lock(solll); sol_deref_and_unlock(solll); } static void sol_disable(struct gensio_ll *ll) { struct sol_ll *solll = ll_to_sol(ll); solll->read_enabled = false; solll->write_enabled = false; solll->close_done = NULL; solll->state = SOL_CLOSED; if (solll->sol) { ipmi_sol_force_close_wsend(solll->sol, 0); solll->ipmi->disable(solll->ipmi); solll->ipmi->close_connection(solll->ipmi); } } static int ipmisol_do_break(struct gensio_ll *ll); static int ipmisol_do_flush(struct gensio_ll *ll, int val, const char *sval); static int ipmisol_do_cts(struct gensio_ll *ll, int ival, const char *sval, gensio_control_done cdone, void *cb_data); static int ipmisol_do_dcd_dsr(struct gensio_ll *ll, int ival, const char *sval, gensio_control_done cdone, void *cb_data); static int ipmisol_do_ri(struct gensio_ll *ll, int ival, const char *sval, gensio_control_done cdone, void *cb_data); static int sol_control(struct gensio_ll *ll, bool get, unsigned int option, char *data, gensiods *datalen) { switch(option) { case GENSIO_CONTROL_RADDR: if (!get) return GE_NOTSUP; if (strtoul(data, NULL, 0) > 0) return GE_NOTFOUND; *datalen = gensio_pos_snprintf(data, *datalen, NULL, "ipmisol"); return 0; case GENSIO_CONTROL_SEND_BREAK: case GENSIO_CONTROL_SER_SEND_BREAK: if (get) return GE_NOTSUP; return ipmisol_do_break(ll); case GENSIO_CONTROL_SER_FLUSH: return ipmisol_do_flush(ll, 0, data); default: return GE_NOTSUP; } } static int sol_acontrol(struct gensio_ll *ll, bool get, unsigned int option, struct gensio_func_acontrol *idata) { const char *data = NULL; if (!get) /* On a get, set val to 0 and data to NULL to fetch the value. */ data = idata->data; switch (option) { case GENSIO_ACONTROL_SER_CTS: return ipmisol_do_cts(ll, 0, data, idata->done, idata->cb_data); case GENSIO_ACONTROL_SER_DCD_DSR: return ipmisol_do_dcd_dsr(ll, 0, data, idata->done, idata->cb_data); case GENSIO_ACONTROL_SER_RI: return ipmisol_do_ri(ll, 0, data, idata->done, idata->cb_data); default: return GE_NOTSUP; } } static int gensio_ll_sol_func(struct gensio_ll *ll, int op, gensiods *count, void *buf, const void *cbuf, gensiods buflen, const char *const *auxdata) { switch (op) { case GENSIO_LL_FUNC_SET_CALLBACK: sol_set_callbacks(ll, cbuf, buf); return 0; case GENSIO_LL_FUNC_WRITE_SG: return sol_write(ll, count, cbuf, buflen); case GENSIO_LL_FUNC_OPEN: return sol_open(ll, cbuf, buf); case GENSIO_LL_FUNC_CLOSE: return sol_close(ll, cbuf, buf); case GENSIO_LL_FUNC_SET_READ_CALLBACK: sol_set_read_callback_enable(ll, buflen); return 0; case GENSIO_LL_FUNC_SET_WRITE_CALLBACK: sol_set_write_callback_enable(ll, buflen); return 0; case GENSIO_LL_FUNC_FREE: sol_free(ll); return 0; case GENSIO_LL_FUNC_DISABLE: sol_disable(ll); return 0; case GENSIO_LL_FUNC_CONTROL: return sol_control(ll, *((bool *) cbuf), buflen, buf, count); case GENSIO_LL_FUNC_ACONTROL: return sol_acontrol(ll, *((bool *) cbuf), buflen, buf); default: return GE_NOTSUP; } } static void ipmisol_flush_done(ipmi_sol_conn_t *conn, int error, int queue_selectors_flushed, void *cb_data) { struct sol_ll *solll = cb_data; int rv; sol_lock(solll); if (solll->state == SOL_OPEN && solll->pending_break) { /* A flush came in while one was pending, do it. */ rv = ipmi_sol_flush(solll->sol, solll->pending_break, ipmisol_flush_done, solll); if (!rv) { solll->pending_flush = 0; sol_ref(solll); } } sol_deref_and_unlock(solll); } static int ipmisol_do_flush(struct gensio_ll *ll, int val, const char *sval) { struct sol_ll *solll = ll_to_sol(ll); int rv; if (sval) { if (strcmp(sval, "recv") == 0) val = GENSIO_SER_FLUSH_RECV; else if (strcmp(sval, "xmit") == 0) val = GENSIO_SER_FLUSH_XMIT; else if (strcmp(sval, "both") == 0) val = GENSIO_SER_FLUSH_BOTH; else return GE_INVAL; } switch(val) { case GENSIO_SER_FLUSH_RECV: val = IPMI_SOL_BMC_RECEIVE_QUEUE; break; case GENSIO_SER_FLUSH_XMIT: val = IPMI_SOL_BMC_TRANSMIT_QUEUE; break; case GENSIO_SER_FLUSH_BOTH: return GE_NOTSUP; default: return GE_INVAL; } sol_lock(solll); rv = ipmi_sol_flush(solll->sol, val, ipmisol_flush_done, solll); if (!rv) { sol_ref(solll); } else if (rv == EAGAIN) { solll->pending_flush |= val; } else if (rv == IPMI_SOL_ERR_VAL(IPMI_SOL_UNCONFIRMABLE_OPERATION)) { rv = 0; /* Operation done, but won't get a callback. */ } else { rv = sol_xlat_ipmi_err(solll->o, rv); } sol_unlock(solll); return rv; } static void ipmisol_break_done(ipmi_sol_conn_t *conn, int err, void *cb_data) { struct sol_ll *solll = cb_data; int rv; sol_lock(solll); if (solll->state == SOL_OPEN && solll->pending_break) { /* A flush came in while one was pending, do it. */ rv = ipmi_sol_send_break(solll->sol, ipmisol_break_done, solll); if (!rv) { solll->pending_break = 0; sol_ref(solll); } } sol_deref_and_unlock(solll); } static int ipmisol_do_break(struct gensio_ll *ll) { struct sol_ll *solll = ll_to_sol(ll); int rv; sol_lock(solll); rv = ipmi_sol_send_break(solll->sol, ipmisol_break_done, solll); if (!rv) { sol_ref(solll); } else if (rv == EAGAIN) { solll->pending_break = 1; } else if (rv == IPMI_SOL_ERR_VAL(IPMI_SOL_UNCONFIRMABLE_OPERATION)) { rv = 0; /* Operation done, but won't get a callback. */ } else { rv = sol_xlat_ipmi_err(solll->o, rv); } sol_unlock(solll); return rv; } static void ipmisol_op_done(ipmi_sol_conn_t *conn, int err, void *icb_data) { struct sol_op_done **op_done = icb_data; struct sol_ll *solll = (*op_done)->solll; sol_lock(solll); sol_op_done(solll, err, op_done); sol_deref_and_unlock(solll); } static int sol_start_op(struct sol_ll *solll, struct sol_op_done *op, struct sol_op_done **op_done) { int rv; rv = op->func(solll->sol, op->val, ipmisol_op_done, op_done); switch (rv) { case 0: op->started = true; sol_ref(solll); break; case IPMI_SOL_ERR_VAL(IPMI_SOL_UNCONFIRMABLE_OPERATION): op->started = true; op->use_runner = true; rv = 0; /* Operation done, but won't get a callback. */ /* Schedule the callback in the runner. */ sol_sched_deferred_op(solll); break; case EAGAIN: /* Should not happen. */ rv = GE_INUSE; break; default: rv = sol_xlat_ipmi_err(solll->o, rv); break; } return rv; } static void sol_op_done(struct sol_ll *solll, int err, struct sol_op_done **op_done) { struct gensio_os_funcs *o = solll->o; struct sol_op_done *op = *op_done; gensio_control_done cdone; void *cb_data; const char *sval = NULL; char str[20]; int val; restart: if (err) err = sol_xlat_ipmi_err(solll->o, err); cdone = op->cdone; val = op->done_val; if (!err && cdone) { if (op->xlatstr) { unsigned int i; for (i = 0; op->xlatstr[i].sval; i++) { if (val == op->xlatstr[i].ival) { sval = op->xlatstr[i].sval; break; } } } if (!sval) { snprintf(str, sizeof(str), "%d", val); sval = str; } } cb_data = op->cb_data; *op_done = op->next; o->free(o, op); if (cdone) { sol_unlock(solll); cdone(solll->io, err, sval, sval ? strlen(sval) : 0, cb_data); sol_lock(solll); } op = *op_done; if (op && !op->started) { err = sol_start_op(solll, op, op_done); if (err) goto restart; } } static int sol_do_op(struct sol_ll *solll, struct sol_op_done **op_done, int (*func)(ipmi_sol_conn_t *, int, ipmi_sol_transmit_complete_cb, void *), int val, int done_val, gensio_control_done cdone, struct sol_xlat_str *xlatstr, void *cb_data) { struct gensio_os_funcs *o = solll->o; struct sol_op_done *op, *op2; int rv = 0; op = o->zalloc(o, sizeof(*op)); if (!op) return GE_NOMEM; op->use_runner = false; op->solll = solll; op->cb_data = cb_data; op->val = val; op->done_val = done_val; op->cdone = cdone; op->xlatstr = xlatstr; op->func = func; op->next = NULL; if (*op_done) { /* Something already in progress, just queue it. */ op2 = *op_done; while (op2->next) op2 = op2->next; op2->next = op; } else { rv = sol_start_op(solll, op, op_done); if (rv) o->free(o, op); else *op_done = op; } return rv; } struct sol_xlat_str cts_xlat_str[] = { { "0", 0 }, { "", 0 }, { "auto", GENSIO_SER_ON }, { "off", GENSIO_SER_OFF }, {} }; static int ipmisol_do_cts(struct gensio_ll *ll, int ival, const char *sval, gensio_control_done cdone, void *cb_data) { struct sol_ll *solll = ll_to_sol(ll); int rv, val; if (sval) { if (strcmp(sval, "auto") == 0) ival = GENSIO_SER_ON; else if (strcmp(sval, "off") == 0) ival = GENSIO_SER_OFF; else return GE_INVAL; } sol_lock(solll); switch (ival) { case GENSIO_SER_ON: val = 1; break; case GENSIO_SER_OFF: val = 0; break; default: rv = GE_INVAL; goto out_unlock; } rv = sol_do_op(solll, &solll->cts_done, ipmi_sol_set_CTS_assertable, val, ival, cdone, cts_xlat_str, cb_data); out_unlock: sol_unlock(solll); return rv; } struct sol_xlat_str on_off_xlat_str[] = { { "0", 0 }, { "", 0 }, { "on", GENSIO_SER_ON }, { "off", GENSIO_SER_OFF }, {} }; static int ipmisol_do_dcd_dsr(struct gensio_ll *ll, int ival, const char *sval, gensio_control_done cdone, void *cb_data) { struct sol_ll *solll = ll_to_sol(ll); int rv, val; if (sval) { if (strcmp(sval, "on") == 0) ival = GENSIO_SER_ON; else if (strcmp(sval, "off") == 0) ival = GENSIO_SER_OFF; else return GE_INVAL; } sol_lock(solll); switch (ival) { case GENSIO_SER_ON: val = 1; break; case GENSIO_SER_OFF: val = 0; break; default: rv = GE_INVAL; goto out_unlock; } rv = sol_do_op(solll, &solll->dcd_dsr_done, ipmi_sol_set_DCD_DSR_asserted, val, ival, cdone, on_off_xlat_str, cb_data); out_unlock: sol_unlock(solll); return rv; } static int ipmisol_do_ri(struct gensio_ll *ll, int ival, const char *sval, gensio_control_done cdone, void *cb_data) { struct sol_ll *solll = ll_to_sol(ll); int rv, val; if (sval) { if (strcmp(sval, "on") == 0) ival = GENSIO_SER_ON; else if (strcmp(sval, "off") == 0) ival = GENSIO_SER_OFF; else return GE_INVAL; } sol_lock(solll); switch (ival) { case GENSIO_SER_ON: val = 1; break; case GENSIO_SER_OFF: val = 0; break; default: rv = GE_INVAL; goto out_unlock; } rv = sol_do_op(solll, &solll->ri_done, ipmi_sol_set_RI_asserted, val, ival, cdone, on_off_xlat_str, cb_data); out_unlock: sol_unlock(solll); return rv; } static int sol_get_defaults(struct sol_ll *solll) { struct gensio_os_funcs *o = solll->o; char *speed; int ival, err; err = gensio_get_default(o, "sol", "speed", false, GENSIO_DEFAULT_STR, &speed, NULL); if (err) { gensio_log(o, GENSIO_LOG_ERR, "Failed getting default sol speed: %s\n", gensio_err_to_str(err)); return err; } if (speed) { if (strncmp(speed, "9600", 4) == 0) solll->speed = IPMI_SOL_BIT_RATE_9600; else if (strncmp(speed, "19200", 5) == 0) solll->speed = IPMI_SOL_BIT_RATE_19200; else if (strncmp(speed, "38400", 5) == 0) solll->speed = IPMI_SOL_BIT_RATE_38400; else if (strncmp(speed, "57600", 5) == 0) solll->speed = IPMI_SOL_BIT_RATE_57600; else if (strncmp(speed, "115200", 6) == 0) solll->speed = IPMI_SOL_BIT_RATE_115200; else { gensio_log(o, GENSIO_LOG_ERR, "Invalid default speed for SOL %s: %s." " Defaulting to 9600", solll->devname, speed); solll->speed = IPMI_SOL_BIT_RATE_9600; } o->free(o, speed); } /* Enable authentication and encryption by default. */ err = gensio_get_default(o, "sol", "authenticated", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (err) return err; solll->authenticated = ival; err = gensio_get_default(o, "sol", "encrypted", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (err) return err; solll->encrypted = ival; err = gensio_get_default(o, "sol", "nobreak", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (err) return err; ival = solll->disablebreak; err = gensio_get_default(o, "sol", "ack-timeout", false, GENSIO_DEFAULT_INT, NULL, &ival); if (err) return err; solll->ack_timeout = ival; err = gensio_get_default(o, "sol", "ack-retries", false, GENSIO_DEFAULT_INT, NULL, &ival); if (err) return err; solll->ack_retries = ival; err = gensio_get_default(o, "sol", "shared-serial-alert", false, GENSIO_DEFAULT_INT, NULL, &ival); if (err) return err; solll->shared_serial_alert_behavior = ival; err = gensio_get_default(o, "sol", "deassert-CTS-DCD-DSR-on-connect", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (err) return err; solll->deassert_CTS_DCD_DSR_on_connect = ival; return 0; } static int sol_process_parm(struct gensio_pparm_info *p, struct sol_ll *solll, char *arg) { if (strncmp(arg, "9600", 4) == 0) { solll->speed = IPMI_SOL_BIT_RATE_9600; } else if (strncmp(arg, "19200", 5) == 0) { solll->speed = IPMI_SOL_BIT_RATE_19200; } else if (strncmp(arg, "38400", 5) == 0) { solll->speed = IPMI_SOL_BIT_RATE_38400; } else if (strncmp(arg, "57600", 5) == 0) { solll->speed = IPMI_SOL_BIT_RATE_57600; } else if (strncmp(arg, "115200", 6) == 0) { solll->speed = IPMI_SOL_BIT_RATE_115200; } else if (gensio_pparm_bool(p, arg, "nobreak", &solll->disablebreak) > 0) { } else if (gensio_pparm_bool(p, arg, "authenticated", &solll->authenticated) > 0) { } else if (gensio_pparm_bool(p, arg, "encrypted", &solll->encrypted) > 0) { } else if (gensio_pparm_bool(p, arg, "deassert-CTS-DCD-DSR-on-connect", &solll->deassert_CTS_DCD_DSR_on_connect) > 0) { } else if (strcasecmp(arg, "shared-serial-alert-fail") == 0) { solll->shared_serial_alert_behavior = ipmi_sol_serial_alerts_fail; } else if (strcmp(arg, "shared-serial-alert-deferred") == 0) { solll->shared_serial_alert_behavior = ipmi_sol_serial_alerts_deferred; } else if (strcmp(arg, "shared-serial-alert-succeed") == 0) { solll->shared_serial_alert_behavior = ipmi_sol_serial_alerts_succeed; } else if (gensio_pparm_uint(p, arg, "ack-timeout", &solll->ack_timeout) > 0) { } else if (gensio_pparm_uint(p, arg, "ack-retries", &solll->ack_retries) > 0) { /* The rest of the ones below are deprecated. */ } else if (strcmp(arg, "-NOBREAK") == 0) { solll->disablebreak = false; } else if (strcmp(arg, "-authenticated") == 0) { solll->authenticated = false; } else if (strcmp(arg, "-encrypted") == 0) { solll->encrypted = false; } else if (strcmp(arg, "-deassert_CTS_DCD_DSR_on_connect") == 0) { solll->deassert_CTS_DCD_DSR_on_connect = false; } else if (strcmp(arg, "deassert_CTS_DCD_DSR_on_connect") == 0) { solll->deassert_CTS_DCD_DSR_on_connect = true; } else if (strcmp(arg, "shared_serial_alert_fail") == 0) { solll->shared_serial_alert_behavior = ipmi_sol_serial_alerts_fail; } else if (strcmp(arg, "shared_serial_alert_deferred") == 0) { solll->shared_serial_alert_behavior = ipmi_sol_serial_alerts_deferred; } else if (strcmp(arg, "shared_serial_alert_succeed") == 0) { solll->shared_serial_alert_behavior = ipmi_sol_serial_alerts_succeed; } else { gensio_pparm_unknown_parm(p, arg); return GE_INVAL; } return 0; } static int sol_process_parms(struct gensio_pparm_info *p, struct sol_ll *solll) { char *pos, *strtok_data; int err; pos = strchr(solll->devname, ','); if (!pos) return 0; *pos++ = '\0'; for (pos = strtok_r(pos, ",", &strtok_data); pos; pos = strtok_r(NULL, ",", &strtok_data)) { err = sol_process_parm(p, solll, pos); if (err) return err; } return 0; } static struct gensio_once gensio_ipmi_initialized; static int ipmi_init_err; static void gensio_sol_cleanup_mem(void) { ipmi_shutdown(); } static struct gensio_class_cleanup sol_cleanup = { gensio_sol_cleanup_mem }; static void gensio_ipmi_init(void *cb_data) { struct gensio_os_funcs *o = cb_data; gensio_os_handler = gensio_openipmi_oshandler_alloc(o); if (!gensio_os_handler) abort(); ipmi_init_err = ipmi_init(gensio_os_handler); if (!ipmi_init_err) gensio_register_class_cleanup(&sol_cleanup); } static int ipmisol_gensio_ll_alloc(struct gensio_pparm_info *p, struct gensio_os_funcs *o, const char *devname, gensio_ll_ipmisol_cb ser_cbs, void *ser_cbs_data, gensiods max_read_size, gensiods max_write_size, struct gensio_ll **rll) { struct sol_ll *solll; int err, argc, curr_arg = 0; const char **argv; o->call_once(o, &gensio_ipmi_initialized, gensio_ipmi_init, o); if (ipmi_init_err) return sol_xlat_ipmi_err(o, ipmi_init_err); solll = o->zalloc(o, sizeof(*solll)); if (!solll) return GE_NOMEM; solll->o = o; solll->refcount = 1; solll->state = SOL_CLOSED; solll->last_any_port_up = -1; solll->devname = gensio_strdup(o, devname); if (!solll->devname) goto out_nomem; err = sol_get_defaults(solll); if (!err) err = sol_process_parms(p, solll); if (err) goto out_err; err = gensio_str_to_argv(o, solll->devname, &argc, &argv, NULL); if (err) goto out_err; if (argc == 0) { err = GE_INVAL; goto out_err; } err = ipmi_parse_args2(&curr_arg, argc, (char **) argv, &solll->args); if (err) { gensio_argv_free(o, argv); goto out_err; } if (curr_arg != argc) { gensio_log(o, GENSIO_LOG_WARNING, "Extra SOL arguments starting with %s\n", argv[curr_arg]); err = GE_INVAL; gensio_argv_free(o, argv); goto out_err; } gensio_argv_free(o, argv); solll->deferred_op_runner = o->alloc_runner(o, sol_deferred_op, solll); if (!solll->deferred_op_runner) goto out_nomem; solll->lock = o->alloc_lock(o); if (!solll->lock) goto out_nomem; solll->xmit_done_lock = o->alloc_lock(o); if (!solll->xmit_done_lock) goto out_nomem; gensio_list_init(&solll->xmit_dones); solll->xmit_done_runner = o->alloc_runner(o, handle_xmit_dones, solll); if (!solll->xmit_done_runner) goto out_nomem; solll->read_data.maxsize = max_read_size; solll->read_data.buf = o->zalloc(o, max_read_size); if (!solll->read_data.buf) goto out_nomem; solll->max_write_size = max_write_size; solll->ll = gensio_ll_alloc_data(o, gensio_ll_sol_func, solll); if (!solll->ll) goto out_nomem; /* Don't set these until here lest a failure call the free operation. */ solll->ser_cbs = ser_cbs; solll->ser_cbs_data = ser_cbs_data; *rll = solll->ll; return 0; out_nomem: err = GE_NOMEM; out_err: sol_finish_free(solll); return err; } struct iterm_data { struct gensio_os_funcs *o; struct gensio_ll *ll; struct gensio *io; }; static void iterm_free(struct iterm_data *idata) { idata->o->free(idata->o, idata); } static void iterm_ser_cb(void *handler_data, int op, void *data) { struct iterm_data *idata = handler_data; if (op == GENSIO_SOL_LL_FREE) { iterm_free(handler_data); return; } gensio_cb(idata->io, op, 0, NULL, NULL, NULL); } static int ipmisol_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **rio) { const char *devname = gdata; struct iterm_data *idata = NULL; int err; gensiods max_read_size = GENSIO_DEFAULT_BUF_SIZE; gensiods max_write_size = GENSIO_DEFAULT_BUF_SIZE; int i; struct sol_ll *solll; struct gensio_base_parms *parms = NULL; GENSIO_DECLARE_PPGENSIO(p, o, cb, "ipmisol", user_data); err = gensio_base_parms_alloc(o, true, "ipmisol", &parms); if (err) goto out_err; for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(&p, args[i], "readbuf", &max_read_size) > 0) continue; if (gensio_pparm_ds(&p, args[i], "writebuf", &max_write_size) > 0) continue; if (parms && gensio_base_parm(parms, &p, args[i]) > 0) continue; gensio_pparm_unknown_parm(&p, args[i]); err = GE_INVAL; goto out_err; } idata = o->zalloc(o, sizeof(*idata)); if (!idata) goto out_nomem; idata->o = o; err = ipmisol_gensio_ll_alloc(&p, o, devname, iterm_ser_cb, idata, max_read_size, max_write_size, &idata->ll); if (err) goto out_err; idata->io = base_gensio_alloc(o, idata->ll, NULL, NULL, "ipmisol", cb, user_data); if (!idata->io) { gensio_ll_free(idata->ll); goto out_nomem; } err = gensio_base_parms_set(idata->io, &parms); if (err) { gensio_free(idata->io); goto out_err; } solll = ll_to_sol(idata->ll); solll->io = idata->io; gensio_set_is_serial(idata->io, true); *rio = idata->io; return 0; out_nomem: err = GE_NOMEM; out_err: if (idata) iterm_free(idata); if (parms) gensio_base_parms_free(&parms); return err; } static int str_to_ipmisol_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { return ipmisol_gensio_alloc(str, args, o, cb, user_data, new_gensio); } int gensio_init_ipmisol(struct gensio_os_funcs *o) { int rv; rv = register_gensio(o, "ipmisol", str_to_ipmisol_gensio, ipmisol_gensio_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/acc.c0000664000175000017500000003053615011177264010134 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include "gensio_base_parms.h" enum basena_state { BASENA_CLOSED, BASENA_OPEN, BASENA_IN_SHUTDOWN }; struct basena_data { enum basena_state state; struct gensio_accepter *acc; struct gensio_os_funcs *o; struct gensio_lock *lock; struct gensio_base_parms parms; gensio_base_acc_op ops; void *acc_op_data; gensio_gensio_acc_cb acc_cb; void *acc_data; gensio_acc_done set_cb_enable_done; void *set_cb_enable_done_data; unsigned int refcount; unsigned int in_cb_count; bool freed; bool call_shutdown_done; gensio_acc_done shutdown_done; void *shutdown_data; }; static void basena_set_state(struct basena_data *nadata, enum basena_state state) { nadata->state = state; } int gensio_acc_base_parms_set(struct gensio_accepter *acc, struct gensio_base_parms **parms) { struct basena_data *nadata = gensio_acc_get_gensio_data(acc); nadata->parms = **parms; gensio_base_parms_free(parms); return 0; } int gensio_acc_base_parms_apply(struct gensio_accepter *acc, struct gensio *io) { struct basena_data *nadata = gensio_acc_get_gensio_data(acc); i_gensio_base_parms_set(io, &nadata->parms); return 0; } struct gensio_base_parms * gensio_acc_base_parms_dup(struct gensio_accepter *acc) { struct basena_data *nadata = gensio_acc_get_gensio_data(acc); struct gensio_os_funcs *o = nadata->parms.o; struct gensio_base_parms *parms = o->zalloc(o, sizeof(*parms)); if (!parms) return NULL; *parms = nadata->parms; return parms; } static int base_gensio_acc_startup(struct basena_data *nadata) { return nadata->ops(nadata->acc, GENSIO_BASE_ACC_STARTUP, nadata->acc_op_data, NULL, 0, NULL, NULL, NULL); } static int base_gensio_acc_shutdown(struct basena_data *nadata, gensio_acc_done done) { return nadata->ops(nadata->acc, GENSIO_BASE_ACC_SHUTDOWN, nadata->acc_op_data, done, 0, NULL, NULL, NULL); } static int base_gensio_acc_set_cb_enable(struct basena_data *nadata, bool enabled, gensio_acc_done done) { return nadata->ops(nadata->acc, GENSIO_BASE_ACC_SET_CB_ENABLE, nadata->acc_op_data, done, enabled, NULL, NULL, NULL); } static int base_gensio_acc_free(struct basena_data *nadata) { return nadata->ops(nadata->acc, GENSIO_BASE_ACC_FREE, nadata->acc_op_data, NULL, 0, NULL, NULL, NULL); } static int base_gensio_acc_disable(struct basena_data *nadata) { return nadata->ops(nadata->acc, GENSIO_BASE_ACC_DISABLE, nadata->acc_op_data, NULL, 0, NULL, NULL, NULL); } static int base_gensio_acc_control(struct basena_data *nadata, bool get, unsigned int option, char *data, gensiods *datalen) { return nadata->ops(nadata->acc, GENSIO_BASE_ACC_CONTROL, nadata->acc_op_data, (unsigned int *) &option, get, data, NULL, datalen); } static int base_gensio_acc_str_to_gensio(struct basena_data *nadata, const char *addr, gensio_event cb, void *user_data, struct gensio **new_io) { return nadata->ops(nadata->acc, GENSIO_BASE_ACC_STR_TO_GENSIO, nadata->acc_op_data, cb, 0, (void *) addr, user_data, new_io); } static void basena_lock(struct basena_data *nadata) { nadata->o->lock(nadata->lock); } static void basena_unlock(struct basena_data *nadata) { nadata->o->unlock(nadata->lock); } static void basena_finish_free(struct basena_data *nadata) { struct gensio_os_funcs *o = nadata->o; if (nadata->lock) o->free_lock(nadata->lock); if (nadata->ops) base_gensio_acc_free(nadata); if (nadata->acc) gensio_acc_data_free(nadata->acc); memset(nadata, 0, sizeof(*nadata)); o->free(o, nadata); } static void basena_ref(struct basena_data *nadata) { assert(nadata->refcount > 0); nadata->refcount++; } static void basena_deref_and_unlock(struct basena_data *nadata) { unsigned int count; assert(nadata->refcount > 0); count = --nadata->refcount; basena_unlock(nadata); if (count == 0) basena_finish_free(nadata); } static void basena_finish_shutdown_unlock(struct basena_data *nadata) { void *shutdown_data; void (*shutdown_done)(struct gensio_accepter *accepter, void *shutdown_data); basena_set_state(nadata, BASENA_CLOSED); shutdown_done = nadata->shutdown_done; shutdown_data = nadata->shutdown_data; nadata->shutdown_done = NULL; basena_unlock(nadata); if (shutdown_done) shutdown_done(nadata->acc, shutdown_data); basena_lock(nadata); basena_deref_and_unlock(nadata); } static void basena_in_cb(struct basena_data *nadata) { basena_ref(nadata); nadata->in_cb_count++; } static void basena_leave_cb_unlock(struct basena_data *nadata) { nadata->in_cb_count--; if (nadata->in_cb_count == 0 && nadata->call_shutdown_done) basena_finish_shutdown_unlock(nadata); else basena_deref_and_unlock(nadata); } static int basena_startup(struct gensio_accepter *accepter) { struct basena_data *nadata = gensio_acc_get_gensio_data(accepter); int err; basena_lock(nadata); assert(!nadata->freed); if (nadata->state != BASENA_CLOSED) { err = GE_NOTREADY; } else { nadata->shutdown_done = NULL; err = base_gensio_acc_startup(nadata); if (!err) basena_set_state(nadata, BASENA_OPEN); } basena_unlock(nadata); return err; } static void basena_child_shutdown_done(struct gensio_accepter *accepter, void *shutdown_data) { struct basena_data *nadata = gensio_acc_get_gensio_data(accepter); basena_lock(nadata); if (nadata->in_cb_count) { nadata->call_shutdown_done = true; basena_deref_and_unlock(nadata); } else { basena_finish_shutdown_unlock(nadata); } } static int basena_shutdown(struct gensio_accepter *accepter, gensio_acc_done shutdown_done, void *shutdown_data) { struct basena_data *nadata = gensio_acc_get_gensio_data(accepter); int rv = GE_NOTREADY; basena_lock(nadata); if (nadata->state == BASENA_OPEN) { nadata->shutdown_done = shutdown_done; nadata->shutdown_data = shutdown_data; rv = base_gensio_acc_shutdown(nadata, basena_child_shutdown_done); if (!rv) { basena_ref(nadata); basena_set_state(nadata, BASENA_IN_SHUTDOWN); } } basena_unlock(nadata); return rv; } static void basena_cb_en_done(struct gensio_accepter *accepter, void *cb_data) { struct basena_data *nadata = gensio_acc_get_gensio_data(accepter); gensio_acc_done done; void *done_data; struct gensio_accepter *acc = nadata->acc; basena_lock(nadata); done = nadata->set_cb_enable_done; done_data = nadata->set_cb_enable_done_data; nadata->set_cb_enable_done = NULL; basena_unlock(nadata); done(acc, done_data); basena_lock(nadata); basena_leave_cb_unlock(nadata); } static int basena_set_accept_callback_enable(struct gensio_accepter *accepter, bool enabled, gensio_acc_done done, void *done_data) { struct basena_data *nadata = gensio_acc_get_gensio_data(accepter); gensio_acc_done ldone = NULL; int rv = 0; basena_lock(nadata); if (nadata->state != BASENA_OPEN || (done && nadata->set_cb_enable_done)) { rv = GE_NOTREADY; } else if (done) { nadata->set_cb_enable_done = done; nadata->set_cb_enable_done_data = done_data; ldone = basena_cb_en_done; } if (!rv) rv = base_gensio_acc_set_cb_enable(nadata, enabled, ldone); if (!rv && done) basena_in_cb(nadata); basena_unlock(nadata); return rv; } static void basena_free(struct gensio_accepter *accepter) { struct basena_data *nadata = gensio_acc_get_gensio_data(accepter); int rv; basena_lock(nadata); assert(!nadata->freed); nadata->freed = true; switch (nadata->state) { case BASENA_CLOSED: break; case BASENA_IN_SHUTDOWN: nadata->shutdown_done = NULL; break; case BASENA_OPEN: rv = base_gensio_acc_shutdown(nadata, basena_child_shutdown_done); if (rv) { basena_set_state(nadata, BASENA_CLOSED); } else { basena_ref(nadata); basena_set_state(nadata, BASENA_IN_SHUTDOWN); } break; default: assert(0); } basena_deref_and_unlock(nadata); } static int basena_str_to_gensio(struct gensio_accepter *accepter, const char *addr, gensio_event cb, void *user_data, struct gensio **new_io) { struct basena_data *nadata = gensio_acc_get_gensio_data(accepter); return base_gensio_acc_str_to_gensio(nadata, addr, cb, user_data, new_io); } static int basena_control(struct gensio_accepter *accepter, bool get, unsigned int option, char *data, gensiods *datalen) { struct basena_data *nadata = gensio_acc_get_gensio_data(accepter); return base_gensio_acc_control(nadata, get, option, data, datalen); } static int basena_disable(struct gensio_accepter *accepter) { struct basena_data *nadata = gensio_acc_get_gensio_data(accepter); basena_set_state(nadata, BASENA_CLOSED); return base_gensio_acc_disable(nadata); } static int gensio_acc_base_func(struct gensio_accepter *acc, int func, int val, const char *addr, void *done, void *data, const void *data2, void *ret) { switch (func) { case GENSIO_ACC_FUNC_STARTUP: return basena_startup(acc); case GENSIO_ACC_FUNC_SHUTDOWN: return basena_shutdown(acc, done, data); case GENSIO_ACC_FUNC_SET_ACCEPT_CALLBACK: return basena_set_accept_callback_enable(acc, val, done, data); case GENSIO_ACC_FUNC_FREE: basena_free(acc); return 0; case GENSIO_ACC_FUNC_STR_TO_GENSIO: return basena_str_to_gensio(acc, addr, done, data, ret); case GENSIO_ACC_FUNC_CONTROL: return basena_control(acc, val, *((unsigned int *) done), data, ret); case GENSIO_ACC_FUNC_DISABLE: return basena_disable(acc); default: return GE_NOTSUP; } } void * base_gensio_accepter_get_op_data(struct gensio_accepter *accepter) { struct basena_data *nadata = gensio_acc_get_gensio_data(accepter); return nadata->acc_op_data; } int base_gensio_accepter_new_child_start(struct gensio_accepter *accepter) { struct basena_data *nadata = gensio_acc_get_gensio_data(accepter); basena_lock(nadata); if (nadata->state != BASENA_OPEN) { basena_unlock(nadata); return GE_NOTREADY; } return 0; } void base_gensio_accepter_new_child_end(struct gensio_accepter *accepter, struct gensio *io, int err) { struct basena_data *nadata = gensio_acc_get_gensio_data(accepter); if (!err) { basena_in_cb(nadata); gensio_acc_add_pending_gensio(nadata->acc, io); } basena_unlock(nadata); } void base_gensio_server_open_done(struct gensio_accepter *accepter, struct gensio *net, int err) { struct basena_data *nadata = gensio_acc_get_gensio_data(accepter); basena_lock(nadata); gensio_acc_remove_pending_gensio(nadata->acc, net); if (err) { gensio_free(net); gensio_acc_log(nadata->acc, GENSIO_LOG_ERR, "Error accepting a gensio: %s", gensio_err_to_str(err)); } else if (nadata->state == BASENA_OPEN) { nadata->in_cb_count++; basena_unlock(nadata); gensio_acc_cb(nadata->acc, GENSIO_ACC_EVENT_NEW_CONNECTION, net); basena_lock(nadata); nadata->in_cb_count--; } else { gensio_free(net); } basena_leave_cb_unlock(nadata); } int base_gensio_accepter_alloc(struct gensio_accepter *child, gensio_base_acc_op ops, void *acc_op_data, struct gensio_os_funcs *o, const char *typename, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { struct basena_data *nadata; nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) return GE_NOMEM; nadata->o = o; nadata->lock = o->alloc_lock(o); if (!nadata->lock) goto out_nomem; nadata->acc = gensio_acc_data_alloc(o, cb, user_data, gensio_acc_base_func, child, typename, nadata); if (!nadata->acc) goto out_nomem; nadata->ops = ops; nadata->acc_op_data = acc_op_data; nadata->refcount = 1; *accepter = nadata->acc; return 0; out_nomem: basena_finish_free(nadata); return GE_NOMEM; } gensio-3.0.0/lib/gensio_sound_portaudio.h0000664000175000017500000003717314747451760014214 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2023 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include struct win_sound_format_cnv { enum gensio_sound_fmt_type gformat; PaSampleFormat fmt; } pa_sound_fmt_cnv[] = { { .gformat = GENSIO_SOUND_FMT_FLOAT, .fmt = paFloat32, }, { .gformat = GENSIO_SOUND_FMT_S32, .fmt = paInt32, }, { .gformat = GENSIO_SOUND_FMT_S24, .fmt = paInt24, }, { .gformat = GENSIO_SOUND_FMT_S16, .fmt = paInt16, }, { .gformat = GENSIO_SOUND_FMT_S8, .fmt = paInt8, }, { .gformat = GENSIO_SOUND_FMT_UNKNOWN } }; static int i_gensio_pa_err_to_err(struct gensio_os_funcs *o, PaErrorCode pa_err, const char *caller, const char *file, unsigned int lineno) { int err; switch (pa_err) { case paNotInitialized: err = GE_NOTREADY; break; case paInvalidChannelCount: err = GE_INVAL; break; case paInvalidSampleRate: err = GE_INVAL; break; case paInvalidDevice: err = GE_INVAL; break; case paInvalidFlag: err = GE_INVAL; break; case paSampleFormatNotSupported: err = GE_INVAL; break; case paBadIODeviceCombination: err = GE_INVAL; break; case paInsufficientMemory: err = GE_NOMEM; break; case paBufferTooBig: err = GE_INVAL; break; case paBufferTooSmall: err = GE_INVAL; break; case paNullCallback: err = GE_INVAL; break; case paBadStreamPtr: err = GE_INVAL; break; case paTimedOut: err = GE_TIMEDOUT; break; case paInternalError: case paDeviceUnavailable: case paIncompatibleHostApiSpecificStreamInfo: case paStreamIsStopped: case paStreamIsNotStopped: case paInputOverflowed: case paOutputUnderflowed: case paHostApiNotFound: case paInvalidHostApi: case paCanNotReadFromACallbackStream: case paCanNotWriteToACallbackStream: case paCanNotReadFromAnOutputOnlyStream: case paCanNotWriteToAnInputOnlyStream: case paIncompatibleStreamHostApi: case paBadBufferPtr: case paUnanticipatedHostError: default: err = GE_OSERR; break; } if (err == GE_OSERR || err == GE_INVAL) { const char *errstr = Pa_GetErrorText(pa_err); gensio_log(o, GENSIO_LOG_INFO, "Unhandled portaudio error in %s:%d: %s (%d)", caller, lineno, errstr, pa_err); } return err; } #define gensio_pa_err_to_err(o, pa_err) \ i_gensio_pa_err_to_err(o, pa_err, __func__, __FILE__, __LINE__) static int gensio_sound_pa_get_wavefmt(enum gensio_sound_fmt_type gformat, PaSampleFormat *fmt) { unsigned int i; for (i = 0; pa_sound_fmt_cnv[i].gformat != GENSIO_SOUND_FMT_UNKNOWN; i++) { if (gformat == pa_sound_fmt_cnv[i].gformat) break; } if (gformat != pa_sound_fmt_cnv[i].gformat) return GE_INVAL; *fmt = pa_sound_fmt_cnv[i].fmt; return 0; } struct pa_sound_info { PaStream *stream; int devidx; /* * Used to avoid stutter at start, wait until we have a few buffers * before starting the transmitter. */ bool started; double latency; /* Position of pcm data, in cnv.buf, both receive and transmit. */ unsigned int size; /* Total buffer size in bytes. */ unsigned int pos; /* Output position in bytes. */ unsigned int len; /* Available data in cnv.buf, in bytes. */ }; #define BASE_LATENCY .1 static unsigned long gensio_sound_pa_drain_count(struct sound_info *si) { struct pa_sound_info *w = si->pinfo; /* * FIXME - This isn't entirely accurate. You really need to get * the number of frames outstanding in portaudio, but there * doesn't seem to be a way to do it. You can't call * Pa_GetStreamWriteAvailable on a callback stream. */ return w->latency * si->samplerate + w->len / si->cnv.pframesize; } static void gensio_sound_pa_api_close_dev(struct sound_info *si) { struct pa_sound_info *w = si->pinfo; if (!w) return; Pa_CloseStream(w->stream); w->stream = NULL; } static void gensio_sound_pa_copy_sample(const unsigned char **in, unsigned char **out, struct sound_cnv_info *info) { memcpy(*out, *in, info->usize); *out += info->usize; *in += info->usize; } static void gensio_sound_pa_process_read_buffer(struct sound_info *si) { struct pa_sound_info *w = si->pinfo; const unsigned char *inbuf; unsigned char *outbuf; gensiods psize; void (*convin)(const unsigned char **in, unsigned char **out, struct sound_cnv_info *info); /* Not enough data or data still left for the user to pick up. */ if (w->len < si->bufsize * si->cnv.pframesize || si->ready) return; psize = si->cnv.psize; if (si->cnv.enabled) convin = si->cnv.convin; else convin = gensio_sound_pa_copy_sample; inbuf = si->cnv.buf + w->pos; outbuf = si->buf + (si->len * si->framesize); while (w->len > 0 && si->len < si->bufsize) { convin(&inbuf, &outbuf, &si->cnv); si->len++; w->len -= psize; w->pos += psize; if (w->pos >= w->size) w->pos = 0; } si->ready = true; gensio_sound_sched_deferred_op(si->soundll); } static void gensio_sound_pa_api_next_read(struct sound_info *si) { gensio_sound_pa_process_read_buffer(si); } static void gensio_sound_pa_api_set_read(struct sound_info *si, bool enable) { if (enable) gensio_sound_pa_process_read_buffer(si); } static void gensio_sound_pa_api_set_write(struct sound_info *si, bool enable) { /* Nothing to do here. */ } static void gensio_sound_pa_stream_finished(void *userData) { struct sound_info *si = userData; gensio_sound_ll_lock(si->soundll); si->soundll->do_close_now = true; gensio_sound_sched_deferred_op(si->soundll); gensio_sound_ll_unlock(si->soundll); } static unsigned int gensio_sound_pa_api_start_close(struct sound_info *si) { struct pa_sound_info *w = si->pinfo; unsigned int rv = 0; int err; if (si->is_input) return 0; /* Nothing to do to stop the input. */ if (!w->started) return 0; /* We haven't queued anything, not worth sending. */ if (w->len > 0) rv++; /* Data in our buffer to write. */ err = Pa_SetStreamFinishedCallback(w->stream, gensio_sound_pa_stream_finished); if (err) { rv = 0; Pa_AbortStream(w->stream); } else { rv++; } return rv; } static int gensio_sound_pa_api_write(struct sound_info *out, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen) { struct pa_sound_info *w = out->pinfo; gensiods count = 0, i, usize, psize, ppos; void (*convout)(const unsigned char **in, unsigned char **out, struct sound_cnv_info *info); unsigned char *obuf; gensiods obuflen = w->size - w->len; usize = out->cnv.usize; if (out->cnv.enabled) { psize = out->cnv.psize; convout = out->cnv.convout; } else { convout = gensio_sound_pa_copy_sample; psize = usize; } ppos = w->pos + w->len; if (ppos >= w->size) ppos -= w->size; obuf = out->cnv.buf + ppos; for (i = 0; obuflen > 0 && i < sglen; i++) { const unsigned char *ibuf = sg[i].buf; gensiods ibuflen = sg[i].buflen; while (ibuflen > 0 && obuflen > 0) { convout(&ibuf, &obuf, &out->cnv); obuflen -= psize; ibuflen -= usize; w->len += psize; ppos += psize; if (ppos >= w->size) { ppos = 0; obuf = out->cnv.buf; } count += usize; } } /* Is there a buffer's worth of free space to write? */ out->ready = w->size - w->len >= out->bufsize * out->cnv.pframesize; /* Wait until we have two buffers before starting the sender. */ if (!w->started && w->len > out->bufsize * out->cnv.pframesize * 2) { PaError perr; w->started = true; perr = Pa_StartStream(w->stream); if (perr) return gensio_pa_err_to_err(out->soundll->o, perr); } if (rcount) *rcount = count; return 0; } static int gensio_sound_pa_stream_cb(const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData) { struct sound_info *si = userData; struct pa_sound_info *w = si->pinfo; gensiods datalen = frameCount * si->cnv.pframesize; gensiods ppos, to_copy; const unsigned char *inbuf; unsigned char *outbuf; gensio_sound_ll_lock(si->soundll); if (si->is_input) { if (w->len + datalen > w->size) /* Not enough room, just drop it. */ goto out_unlock; inbuf = input; ppos = w->pos + w->len; /* Place to put new data. */ if (ppos >= w->size) ppos -= w->size; outbuf = si->cnv.buf + ppos; if (ppos + datalen > w->size) { to_copy = w->size - ppos; memcpy(outbuf, inbuf, to_copy); w->len += to_copy; datalen -= to_copy; inbuf += to_copy; outbuf = si->cnv.buf; } memcpy(outbuf, inbuf, datalen); w->len += datalen; gensio_sound_pa_process_read_buffer(si); } else { if (w->len < datalen) { /* Not enough room, just send zeros. */ memset(output, 0, datalen); goto out_unlock; } outbuf = output; inbuf = si->cnv.buf + w->pos; if (w->pos + datalen > w->size) { to_copy = w->size - w->pos; w->len -= datalen; memcpy(outbuf, inbuf, to_copy); datalen -= to_copy; w->pos = 0; outbuf = si->cnv.buf; inbuf += to_copy; } memcpy(output, inbuf, datalen); w->len -= datalen; w->pos += datalen; if (w->pos >= w->size) w->pos = 0; /* Is there a buffer's worth of free space to write? */ si->ready = w->size - w->len >= si->bufsize * si->cnv.pframesize; } gensio_sound_sched_deferred_op(si->soundll); out_unlock: gensio_sound_ll_unlock(si->soundll); return paContinue; } static int gensio_sound_pa_api_open_dev(struct sound_info *si) { struct gensio_os_funcs *o = si->soundll->o; struct pa_sound_info *w = si->pinfo; PaSampleFormat pa_fmt; enum gensio_sound_fmt_type pfmt; PaStreamParameters parms, *iparms = NULL, *oparms = NULL; const PaStreamInfo *streaminfo; int err; PaError perr; if (si->cnv.pfmt != GENSIO_SOUND_FMT_UNKNOWN) pfmt = si->cnv.pfmt; else pfmt = si->cnv.ufmt; err = gensio_sound_pa_get_wavefmt(pfmt, &pa_fmt); if (err) return err; memset(&parms, 0, sizeof(parms)); parms.device = w->devidx; parms.channelCount = si->chans; parms.sampleFormat = pa_fmt; parms.suggestedLatency = BASE_LATENCY; if (si->is_input) iparms = &parms; else oparms = &parms; si->cnv.pframesize = si->cnv.psize * si->chans; if (si->is_input) { w->size = si->num_bufs * si->bufsize * si->cnv.pframesize; si->cnv.buf = o->zalloc(o, w->size); } else { /* * For output buffers, we allocate two buffers worth of data * for our buffering. The rest of the buffering should happen * in portaudio. */ w->size = si->num_bufs * si->bufsize * si->cnv.pframesize; si->cnv.buf = o->zalloc(o, w->size); } if (!si->cnv.buf) return GE_NOMEM; w->len = 0; w->pos = 0; perr = Pa_OpenStream(&w->stream, iparms, oparms, si->samplerate, si->bufsize, 0, gensio_sound_pa_stream_cb, si); if (perr) { err = gensio_pa_err_to_err(o, perr); o->free(o, si->cnv.buf); si->cnv.buf = NULL; return err; } streaminfo = Pa_GetStreamInfo(w->stream); if (si->is_input) { w->latency = streaminfo->inputLatency; } else { w->latency = streaminfo->outputLatency; si->ready = true; } if (si->is_input) { perr = Pa_StartStream(w->stream); if (perr) { err = gensio_pa_err_to_err(o, perr); Pa_CloseStream(w->stream); w->stream = NULL; o->free(o, si->cnv.buf); si->cnv.buf = NULL; return err; } w->started = true; } return 0; } static PaDeviceIndex gensio_sound_pa_lookup_dev_by_name(char *name, bool is_input) { PaDeviceIndex i, ndevs; ndevs = Pa_GetDeviceCount(); for (i = 0; i < ndevs; i++) { const struct PaDeviceInfo *padev = Pa_GetDeviceInfo(i); char tstr[100]; if (!padev) continue; if (is_input && padev->maxInputChannels == 0) continue; if (!is_input && padev->maxOutputChannels == 0) continue; snprintf(tstr, sizeof(tstr), "%d:%s", i, padev->name); if (strstr(tstr, name)) return i; } return -1; } static int gensio_sound_pa_api_setup(struct gensio_pparm_info *p, struct sound_info *si, struct gensio_sound_info *io) { struct gensio_os_funcs *o = si->soundll->o; struct pa_sound_info *w = NULL; int err; PaError pa_err; pa_err = Pa_Initialize(); if (pa_err) { err = gensio_pa_err_to_err(o, pa_err); return err; } si->cardname = gensio_strdup(o, io->devname); if (!si->cardname) goto out_nomem; w = o->zalloc(o, sizeof(struct pa_sound_info)); if (!w) goto out_nomem; si->pinfo = w; w->devidx = gensio_sound_pa_lookup_dev_by_name(si->cardname, si->is_input); if (w->devidx == -1) { err = GE_NOTFOUND; goto out_err; } return 0; out_nomem: err = GE_NOMEM; out_err: if (si->cardname) { o->free(o, si->cardname); si->cardname = NULL; } if (w) { si->pinfo = NULL; o->free(o, w); } Pa_Terminate(); return err; } static void gensio_sound_pa_api_cleanup(struct sound_info *si) { struct gensio_os_funcs *o = si->soundll->o; struct pa_sound_info *w = si->pinfo; gensio_sound_pa_api_close_dev(si); if (w) { o->free(o, w); si->pinfo = NULL; } Pa_Terminate(); } static int gensio_sound_pa_api_devices(struct gensio_os_funcs *o, char ***rnames, char ***rspecs, gensiods *rcount) { gensiods count = 0, size = 0; PaDeviceIndex i, ndevs; char **names = NULL, **specs = NULL; char *name = NULL, *spec = NULL; int err; PaError pa_err; pa_err = Pa_Initialize(); if (pa_err) { err = gensio_pa_err_to_err(o, pa_err); return err; } ndevs = Pa_GetDeviceCount(); names = calloc(ndevs, sizeof(char *)); if (!names) goto out_nomem; specs = calloc(ndevs, sizeof(char *)); if (!specs) goto out_nomem; for (i = 0; i < ndevs; i++) { const struct PaDeviceInfo *padev = Pa_GetDeviceInfo(i); char tstr[100]; if (!padev) { err = GE_INCONSISTENT; goto out_err; } snprintf(tstr, sizeof(tstr), "%d:%s", i, padev->name); name = strdup(tstr); if (!name) goto out_nomem; if (padev->maxInputChannels && padev->maxOutputChannels) snprintf(tstr, sizeof(tstr), "input,inchans=%d,output,outchans=%d", padev->maxInputChannels, padev->maxOutputChannels); else if (padev->maxInputChannels) snprintf(tstr, sizeof(tstr), "input,inchans=%d", padev->maxInputChannels); else if (padev->maxOutputChannels) snprintf(tstr, sizeof(tstr), "output,outchans=%d", padev->maxOutputChannels); else tstr[0] = '\0'; spec = strdup(tstr); if (!spec) goto out_nomem; if (count >= size) { if (extend_sound_devs(&names, &specs, &size)) goto out_nomem; } names[count] = name; name = NULL; specs[count] = spec; spec = NULL; count++; } *rnames = names; *rspecs = specs; *rcount = count; Pa_Terminate(); return 0; out_nomem: err = GE_NOMEM; out_err: if (name) free(name); if (spec) free(spec); gensio_sound_devices_free(names, specs, count); Pa_Terminate(); return err; } static struct sound_type pa_sound_type = { "portaudio", .setup = gensio_sound_pa_api_setup, .cleanup = gensio_sound_pa_api_cleanup, .open_dev = gensio_sound_pa_api_open_dev, .close_dev = gensio_sound_pa_api_close_dev, .write = gensio_sound_pa_api_write, .set_write_enable = gensio_sound_pa_api_set_write, .set_read_enable = gensio_sound_pa_api_set_read, .next_read = gensio_sound_pa_api_next_read, .start_close = gensio_sound_pa_api_start_close, .drain_count = gensio_sound_pa_drain_count, .devices = gensio_sound_pa_api_devices }; #define PORTAUDIO_INIT &pa_sound_type, gensio-3.0.0/lib/gensio_ax25.c0000664000175000017500000044054715061042505011532 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2021 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* * This is an implementation of the AX25 protocol, sort of 2.0 and * sort of 2.2, available at http://www.ax25.net. * * It's not a full 2.2 implementation because parts of the protocol * are almost unimplementable. I don't see how the * segmentation/reassembly could possibly work as described. * * This code does implement the extended sequence numbers (SABME) from * that spec. XID is implemented, but it's stupid. Really. The * SABME should carry the information needed to negotiate the various * parameters. 4 bytes would be plenty. So this code implements a * extra data field to tell the remote end about the max message size * and windows, if extended2 is enabled. If it gets a FRMR back from * the remote end, it falls back to SABME. If not enabled (the * default) it will send a normal SABME, In both cases if it gets a * FRMR from a normal SABME it will fall back to 3-bit sequence * numbers. * * The extended2 extra data is carried on SABME and UA responses to * SABME. It has the following format: * byte 0 - The maximum receive window. bit 7 is reserved and should be * zero. This will be used to enable SREJ. * byte 1 - The upper 8 bits of the maximum message size. * byte 2 - The lower 8 bits of the maximum message size. * byte 3 - Unused flags, should all be zero. * * This code does not currently send an SREJ. That's pretty * complicated, but could be valuable in some situations. This may be * added in the future. It will handle a received SREJ. * * Flow-control enable/disable is not done immediately, it is delayed * until an ack is sent. That way momentary enable/disable operations * won't result in a ton of unnecessary traffic. * * In the 2.2 spec the flow-control handling appears to be broken. If * in own receive busy and that is cleared, it sends an RR command * with P=1. However, the response to that (RR response with F=1) is * only properly handled in timer recovery state, and the state * machines don't go there in this case. And if they did, that could * result in unnecessary data retransmission in the opposite direction * on handling the RR response with F=1. The way the Linux stack * handles this is to send an normal RR response with F=0, that's what * this code does, too. But if that RR gets missed, that could result * in a stalemate until t3 goes off, which could be a long time. The * only reasonable solution I could see was to go into timer recovery * when this happens and live with the retransmits. * * It seems wrong that a REJ clears peer receive busy in the spec. * Only an RR should do that. This implementation does not do that. * * Both REJ and SREJ stop T1 and T3 and do not start a new timer, but * there's no way that's right. My guess is that * invoke_retransmission should start T1, so that's what this code * does. * * In the spec, SREJ in connected state starts T3, but it should stop * T3. * * There is nothing in the spec that resets the RC value to zero. * That should happen when going from timer recover to connected * state. * * The spec says to never set the P bit on I frames, but that's kind * of crazy. This implementation sets the P bit when sending the * packet that closes it's transmit window. * * When checking the sequence numbers for sending a REJ, the sequence * number must be in the current receive window. Otherwise an message * from an old resend can result in in_rej being set, but never having * anything to clear it. * * Don't recalculate t1 on a disconnect. If the other end is no * longer available, it can make the shutdown painfully slow. Just * stuck with the t1 value that we were at when the disconnect * starts. * * There are some layer 3 interactions that this code does differently * than the spec. It will never re-initialize a connection if it lost * data. Any significant protocol error will cause the code to shut * down the connection and let the user decide what to do. If the * code gets a SABM[E] before it has transferred any data, it will * just pretend the previous SABM[E] didn't occur and use the last * one, to help in situations where two systems come up at the same * time. * * When a connection is closed, the code here has a wait drain state * that waits for all transmitted data to be acked. That's pretty * important for sane usage. However, this can result in a delay on * close, since it has to wait for the ack from the other end for the * last data sent. To expedite this process, in this case the code * goes into timer recovery to get a quick response, which is a bit of * an abuse of that state. * * X.25 is really far too complicated. You can implement a good * protocol with four messages. There is no need for an RNR, you can * just use the windows to do flow control, like TCP does. There * should be a version number in the SABME command to allow backwards * compatibility. The whole timer recovery and P/F bit thing is a * mess of complexity. The command/response bits are silly. The * SABME should have a command/response bit in it instead of relying * on a UA to ack it. Same with DISC. I could go on. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef DEBUG_DATA #define ENABLE_PRBUF 1 #include "utils.h" #endif #include "crc.h" enum x25_cmds { X25_SABME = 0x6f, X25_SABM = 0x2f, X25_DISC = 0x43, X25_DM = 0x0f, X25_UA = 0x63, X25_FRMR = 0x87, X25_UI = 0x03, X25_XID = 0xaf, X25_TEST = 0xe3, X25_I = 0x00, X25_RR = 0x01, X25_RNR = 0x05, X25_REJ = 0x09, X25_SREJ = 0x0d /* Receive side implemented. */ }; enum ax25_base_state { /* * All channels are closed, child is closed. * * free of last chan -> free * open chan -> AX25_BASE_IN_LL_OPEN */ AX25_BASE_CLOSED = 50, /* * We have requested that our child open, but have not received the * confirmation yet. * * child open done (err) -> AX25_BASE_CLOSED, fail close all chans * child open done -> AX25_BASE_OPEN, start chan opens * if all chan opens fail ->AX25_BASE_CLOSED */ AX25_BASE_IN_CHILD_OPEN, /* * The child is open, at least one chan is not closed. * * last chan closed -> AX25_BASE_IN_CHILD_CLOSE * io err -> AX25_BASE_IN_CHILD_IO_ERR_CLOSE */ AX25_BASE_OPEN, /* * A close has been requested, but there is still base data to send. */ AX25_BASE_CLOSE_WAIT_DRAIN, /* * All chans closed, waiting for the child to close * * child close && chans waiting open -> AX25_BASE_IN_CHILD_OPEN * child close && no chans waiting open -> AX25_BASE_CLOSED */ AX25_BASE_IN_CHILD_CLOSE, /* * An I/O error occurred, waiting for the close from the child * * child close && all chans closed -> AX25_BASE_CLOSED */ AX25_BASE_CHILD_IO_ERR, }; /* * Events: * child_write_ready * child_read * child_open_done * child_close_done * write * open * close * free */ enum ax25_chan_state { /* * gensio is closed, either at initial startup after close is * complete. * * chan open && base not open -> start base open if close && * AX25_CHAN_WAITING_OPEN * chan open && base open -> start open && AX25_CHAN_IN_OPEN */ AX25_CHAN_CLOSED = 100, /* * We have requested that our child open, but have not received the * confirmation yet. * * base open success -> start open && AX25_CHAN_IN_OPEN * close -> if all chans close start base close && * start runner && AX25_CHAN_REPORT_CLOSE * base open fails -> AX25_CHAN_CLOSED && report open errors */ AX25_CHAN_WAITING_OPEN, /* * We have started the open process. * * open done -> AX25_CHAN_OPEN * close -> start close && AX25_CHAN_REPORT_CLOSE * remote close -> report open error && AX25_CHAN_CLOSED * io err -> report open error && AX25_CHAN_CLOSED */ AX25_CHAN_IN_OPEN, /* * gensio is operational * * close && write data pending -> AX25_CHAN_CLOSE_WAIT_DRAIN * close && no write data pending -> AX25_CHAN_IN_CLOSE * remote close -> AX25_CHAN_REM_DISC * io err -> AX25_CHAN_IO_ERR */ AX25_CHAN_OPEN, /* * A close has been requested, but we have write data to deliver. * * All data written -> start close && AX25_CHAN_IN_CLOSE * io err -> report close && AX25_CHAN_CLOSED * remote close -> AX25_CHAN_REPORT_CLOSE */ AX25_CHAN_CLOSE_WAIT_DRAIN, /* * A close has finished and needs to be reported. It may be in a * callback, or it may be waiting for the base to close if it's the * last channel. An open with an error may be pending, too, just * do that at first opportunity if open_done is set. * * close done -> report close && AX25_CHAN_CLOSED * io err -> report close && AX25_CHAN_CLOSED */ AX25_CHAN_IN_CLOSE, /* * A disconnect has been received, we need to transmit the UA * and shut down. * * close -> report close && AX25_CHAN_IN_CLOSE * io err -> report close && AX25_CHAN_CLOSED * ua sent -> report close && AX25_CHAN_CLOSED */ AX25_CHAN_REM_DISC, /* * A disconnect has been received and then a close was requested, * we need to transmit the UA and close * * io err -> report close && AX25_CHAN_CLOSED * ua sent -> report close && AX25_CHAN_CLOSED */ AX25_CHAN_REM_CLOSE, /* * A close has been requested finished and needs to be reported in the runner. * * runner -> report close && AX25_CHAN_CLOSED * io err -> report close && AX25_CHAN_CLOSED */ AX25_CHAN_REPORT_CLOSE, /* * An I/O error happened on AX25_CHAN_OPEN, waiting close call. * * close -> AX25_CHAN_REPORT_CLOSE * another io err should be ignored */ AX25_CHAN_IO_ERR, /* * The channel has no address and just receives/sends UI frames. */ AX25_CHAN_NOCON_IN_OPEN, AX25_CHAN_NOCON, }; #ifdef ENABLE_INTERNAL_TRACE #define DEBUG_STATE #endif struct ax25_chan; struct ax25_base; #ifdef DEBUG_STATE enum ax25_base_trace_type { AX25_TRACE_BASE_STATE, AX25_TRACE_CHAN_STATE, AX25_TRACE_BASE_LOCK, AX25_TRACE_BASE_UNLOCK, AX25_TRACE_CHAN_LOCK, AX25_TRACE_CHAN_UNLOCK, AX25_TRACE_BASE_REF, AX25_TRACE_BASE_DEREF, AX25_TRACE_CHAN_REF, AX25_TRACE_CHAN_DEREF, AX25_TRACE_OTHER }; struct ax25_base_state_trace { enum ax25_base_trace_type type; union { struct { enum ax25_base_state old_state; enum ax25_base_state new_state; } ax25_base_state; struct { enum ax25_chan_state old_state; enum ax25_chan_state new_state; } ax25_chan_state; int oinfo; } u; unsigned int line; }; #define STATE_TRACE_LEN 1024 static void i_ax25_base_add_lock(struct ax25_base *base, int line); static void i_ax25_base_add_other(struct ax25_base *base, enum ax25_base_trace_type type, int other, int line); static void i_ax25_base_lock_add_other(struct ax25_base *base, enum ax25_base_trace_type type, int other, int line); #else #define i_ax25_base_add_lock(base, line) #define i_ax25_base_add_unlock(base, line) #define i_ax25_base_add_other(base, type, other, line) #define i_ax25_base_lock_add_other(base, type, other, line) #define i_ax25_chan_lock_add_lock(chan, line) #define i_ax25_chan_lock_add_unlock(chan, line) #endif /* * LOCKING INFORMATION * * The code has three locks: the base lock and the channel lock. The * base lock protects the base data strutures, primarily the list of * channels. The channel lock is per-channel and protects the channel * information. * * If you hold a channel lock, you may lock the base lock. They both * may be locked independently, but if you have the base locked, you * cannot lock a channel lock, because you risk deadlock. When calls * come in from the user, you would claim the channel lock first. But * when something comes from the lower layer, it has to claim the base * lock so it can search the channels and find which one to use. But * if it releases the base lock and claims the channel lock, there is * a chance the channel can be deleted in this time. * * The refcounts are atomics, and you do not need any locks held to * modify them. So the channel refcount can be incremented while * holding the base lock if the refcount is not already zero. If the * refcount is already zero, the channel can be ignored. This will * keep the channel from being deleted when the base lock is released. * * This is solved by creating a way that, when the base lock is held, * a channel will be refcounted to keep it around. Then the base lock * is released and the channel lock is grabbed. Then the channel * checked to make sure it is still in a good state, and just derefs * it if it's not. * * When a message comes in from the remote (the child read), and in a * few other circumstances, the code must claim the base lock in order * to search the lists and find the channel involved. It refcounts * the channels then releases the base lock. It calls a function that * locks the channel and checks to make sure the channel is in the * proper state. If it is not, the channel is deref-ed and ignored. * If it is in the proper state, the channel is returned. The user * must deref the channel after done. * * Unnumbered information (UI), opens, and error adds another twist * because they need to be able to process multiple channels. Each of * these has their own link in the channel data, all the channels are * collected into a list and marked, the base lock is released, and * each channel is handled individually. */ struct ax25_base_cmdrsp { unsigned char addr[AX25_ADDR_MAX_ENCODED_LEN]; uint8_t addrlen; uint8_t cr; uint8_t crlen; uint8_t extra_data_size; unsigned char extra_data[4]; }; #define AX25_BASE_MAX_CMDRSP 16 struct ax25_conf_data { gensiods max_read_size; gensiods max_write_size; unsigned int readwindow; unsigned int writewindow; bool writewindow_set; unsigned int srtv; unsigned int t2v; unsigned int t3v; unsigned int max_retries; unsigned int extended; unsigned int pid; bool do_crc; bool ignore_embedded_ua; struct gensio_ax25_subaddr *conf_laddrs; unsigned int num_conf_laddrs; struct gensio_addr *addr; unsigned int drop_pos; /* Addresses we listen for UIs from. */ struct gensio_ax25_subaddr *conf_uiaddrs; unsigned int num_conf_uiaddrs; /* Report senders of all packets? */ bool report_heard; /* Report all raw packets? */ bool report_raw; /* Add timestamps to messages. */ #define GENSIO_AX25_DEBUG_TIME 0x10 /* Dump full received/sent messages. */ #define GENSIO_AX25_DEBUG_MSG 0x08 /* Debug flags. */ unsigned int debug; }; struct ax25_base { struct gensio_os_funcs *o; struct gensio_lock *lock; /* If we came from an accepter. */ struct gensio_accepter *accepter; enum ax25_base_state state; bool locked; /* * When opened as an accepter, this says to take the first channel * that's already there and use it for the first connection coming * in. */ bool waiting_first_open; /* * When closing the base, this will be set to the last channel * that closed that cause the base to close. The close of that * channel will be delayed until the base closes. */ struct ax25_chan *closing_chan; struct ax25_conf_data conf; struct gensio_lock *addrlock; struct gensio_list listen_addrs; /* A channel will be in one of the following 3 lists, link element. */ /* Channels that are in closed, report close, or io error state */ struct gensio_list chans_closed; /* Channels that are waiting open */ struct gensio_list chans_waiting_open; /* Channels in all other states, they can receive messages. */ struct gensio_list chans; /* * If a channel has data to write, it will be in this, linksend element. */ struct gensio_list send_list; /* A queue of commands/responses to send not associated with a channel. */ struct ax25_base_cmdrsp cmdrsp[AX25_BASE_MAX_CMDRSP]; uint8_t cmdrsp_pos; uint8_t cmdrsp_len; struct gensio *child; gensio_refcount refcount; /* Transfer data to the deferred open. */ int open_err; /* Marks that we had an error on the child. */ int child_err; /* Are there any raw reporting channels? */ bool have_raw; #ifdef DEBUG_STATE struct gensio_lock *trace_lock; struct ax25_base_state_trace state_trace[STATE_TRACE_LEN]; unsigned int state_trace_pos; #endif }; struct ax25_iaddr { struct gensio_link link; struct gensio_ax25_subaddr addr; }; #define to_ax25_iaddr(l) gensio_container_of(l, struct ax25_iaddr, link) static int ax25_add_iaddr(struct gensio_os_funcs *o, struct gensio_list *list, struct gensio_ax25_subaddr *addr) { struct ax25_iaddr *l = o->zalloc(o, sizeof(*l)); if (!l) return GE_NOMEM; l->addr = *addr; gensio_list_add_tail(list, &l->link); return 0; } static int ax25_del_iaddr(struct gensio_os_funcs *o, struct gensio_list *list, struct gensio_ax25_subaddr *addr) { struct gensio_link *l, *l2; int rv = GE_NOTFOUND; gensio_list_for_each_safe(list, l, l2) { struct ax25_iaddr *iaddr = to_ax25_iaddr(l); if (ax25_subaddr_equal(addr, &iaddr->addr)) { gensio_list_rm(list, l); o->free(o, iaddr); rv = 0; break; } } return rv; } static bool ax25_iaddr_find(struct gensio_list *list, struct gensio_ax25_subaddr *addr) { struct gensio_link *l; gensio_list_for_each(list, l) { struct ax25_iaddr *iaddr = to_ax25_iaddr(l); if (ax25_subaddr_equal(addr, &iaddr->addr)) return true; } return false; } static int ax25_free_iaddr_list(struct gensio_os_funcs *o, struct gensio_list *list) { struct gensio_link *l, *l2; gensio_list_for_each_safe(list, l, l2) { struct ax25_iaddr *iaddr = to_ax25_iaddr(l); gensio_list_rm(list, l); o->free(o, iaddr); } return false; } struct ax25_data { unsigned char *data; uint16_t len; uint16_t pos; uint8_t seq; uint8_t present; uint8_t pid; }; struct ax25_raw_data { struct gensio_link link; uint16_t len; }; #define AX25_CHAN_MAX_CMDRSP_EXTRA 32 struct ax25_chan_cmdrsp { uint8_t cr; uint8_t pf; uint8_t is_cmd; uint8_t extra_data_size; unsigned char extra_data[AX25_CHAN_MAX_CMDRSP_EXTRA]; }; #define AX25_CHAN_MAX_CMDRSP 8 enum ax25_snd_rcv { SENT, RCVD }; #ifdef DEBUG_STATE struct ax25_chan_msgtrace { gensio_time time; enum ax25_snd_rcv type; bool is_cmd; unsigned char data[2]; bool in_rej; bool peer_rcv_bsy; bool own_rcv_bsy; uint8_t ack_pending; uint8_t orig_cmd; }; #define AX25_CHAN_NR_MSGTRACE 256 #endif struct ax25_chan { struct gensio_link link; struct gensio_os_funcs *o; struct ax25_base *base; bool locked; struct gensio_lock *lock; struct gensio *io; /* The gensio for this channel */ unsigned char encoded_addr[AX25_ADDR_MAX_ENCODED_LEN]; uint8_t encoded_addr_len; /* These are after negotiation. */ uint8_t readwindow; uint8_t writewindow; uint16_t max_write_size; unsigned int max_retries; unsigned int curr_drop; /* These are modified under the base lock, see locking info above. */ struct gensio_link hold_ui_link; struct gensio_link hold_open_link; struct gensio_link hold_err_link; struct gensio_link hold_count_link; /* Report UI frames to the upper layer? */ unsigned int report_ui; /* In a UI or heard or raw report? */ bool in_ui; int in_newchannel; int err; /* * The read_pos is the current next location to report to the * user, read_len is the number of packets in queue. * These wrap at readwindow. */ struct ax25_data *read_data; uint8_t read_pos; uint8_t read_len; bool in_read; /* * write_pos is the next message location the user can write. * write_len is the number of items in the queue, including ones * already sent but unacked, and ones not sent. Note that items * are not removed from this until they are acked. send_len is * the number of packets left to send, starting at write_pos - * send_len. These wrap at conf.writewindow. */ struct ax25_data *write_data; uint8_t write_pos; uint8_t write_len; uint8_t send_len; bool in_write; /* * This is seq# of the next frame to transmit. It corresponds to * write_pos. */ uint8_t vs; /* * This is the seq# of the next expected frame. It corresponds to * read_pos + read_len. */ uint8_t vr; /* * This is the last frame acknowledged by the remote side. vr - va * will fall within read_pos and read_pos + read_len. */ uint8_t va; /* A queue of commands/responses to send. */ struct ax25_chan_cmdrsp cmdrsp[AX25_CHAN_MAX_CMDRSP]; uint8_t cmdrsp_pos; uint8_t cmdrsp_len; /* List of unnumbered information packets to send. */ struct gensio_list raws; /* * Link for list of things waiting to write, for the base * send_list. The channel will be refcounted if it's in * send_list. */ struct gensio_link sendlink; enum ax25_chan_state state; /* * Note that we do not have a layer_3_initiated bool like the * standard does. If there is some protocol error, just shut the * connection down. That's a lot safer than dropping data in some * fashion. */ bool got_firstmsg; unsigned int extended; uint8_t modulo; bool peer_rcv_bsy; bool own_rcv_bsy; bool in_rej; uint8_t ack_pending; /* Number of rcv packets that haven't been acked. */ bool poll_pending; /* Timer recovery state. */ bool data_p_sent; /* Sent a P=1 in data. */ /* * SREJ is not currently implemented on the send side, just the receive. * uint8_t srej_count; */ struct ax25_conf_data conf; /* A list of addresses we listen for UI packets on. */ struct gensio_lock *ui_addr_lock; struct gensio_list ui_addrs; /* Current srt and t1 values, in milliseconds. */ unsigned int t1v; unsigned int srt; /* Absolute timeout values, in milliseconds. zero is diabled. */ int64_t t1; int64_t t2; int64_t t3; int64_t curr_timeout; unsigned int retry_count; struct gensio_timer *timer; gensio_refcount refcount; bool read_enabled; bool xmit_enabled; bool freed; gensio_done_err open_done; void *open_data; gensio_done close_done; void *close_data; /* * Used to run user callbacks from the selector to avoid running * it directly from user calls. * Refcount is 1 if the deferred op is not pending, it is zero if * pending. dec_if_nz is used to decrement it and know if the * deferred op needs to be started. */ gensio_refcount deferred_op_pending; struct gensio_runner *deferred_op_runner; #ifdef DEBUG_STATE struct ax25_chan_msgtrace msgtrace[AX25_CHAN_NR_MSGTRACE]; unsigned int msgtrace_pos; #endif }; static void ax25_chan_trace_msg(struct ax25_chan *chan, int type, bool is_cmd, uint8_t orig_cmd, unsigned char *data, unsigned int len) { #ifdef DEBUG_STATE unsigned int pos = chan->msgtrace_pos++, i; struct ax25_chan_msgtrace *t = &(chan->msgtrace[pos]); chan->o->get_monotonic_time(chan->o, &t->time); t->type = type; t->is_cmd = is_cmd; if (len > sizeof(t->data)) len = sizeof(t->data); memcpy(t->data, data, len); for (i = len; i < sizeof(t->data); i++) t->data[i] = 0; t->in_rej = chan->in_rej; t->peer_rcv_bsy = chan->peer_rcv_bsy; t->own_rcv_bsy = chan->own_rcv_bsy; t->ack_pending = chan->ack_pending; t->orig_cmd = orig_cmd; if (chan->msgtrace_pos >= AX25_CHAN_NR_MSGTRACE) chan->msgtrace_pos = 0; #endif } static int i_ax25_base_child_close_done(struct ax25_base *base); static void ax25_base_child_close_done(struct gensio *child, void *open_data); static void ax25_chan_sched_deferred_op(struct ax25_chan *chan); static int ax25_base_start_open(struct ax25_base *base); static void ax25_chan_prestart_connect(struct ax25_chan *chan); static void ax25_chan_start_connect(struct ax25_chan *chan); static int ax25_chan_alloc(struct ax25_base *base, const char *const args[], gensio_event cb, void *user_data, enum ax25_chan_state start_state, struct gensio_addr *addr, bool firstchan, struct ax25_chan **rchan); static void ax25_chan_start_t1(struct ax25_chan *chan); static void ax25_chan_stop_t1(struct ax25_chan *chan); static void ax25_chan_start_t2(struct ax25_chan *chan); static void ax25_chan_stop_t2(struct ax25_chan *chan); static void ax25_chan_start_t3(struct ax25_chan *chan); static void ax25_chan_stop_t3(struct ax25_chan *chan); static void ax25_chan_send_cmd(struct ax25_chan *chan, uint8_t cmd, uint8_t pf); static void ax25_chan_send_rsp(struct ax25_chan *chan, uint8_t cmd, uint8_t pf); static void ax25_stop_timer(struct ax25_chan *chan); static void ax25_chan_reset_data(struct ax25_chan *chan); /* * base locking and refcounting. */ static void i_ax25_base_lock(struct ax25_base *base) { base->o->lock(base->lock); base->locked = true; } #define ax25_base_lock(base) do { \ i_ax25_base_lock((base)); \ i_ax25_base_add_lock(base, __LINE__); \ } while(false) static void i_ax25_base_unlock(struct ax25_base *base) { base->locked = false; base->o->unlock(base->lock); } #define ax25_base_unlock(base) do { \ i_ax25_base_add_unlock(base, __LINE__); \ i_ax25_base_unlock((base)); \ } while(false) #ifdef DEBUG_STATE static void i_ax25_base_trace_lock(struct ax25_base *base) { base->o->lock(base->trace_lock); } static void i_ax25_base_trace_unlock(struct ax25_base *base) { base->o->unlock(base->trace_lock); } #endif static void i_ax25_base_ref(struct ax25_base *base, int line) { gensio_refcount_inc(&base->refcount); i_ax25_base_add_other(base, AX25_TRACE_BASE_REF, gensio_refcount_get(&base->refcount), line); } #define ax25_base_ref(base) i_ax25_base_ref((base), __LINE__) static void i_ax25_base_lock_and_ref(struct ax25_base *base, int line) { i_ax25_base_lock(base); i_ax25_base_ref(base, line); } #define ax25_base_lock_and_ref(base) i_ax25_base_lock_and_ref((base), __LINE__) /* * This can *only* be called if the refcount is guaranteed not to reach * zero. */ static void i_ax25_base_deref(struct ax25_base *base, int line) { i_ax25_base_add_other(base, AX25_TRACE_BASE_DEREF, gensio_refcount_get(&base->refcount), line); gensio_refcount_dec(&base->refcount); } #define ax25_base_deref(base) i_ax25_base_deref((base), __LINE__) static void ax25_addr_lock(struct ax25_base *base) { base->o->lock(base->addrlock); } static void ax25_addr_unlock(struct ax25_base *base) { base->o->unlock(base->addrlock); } static void ax25_ui_addr_lock(struct ax25_chan *chan) { chan->o->lock(chan->ui_addr_lock); } static void ax25_ui_addr_unlock(struct ax25_chan *chan) { chan->o->unlock(chan->ui_addr_lock); } static void ax25_cleanup_conf(struct gensio_os_funcs *o, struct ax25_conf_data *conf) { if (conf->conf_laddrs) o->free(o, conf->conf_laddrs); if (conf->conf_uiaddrs) o->free(o, conf->conf_uiaddrs); if (conf->addr) gensio_addr_free(conf->addr); } static void ax25_base_finish_free(struct ax25_base *base) { ax25_cleanup_conf(base->o, &base->conf); ax25_free_iaddr_list(base->o, &base->listen_addrs); if (base->lock) base->o->free_lock(base->lock); #ifdef DEBUG_STATE if (base->trace_lock) base->o->free_lock(base->trace_lock); #endif if (base->addrlock) base->o->free_lock(base->addrlock); if (base->child) gensio_free(base->child); gensio_refcount_cleanup(&base->refcount); base->o->free(base->o, base); } static void i_ax25_base_deref_and_unlock(struct ax25_base *base, int line) { unsigned int count; i_ax25_base_add_other(base, AX25_TRACE_BASE_DEREF, gensio_refcount_get(&base->refcount), line); count = gensio_refcount_dec(&base->refcount); i_ax25_base_unlock(base); if (count == 0) ax25_base_finish_free(base); } #define ax25_base_deref_and_unlock(base) i_ax25_base_deref_and_unlock((base), \ __LINE__) /* * chan locking and refcounting. */ static void i_ax25_chan_lock(struct ax25_chan *chan) { chan->o->lock(chan->lock); chan->locked = true; } #define ax25_chan_lock(chan) do { \ i_ax25_chan_lock((chan)); \ i_ax25_chan_lock_add_lock(chan, __LINE__); \ } while(false) static void i_ax25_chan_unlock(struct ax25_chan *chan) { assert(chan->locked); chan->locked = false; chan->o->unlock(chan->lock); } #define ax25_chan_unlock(chan) do { \ i_ax25_chan_lock_add_unlock(chan, __LINE__); \ i_ax25_chan_unlock((chan)); \ } while(false) static void ax25_chan_finish_free(struct ax25_chan *chan, bool baselocked) { struct ax25_base *base = chan->base; struct gensio_os_funcs *o = chan->o; unsigned int i; if (chan->io) gensio_data_free(chan->io); if (base) ax25_free_iaddr_list(base->o, &chan->ui_addrs); if (chan->ui_addr_lock) o->free_lock(chan->ui_addr_lock); if (chan->read_data) { for (i = 0; i < chan->conf.readwindow; i++) { if (chan->read_data[i].data) o->free(o, chan->read_data[i].data); } o->free(o, chan->read_data); } if (chan->write_data) { for (i = 0; i < chan->conf.writewindow; i++) { if (chan->write_data[i].data) o->free(o, chan->write_data[i].data); } o->free(o, chan->write_data); } if (base) { if (!baselocked) ax25_base_lock(base); if (gensio_list_link_inlist(&chan->sendlink)) gensio_list_rm(&base->send_list, &chan->sendlink); gensio_list_rm(&base->chans_closed, &chan->link); if (baselocked) ax25_base_deref(base); else ax25_base_deref_and_unlock(base); } ax25_cleanup_conf(o, &chan->conf); if (chan->lock) o->free_lock(chan->lock); if (chan->timer) o->free_timer(chan->timer); gensio_refcount_cleanup(&chan->deferred_op_pending); if (chan->deferred_op_runner) o->free_runner(chan->deferred_op_runner); gensio_refcount_cleanup(&chan->refcount); o->free(o, chan); } static void i_ax25_chan_ref(struct ax25_chan *chan, int line) { gensio_refcount_inc(&chan->refcount); i_ax25_base_lock_add_other(chan->base, AX25_TRACE_CHAN_REF, gensio_refcount_get(&chan->refcount), line); } #define ax25_chan_ref(chan) i_ax25_chan_ref((chan), __LINE__) static bool i_ax25_chan_ref_if_nz(struct ax25_chan *chan, int line) { bool rv = gensio_refcount_inc_if_nz(&chan->refcount); i_ax25_base_lock_add_other(chan->base, AX25_TRACE_CHAN_REF, gensio_refcount_get(&chan->refcount), line); return rv; } #define ax25_chan_ref_if_nz(chan) i_ax25_chan_ref_if_nz((chan), __LINE__) static void i_ax25_chan_lock_and_ref(struct ax25_chan *chan, int line) { i_ax25_chan_lock(chan); i_ax25_chan_ref(chan, line); } #define ax25_chan_lock_and_ref(chan) i_ax25_chan_lock_and_ref((chan), __LINE__) /* * This can *only* be called if the refcount is guaranteed not to reach * zero. */ static void i_ax25_chan_deref(struct ax25_chan *chan, int line) { i_ax25_base_lock_add_other(chan->base, AX25_TRACE_CHAN_DEREF, gensio_refcount_get(&chan->refcount), line); assert(gensio_refcount_dec(&chan->refcount) > 0); } #define ax25_chan_deref(chan) i_ax25_chan_deref((chan), __LINE__) static void i_ax25_chan_deref_and_unlock(struct ax25_chan *chan, int line) { struct ax25_base *base = chan->base; assert(chan->locked); i_ax25_base_lock_add_other(base, AX25_TRACE_CHAN_DEREF, gensio_refcount_get(&chan->refcount), line); if (gensio_refcount_dec(&chan->refcount) == 0) { assert(chan->freed); i_ax25_base_lock(base); i_ax25_base_unlock(base); i_ax25_chan_unlock(chan); ax25_chan_finish_free(chan, false); } else { i_ax25_chan_unlock(chan); } } #define ax25_chan_deref_and_unlock(chan) i_ax25_chan_deref_and_unlock((chan), __LINE__) #ifdef DEBUG_STATE static void i_ax25_base_finish_trace(struct ax25_base *base, enum ax25_base_trace_type type, unsigned int line) { struct ax25_base_state_trace *t; t = &(base->state_trace[base->state_trace_pos]); memset(t, 0, sizeof(*t)); t->type = type; t->line = line; if (base->state_trace_pos == STATE_TRACE_LEN - 1) base->state_trace_pos = 0; else base->state_trace_pos++; } /* Set the state with only the channel locked, not base. */ static void i_ax25_chan_set_state(struct ax25_chan *chan, enum ax25_chan_state new_state, int line) { struct ax25_base *base = chan->base; struct ax25_base_state_trace *t; assert(chan->locked); i_ax25_base_trace_lock(base); t = &(base->state_trace[base->state_trace_pos]); i_ax25_base_finish_trace(base, AX25_TRACE_CHAN_STATE, line); t->u.ax25_chan_state.old_state = chan->state; t->u.ax25_chan_state.new_state = new_state; i_ax25_base_trace_unlock(base); chan->state = new_state; } #define ax25_chan_set_state(chan, state) \ i_ax25_chan_set_state(chan, state, __LINE__) static void i_ax25_base_set_state(struct ax25_base *base, enum ax25_base_state new_state, int line) { struct ax25_base_state_trace *t; assert(base->locked); i_ax25_base_trace_lock(base); t = &(base->state_trace[base->state_trace_pos]); i_ax25_base_finish_trace(base, AX25_TRACE_BASE_STATE, line); t->u.ax25_base_state.old_state = base->state; t->u.ax25_base_state.new_state = new_state; base->state = new_state; i_ax25_base_trace_unlock(base); } #define ax25_base_set_state(base, state) \ i_ax25_base_set_state(base, state, __LINE__) static void i_ax25_chan_lock_add_lock(struct ax25_chan *chan, int line) { struct ax25_base *base = chan->base; i_ax25_base_trace_lock((chan)->base); i_ax25_base_finish_trace(base, AX25_TRACE_CHAN_LOCK, line); i_ax25_base_trace_unlock((chan)->base); } static void i_ax25_chan_lock_add_unlock(struct ax25_chan *chan, int line) { struct ax25_base *base = chan->base; i_ax25_base_trace_lock((chan)->base); i_ax25_base_finish_trace(base, AX25_TRACE_CHAN_UNLOCK, line); i_ax25_base_trace_unlock((chan)->base); } static void i_ax25_base_add_lock(struct ax25_base *base, int line) { i_ax25_base_trace_lock(base); i_ax25_base_finish_trace(base, AX25_TRACE_BASE_LOCK, line); i_ax25_base_trace_unlock(base); } static void i_ax25_base_add_unlock(struct ax25_base *base, int line) { i_ax25_base_trace_lock(base); i_ax25_base_finish_trace(base, AX25_TRACE_BASE_UNLOCK, line); i_ax25_base_trace_unlock(base); } static void i_ax25_base_add_other(struct ax25_base *base, enum ax25_base_trace_type type, int other, int line) { struct ax25_base_state_trace *t; i_ax25_base_trace_lock(base); t = &(base->state_trace[base->state_trace_pos]); i_ax25_base_finish_trace(base, type, line); t->u.oinfo = other + 1000; i_ax25_base_trace_unlock(base); } static void i_ax25_base_lock_add_other(struct ax25_base *base, enum ax25_base_trace_type type, int other, int line) { struct ax25_base_state_trace *t; i_ax25_base_trace_lock(base); t = &(base->state_trace[base->state_trace_pos]); i_ax25_base_finish_trace(base, type, line); t->u.oinfo = other + 1000; i_ax25_base_trace_unlock(base); } #else static void ax25_chan_set_state(struct ax25_chan *chan, enum ax25_chan_state state) { chan->state = state; } static void ax25_base_set_state(struct ax25_base *base, enum ax25_base_state state) { base->state = state; } #endif /* * Message printing handling, for debugging. */ static int decode_ax25_control_field(char *str, size_t strlen, unsigned char *buf, unsigned int buflen) { static char *sname[4] = { "RR", "RNR", "REJ", "SREJ" }; static char *uname[32] = { [0x0f] = "SABME", [0x07] = "SABM", [0x08] = "DISC", [0x03] = "DM", [0x0c] = "UA", [0x11] = "FRMR", [0x00] = "UI", [0x17] = "XID", [0x1c] = "TEST" }; if ((*buf & 1) == 0) { /* I frame. */ snprintf(str, strlen, "I p=%d nr=%d ns=%d", (*buf >> 4) & 1, (*buf >> 5) & 0x7, (*buf >> 1) & 0x7); } else if ((*buf & 0x3) == 1) { /* S frame */ snprintf(str, strlen, "%s pf=%d nr=%d", sname[(*buf >> 2) & 0x3], (*buf >> 4) & 1, (*buf >> 5) & 0x7); } else { /* UI frame. */ char *n = uname[((*buf >> 2) & 0x3) | ((*buf >> 3) & 0x1c)]; if (!n) n = "?"; snprintf(str, strlen, "%s pf=%d", n, (*buf >> 4) & 1); } return 0; } static void ax25_prmsg(struct gensio_os_funcs *o, struct gensio_sg *sg, gensiods sglen, unsigned int buflen) { struct gensio_ax25_addr addr; char str[100]; unsigned char buf[15]; gensiods pos = 0, pos2 = 0; int err; unsigned int i, j, k; if (buflen < 15) return; for (i = 0, j = 0, k = 0; i < 15; i++) { const unsigned char *nbuf = sg[j].buf; buf[i] = nbuf[k]; k++; if (k >= sg[j].buflen) { k = 0; j++; } } err = decode_ax25_addr(o, buf, &pos, 15, 0, &addr); if (err) return; err = addr.r.funcs->addr_to_str(&addr.r, str, &pos2, sizeof(str)); if (err) return; printf(" %s", str); printf(" ch=%d", addr.dest.ch); if (pos < buflen) { err = decode_ax25_control_field(str, sizeof(str), buf + pos, buflen - pos); if (err) return; printf(" %s", str); } } static void ax25_print_msg_sg(struct ax25_base *base, char *t, struct gensio_sg *sg, gensiods sglen) { struct gensio_os_funcs *o = base->o; struct gensio_fdump h; unsigned int buflen = 0; unsigned int i; for (i = 0; i < sglen; i++) { buflen += sg[i].buflen; } if (base->conf.debug & GENSIO_AX25_DEBUG_TIME) { gensio_time time; o->get_monotonic_time(o, &time); printf("%lld:%6.6d: ", (long long) time.secs, (time.nsecs + 500) / 1000); } printf("%sMSG(%u):", t, buflen); ax25_prmsg(o, sg, sglen, buflen); printf("\n"); gensio_fdump_init(&h, 1); for (i = 0; i < sglen; i++) gensio_fdump_buf(stdout, sg[i].buf, sg[i].buflen, &h); gensio_fdump_buf_finish(stdout, &h); fflush(stdout); } static void ax25_print_msg(struct ax25_base *base, char *t, unsigned char *buf, unsigned int buflen) { struct gensio_sg sg; sg.buf = buf; sg.buflen = buflen; ax25_print_msg_sg(base, t, &sg, 1); } /* * Sequence number and window handling. When dealing with sequence number, the * window is either 8 or 128 depending on if we are in extended mode. * * This also used for calculations dealing with the circular queue, where * window is the queue size. */ /* * Return the value of val1 - val2, wrapping around at window. */ static uint8_t sub_seq(uint8_t val1, uint8_t val2, uint8_t window) { if (val2 > val1) val1 += window; return val1 - val2; } /* * Add amt to the given value, wrapping around at window. */ static uint8_t add_seq(uint8_t val, uint8_t amt, uint8_t window) { uint8_t rv = amt + val; if (rv >= window) rv -= window; return rv; } /* * Return true if start <= val < end, false if not, taking into account * wrapping at the given window. */ static bool seq_in_range(uint8_t start, uint8_t end, uint8_t val, uint8_t window) { if (start == end) return start == val; if (end > start) return val >= start && val <= end; return val >= start || val <= end; } /* Can the upper layer write to me? */ static bool chan_can_write(struct ax25_chan *chan) { return ((chan->state == AX25_CHAN_OPEN && chan->write_len < chan->writewindow) || chan->err || chan->state == AX25_CHAN_NOCON); } /* Do I have data to deliver to the upper layer? */ static bool chan_can_read(struct ax25_chan *chan) { return chan->err || chan->read_len > 0; } static void ax25_chan_report_open(struct ax25_chan *chan) { gensio_done_err open_done = chan->open_done; void *open_data = chan->open_data; int err = chan->err; if (open_done) { chan->open_done = NULL; ax25_chan_unlock(chan); open_done(chan->io, err, open_data); ax25_chan_lock(chan); } } static void ax25_chan_report_close(struct ax25_chan *chan) { gensio_done close_done = chan->close_done; void *close_data = chan->close_data; ax25_chan_set_state(chan, AX25_CHAN_CLOSED); ax25_stop_timer(chan); ax25_chan_reset_data(chan); if (close_done) { chan->close_done = NULL; ax25_chan_unlock(chan); close_done(chan->io, close_data); ax25_chan_lock(chan); } /* Lose the ref from when close was called. */ ax25_chan_deref(chan); /* * When we close, we may still be in the sendlink list, but it * won't get processed again. So make sure to clear it out. */ ax25_base_lock(chan->base); if (gensio_list_link_inlist(&chan->sendlink)) { gensio_list_rm(&chan->base->send_list, &chan->sendlink); ax25_chan_deref(chan); } ax25_base_unlock(chan->base); } static void ax25_chan_check_close(struct ax25_chan *chan) { ax25_chan_report_open(chan); if (chan->in_read || chan->in_write || chan->in_ui || chan->base->closing_chan == chan) return; ax25_chan_report_close(chan); } static void ax25_base_child_close(struct ax25_base *base) { int err; err = gensio_close(base->child, ax25_base_child_close_done, base); if (err) i_ax25_base_child_close_done(base); else ax25_base_set_state(base, AX25_BASE_IN_CHILD_CLOSE); } static void ax25_chan_move_to_closed(struct ax25_chan *chan, struct gensio_list *old_list) { struct ax25_base *base = chan->base; ax25_stop_timer(chan); ax25_base_lock_and_ref(base); gensio_list_rm(old_list, &chan->link); gensio_list_add_tail(&base->chans_closed, &chan->link); if (base->state == AX25_BASE_OPEN) { if (gensio_list_empty(&base->chans)) { base->closing_chan = chan; if (base->cmdrsp_len > 0) { ax25_base_set_state(base, AX25_BASE_CLOSE_WAIT_DRAIN); } else { ax25_base_child_close(base); } } } ax25_base_deref_and_unlock(base); } static void ax25_chan_do_close(struct ax25_chan *chan) { struct ax25_base *base = chan->base; ax25_chan_set_state(chan, AX25_CHAN_REPORT_CLOSE); ax25_chan_move_to_closed(chan, &base->chans); ax25_chan_check_close(chan); } static void ax25_chan_do_err_close(struct ax25_chan *chan, bool do_deferred_op) { struct ax25_base *base = chan->base; switch (chan->state) { case AX25_CHAN_IN_OPEN: ax25_chan_set_state(chan, AX25_CHAN_CLOSED); ax25_chan_report_open(chan); break; case AX25_CHAN_IN_CLOSE: case AX25_CHAN_CLOSE_WAIT_DRAIN: ax25_chan_set_state(chan, AX25_CHAN_REPORT_CLOSE); ax25_chan_check_close(chan); break; case AX25_CHAN_REPORT_CLOSE: ax25_chan_check_close(chan); break; default: ax25_chan_set_state(chan, AX25_CHAN_IO_ERR); if (do_deferred_op) ax25_chan_sched_deferred_op(chan); } ax25_chan_move_to_closed(chan, &base->chans); } static void ax25_chan_send_ack(struct ax25_chan *chan, uint8_t pf, bool is_cmd) { unsigned int i; unsigned int pos; chan->ack_pending = 0; ax25_chan_stop_t2(chan); if (!pf && !is_cmd && chan->send_len > 0) return; /* Just let an I frame ack it. */ for (pos = chan->cmdrsp_pos, i = 0; i < chan->cmdrsp_len; i++) { struct ax25_chan_cmdrsp *cr= &(chan->cmdrsp[pos]); /* * Don't have duplicate RRs in the queue. If there is already * an RR there, just set the pf bit as necessary. */ if (cr->cr == X25_RR && cr->is_cmd == is_cmd) { if (pf) cr->pf = pf; return; } pos = (pos + 1) % AX25_CHAN_MAX_CMDRSP; } /* Note that RRs get converted to RNRs in the send code as needed. */ if (is_cmd) ax25_chan_send_cmd(chan, X25_RR, pf); else ax25_chan_send_rsp(chan, X25_RR, pf); } static void ax25_chan_deliver_read(struct ax25_chan *chan) { gensiods rcount; struct ax25_data *d; char pidstr[10]; const char *auxdata[2] = { pidstr, NULL }; int err; if (chan->in_read) goto check_for_busy; chan->in_read = true; while (chan->read_enabled && chan_can_read(chan)) { if (chan->err) { ax25_chan_unlock(chan); chan->read_enabled = false; /* Already have an error, the error return is irrelevant. */ gensio_cb(chan->io, GENSIO_EVENT_READ, chan->err, NULL, NULL, NULL); ax25_chan_lock(chan); continue; } d = &(chan->read_data[chan->read_pos]); snprintf(pidstr, sizeof(pidstr), "pid:%d", d->pid); ax25_chan_unlock(chan); rcount = d->len; err = gensio_cb(chan->io, GENSIO_EVENT_READ, 0, d->data + d->pos, &rcount, auxdata); ax25_chan_lock(chan); if (err) { if (!chan->err) { chan->err = err; ax25_chan_do_err_close(chan, true); } break; } if (rcount < d->len) { d->len -= rcount; d->pos += rcount; } else { chan->read_pos = add_seq(chan->read_pos, 1, chan->conf.readwindow); chan->read_len--; d->present = false; } } chan->in_read = false; if (chan->state == AX25_CHAN_REPORT_CLOSE) ax25_chan_check_close(chan); check_for_busy: if (!chan->own_rcv_bsy && chan->read_len > chan->conf.readwindow / 2) { chan->own_rcv_bsy = true; ax25_chan_send_ack(chan, 0, false); } else if (chan->own_rcv_bsy && chan->read_len == 0) { chan->own_rcv_bsy = false; ax25_chan_send_ack(chan, 1, true); chan->poll_pending = true; if (!chan->t1) { ax25_chan_stop_t3(chan); ax25_chan_start_t1(chan); } } } static void ax25_chan_deliver_write_ready(struct ax25_chan *chan) { int err; if (chan->in_write) return; chan->in_write = true; while (chan->xmit_enabled && chan_can_write(chan)) { ax25_chan_unlock(chan); err = gensio_cb(chan->io, GENSIO_EVENT_WRITE_READY, 0, NULL, NULL, NULL); ax25_chan_lock(chan); if (err) { if (!chan->err) { chan->err = err; ax25_chan_do_err_close(chan, true); } break; } } chan->in_write = false; if (chan->state == AX25_CHAN_REPORT_CLOSE) ax25_chan_check_close(chan); } static void ax25_chan_deferred_op(struct gensio_runner *runner, void *cbdata) { struct ax25_chan *chan = cbdata; gensio_refcount_set(&chan->deferred_op_pending, 1); ax25_chan_lock(chan); if (chan->state == AX25_CHAN_NOCON_IN_OPEN) { ax25_chan_set_state(chan, AX25_CHAN_NOCON); ax25_chan_report_open(chan); } if (chan->state == AX25_CHAN_REPORT_CLOSE) ax25_chan_check_close(chan); /* Read/write callbacks for delivering data and reporting errors. */ ax25_chan_deliver_read(chan); /* Read/write callbacks for delivering data and reporting errors. */ ax25_chan_deliver_write_ready(chan); ax25_chan_deref_and_unlock(chan); /* Ref from ax25_chan_sched_deferred_op */ } static void ax25_chan_sched_deferred_op(struct ax25_chan *chan) { if (gensio_refcount_dec_if_nz(&chan->deferred_op_pending)) { ax25_chan_ref(chan); chan->o->run(chan->deferred_op_runner); } } /* Must hold the base lock to call this. */ static struct ax25_chan * ax25_base_lookup_chan_by_addr(struct ax25_base *base, struct gensio_addr *addr) { struct gensio_link *l; gensio_list_for_each(&base->chans, l) { struct ax25_chan *chan = gensio_container_of(l, struct ax25_chan, link); if (chan->conf.addr && gensio_addr_equal(addr, chan->conf.addr, true, false)) return chan; } gensio_list_for_each(&base->chans_waiting_open, l) { struct ax25_chan *chan = gensio_container_of(l, struct ax25_chan, link); if (chan->conf.addr && gensio_addr_equal(addr, chan->conf.addr, true, false)) return chan; } return NULL; } static void ax25_chan_report_open_err(struct ax25_chan *chan, struct gensio_list *old_list, int err) { gensio_done_err open_done = chan->open_done; void *open_data = chan->open_data; chan->open_done = NULL; ax25_chan_set_state(chan, AX25_CHAN_CLOSED); ax25_chan_move_to_closed(chan, old_list); if (open_done) { ax25_chan_unlock(chan); if (open_done) open_done(chan->io, err, open_data); ax25_chan_lock(chan); } } static struct ax25_chan * ax25_chan_check_and_lock(struct ax25_chan *chan, struct gensio_list *should_be_in, bool incl_disc) { struct ax25_base *base = chan->base; ax25_chan_lock(chan); ax25_base_lock(base); if (!gensio_list_link_in_this_list(&chan->link, should_be_in) || (incl_disc && (chan->state == AX25_CHAN_REM_DISC || chan->state == AX25_CHAN_REM_CLOSE))) { /* Channel is not in a state where it should be. */ ax25_base_unlock(base); ax25_chan_deref_and_unlock(chan); return NULL; } ax25_base_unlock(base); return chan; } static void ax25_base_handle_open_done(struct ax25_base *base, int err) { struct gensio_list to_deliver; struct gensio_link *l, *l2; if (gensio_list_empty(&base->chans_waiting_open)) { if (err) { ax25_base_deref(base); ax25_base_set_state(base, AX25_BASE_CLOSED); } else { ax25_base_child_close(base); } return; } restart: gensio_list_init(&to_deliver); gensio_list_for_each(&base->chans_waiting_open, l) { struct ax25_chan *chan = gensio_container_of(l, struct ax25_chan, link); if (ax25_chan_ref_if_nz(chan)) gensio_list_add_tail(&to_deliver, &chan->hold_open_link); } if (err) ax25_base_set_state(base, AX25_BASE_IN_CHILD_CLOSE); else ax25_base_set_state(base, AX25_BASE_OPEN); ax25_base_unlock(base); gensio_list_for_each_safe(&to_deliver, l, l2) { struct ax25_chan *chan = gensio_container_of(l, struct ax25_chan, hold_open_link); gensio_list_rm(&to_deliver, l); chan = ax25_chan_check_and_lock(chan, &base->chans_waiting_open, true); if (!chan) continue; if (chan->state == AX25_CHAN_WAITING_OPEN) { if (err) { ax25_chan_report_open_err(chan, &base->chans_waiting_open, err); } else { ax25_base_lock(base); gensio_list_rm(&base->chans_waiting_open, &chan->link); gensio_list_add_tail(&base->chans, &chan->link); ax25_chan_prestart_connect(chan); ax25_base_unlock(base); ax25_chan_start_connect(chan); } } ax25_chan_deref_and_unlock(chan); } ax25_base_lock(base); if (err) { err = i_ax25_base_child_close_done(base); if (err) goto restart; } else { /* Make sure all channels are not waiting open before enabling read. */ if (base->state == AX25_BASE_OPEN) gensio_set_read_callback_enable(base->child, true); } } static int i_ax25_base_child_close_done(struct ax25_base *base) { int rv = 0; struct ax25_chan *chan = base->closing_chan; base->closing_chan = NULL; ax25_base_set_state(base, AX25_BASE_CLOSED); ax25_base_deref(base); if (chan) /* * Cause the close to be reported channel that caused the * base to close. */ ax25_chan_sched_deferred_op(chan); if (!gensio_list_empty(&base->chans_waiting_open)) { rv = ax25_base_start_open(base); if (rv) /* * An error return will cause this to call * handle_open_done with an error or restart it, which * will drop the ref count again. */ ax25_base_ref(base); else ax25_base_set_state(base, AX25_BASE_IN_CHILD_OPEN); } return rv; } static void ax25_base_child_close_done(struct gensio *child, void *open_data) { struct ax25_base *base = open_data; int rv; ax25_base_lock_and_ref(base); rv = i_ax25_base_child_close_done(base); if (rv) ax25_base_handle_open_done(base, rv); ax25_base_deref_and_unlock(base); } static void ax25_base_child_open_done(struct gensio *child, int err, void *open_data) { struct ax25_base *base = open_data; ax25_base_lock_and_ref(base); ax25_base_handle_open_done(base, err); ax25_base_deref_and_unlock(base); } /* Must be called with the base lock held. */ static int ax25_base_start_open(struct ax25_base *base) { int rv; base->child_err = 0; rv = gensio_open(base->child, ax25_base_child_open_done, base); if (!rv) { ax25_base_ref(base); ax25_base_set_state(base, AX25_BASE_IN_CHILD_OPEN); } return rv; } static void ax25_proto_err(struct ax25_base *base, struct ax25_chan *chan, const char *errstr) { if (chan) ax25_chan_unlock(chan); if (chan && chan->conf.addr) { char addrstr[100] = ""; if (chan->conf.addr) gensio_addr_to_str(chan->conf.addr, addrstr, NULL, sizeof(addrstr)); gensio_glog(chan->io, GENSIO_LOG_ERR, "AX25 error from %s: %s", addrstr, errstr); } else if (chan) { gensio_glog(chan->io, GENSIO_LOG_ERR, "AX25 error: %s", errstr); } else { gensio_log(base->o, GENSIO_LOG_ERR, "AX25 error: %s", errstr); } if (chan) ax25_chan_lock(chan); } static void ax25_chan_reset_data(struct ax25_chan *chan) { chan->vs = 0; chan->va = 0; chan->vr = 0; chan->peer_rcv_bsy = false; chan->own_rcv_bsy = false; chan->read_pos = 0; chan->read_len = 0; chan->write_pos = 0; chan->write_len = 0; chan->send_len = 0; chan->cmdrsp_pos = 0; chan->cmdrsp_len = 0; chan->in_rej = false; chan->ack_pending = 0; chan->poll_pending = false; chan->data_p_sent = false; chan->retry_count = 0; chan->srt = chan->conf.srtv; if (chan->conf.addr) { struct gensio_ax25_addr *aaddr = addr_to_ax25(chan->conf.addr); /* Increase the timeout based on the number of digipeaters. */ chan->srt *= (aaddr->nr_extra + 1); } chan->t1v = chan->srt * 2; chan->t1 = 0; chan->t2 = 0; chan->t3 = 0; chan->curr_timeout = 0; chan->err = 0; chan->got_firstmsg = false; chan->freed = false; } static void i_ax25_chan_schedule_write(struct ax25_chan *chan) { struct ax25_base *base = chan->base; if (base->state == AX25_BASE_OPEN) { if (!gensio_list_link_inlist(&chan->sendlink)) { if (ax25_chan_ref_if_nz(chan)) gensio_list_add_tail(&base->send_list, &chan->sendlink); } gensio_set_write_callback_enable(base->child, true); } } static void ax25_chan_schedule_write(struct ax25_chan *chan) { struct ax25_base *base = chan->base; ax25_base_lock(base); i_ax25_chan_schedule_write(chan); ax25_base_unlock(base); } static void ax25_base_send_rsp(struct ax25_base *base, struct gensio_addr *addr, uint8_t rsp, uint8_t pf, unsigned char *extra, unsigned extra_size) { struct ax25_base_cmdrsp *cr; unsigned int pos; ax25_base_lock(base); if (base->cmdrsp_len < AX25_BASE_MAX_CMDRSP && base->state == AX25_BASE_OPEN) { pos = (base->cmdrsp_pos + base->cmdrsp_len) % AX25_BASE_MAX_CMDRSP; cr = &(base->cmdrsp[pos]); cr->cr = rsp | (pf << 4); cr->addrlen = ax25_addr_encode(cr->addr, addr); /* Set C/R bits to response. */ cr->addr[6] &= ~0x80; cr->addr[13] |= 0x80; cr->extra_data_size = extra_size; if (extra) memcpy(cr->extra_data, extra, extra_size); base->cmdrsp_len++; gensio_set_write_callback_enable(base->child, true); } ax25_base_unlock(base); } static void ax25_chan_send_cr(struct ax25_chan *chan, uint8_t crv, uint8_t pf, bool is_cmd, unsigned char *extra, uint8_t extra_size) { struct ax25_base *base = chan->base; struct ax25_chan_cmdrsp *cr; unsigned int pos; ax25_base_lock(base); if (chan->cmdrsp_len < AX25_CHAN_MAX_CMDRSP) { pos = (chan->cmdrsp_pos + chan->cmdrsp_len) % AX25_CHAN_MAX_CMDRSP; cr = &(chan->cmdrsp[pos]); cr->cr = crv; cr->pf = pf; cr->is_cmd = is_cmd; cr->extra_data_size = extra_size; if (extra) memcpy(cr->extra_data, extra, extra_size); chan->cmdrsp_len++; i_ax25_chan_schedule_write(chan); } ax25_base_unlock(base); } static void ax25_chan_send_cmd(struct ax25_chan *chan, uint8_t cmd, uint8_t pf) { ax25_chan_send_cr(chan, cmd, pf, true, NULL, 0); } static void ax25_chan_send_rsp(struct ax25_chan *chan, uint8_t rsp, uint8_t pf) { ax25_chan_send_cr(chan, rsp, pf, false, NULL, 0); } static void ax25_chan_send_sabm(struct ax25_chan *chan) { if (chan->extended > 1) { unsigned char extra[4]; extra[0] = chan->conf.readwindow; extra[1] = chan->conf.max_read_size & 0xff; extra[2] = chan->conf.max_read_size >> 8; extra[3] = 0; ax25_chan_send_cr(chan, X25_SABME, 1, true, extra, 4); } else if (chan->extended) ax25_chan_send_cmd(chan, X25_SABME, 1); else ax25_chan_send_cmd(chan, X25_SABM, 1); } static void ax25_stop_timer(struct ax25_chan *chan) { int rv; if (chan->curr_timeout) { rv = chan->o->stop_timer(chan->timer); if (rv == 0) { /* We stopped it, lose the ref. */ ax25_chan_deref(chan); chan->curr_timeout = 0; } else { /* It's in the handler, it will do the deref. */ assert(rv == GE_TIMEDOUT); } } else { /* Just to be sure. */ chan->o->stop_timer(chan->timer); } } static void ax25_chan_check_new_timeout(struct ax25_chan *chan, int64_t value, gensio_time *nowt) { struct gensio_os_funcs *o = chan->o; gensio_time t; uint64_t now, then; int rv; if (chan->state == AX25_CHAN_CLOSED) return; if (chan->curr_timeout) { /* The timer is running or in the handler. */ if (value >= chan->curr_timeout) return; /* New value is after the current timeout. */ } ax25_stop_timer(chan); chan->curr_timeout = value; now = gensio_time_to_msecs(nowt); then = chan->curr_timeout - now; gensio_msecs_to_time(&t, then); rv = o->start_timer(chan->timer, &t); if (rv) { gensio_glog(chan->io, GENSIO_LOG_FATAL, "AX25 timer start error: %s", gensio_err_to_str(rv)); assert(0); } ax25_chan_ref(chan); } /* * Given a value in milliseconds, return the absolute time in * milliseconds and return the current time in now. */ static int64_t ax25_get_abs_timeout(struct gensio_os_funcs *o, unsigned int val, gensio_time *now) { int64_t v; o->get_monotonic_time(o, now); v = gensio_time_to_msecs(now); v += val; return v; } /* * You most be holding the channel lock to do timer operations. */ static void ax25_chan_start_t1(struct ax25_chan *chan) { gensio_time now; assert(chan->locked); chan->t1 = ax25_get_abs_timeout(chan->o, chan->t1v, &now); ax25_chan_check_new_timeout(chan, chan->t1, &now); } static void ax25_chan_start_t2(struct ax25_chan *chan) { gensio_time now; assert(chan->locked); chan->t2 = ax25_get_abs_timeout(chan->o, chan->conf.t2v, &now); ax25_chan_check_new_timeout(chan, chan->t2, &now); } static void ax25_chan_start_t3(struct ax25_chan *chan) { gensio_time now; assert(chan->locked); chan->t3 = ax25_get_abs_timeout(chan->o, chan->conf.t3v, &now); ax25_chan_check_new_timeout(chan, chan->t3, &now); } static void ax25_chan_stop_t1(struct ax25_chan *chan) { assert(chan->locked); chan->t1 = 0; } static void ax25_chan_stop_t2(struct ax25_chan *chan) { assert(chan->locked); chan->t2 = 0; } static void ax25_chan_stop_t3(struct ax25_chan *chan) { assert(chan->locked); chan->t3 = 0; } /* * Note that unlike the spec, this must be called *before* t1 is * cancelled, since that will set it to zero. */ static void ax25_chan_recalc_t1(struct ax25_chan *chan, bool t1_expiry) { struct gensio_os_funcs *o = chan->o; gensio_time now; int64_t diff; /* Calculate how much time is left on t1. */ o->get_monotonic_time(o, &now); diff = gensio_time_to_msecs(&now); diff = chan->t1 - diff; if (diff < 0) diff = 0; if (chan->retry_count == 0) { chan->srt = (7 * chan->srt / 8) + (chan->t1v / 8) - (diff / 8); chan->t1v = chan->srt * 2; } else if (t1_expiry) { chan->t1v = (1 << (chan->retry_count + 1)) * chan->srt; } } static void ax25_chan_transmit_enquiry(struct ax25_chan *chan) { ax25_chan_send_ack(chan, 1, true); ax25_chan_start_t1(chan); } static void ax25_t1_timeout(struct ax25_chan *chan) { struct ax25_base *base = chan->base; switch (chan->state) { case AX25_CHAN_IN_OPEN: if (chan->retry_count >= chan->max_retries) { chan->err = GE_TIMEDOUT; ax25_chan_set_state(chan, AX25_CHAN_CLOSED); ax25_chan_move_to_closed(chan, &base->chans); ax25_chan_report_open(chan); } else { chan->retry_count++; ax25_chan_send_sabm(chan); ax25_chan_recalc_t1(chan, true); chan->t1 = chan->t1v; ax25_chan_start_t1(chan); } break; case AX25_CHAN_OPEN: case AX25_CHAN_CLOSE_WAIT_DRAIN: if (chan->poll_pending) { if (chan->retry_count == chan->max_retries) { ax25_proto_err(chan->base, chan, "Connection timed out"); ax25_chan_send_rsp(chan, X25_DM, 1); chan->err = GE_TIMEDOUT; ax25_chan_do_err_close(chan, true); ax25_chan_stop_t3(chan); ax25_chan_stop_t1(chan); } else { chan->retry_count++; ax25_chan_transmit_enquiry(chan); } } else { chan->retry_count = 1; chan->poll_pending = true; ax25_chan_transmit_enquiry(chan); } break; case AX25_CHAN_IN_CLOSE: if (chan->retry_count >= chan->max_retries) { chan->err = GE_TIMEDOUT; ax25_chan_do_close(chan); } else { chan->retry_count++; ax25_chan_send_cmd(chan, X25_DISC, 1); /* * Do not recalculate t1 on a disconnect. It is possible * the other end isn't listening any more and this will * make the disconnect painfully slow. */ chan->t1 = chan->t1v; ax25_chan_start_t1(chan); } break; default: /* Just ignore this. */ break; } } static void ax25_t2_timeout(struct ax25_chan *chan) { switch (chan->state) { case AX25_CHAN_CLOSE_WAIT_DRAIN: case AX25_CHAN_OPEN: if (chan->ack_pending) ax25_chan_send_ack(chan, 0, false); break; case AX25_CHAN_IN_OPEN: case AX25_CHAN_IN_CLOSE: default: /* Just ignore this. */ break; } } static void ax25_t3_timeout(struct ax25_chan *chan) { switch (chan->state) { case AX25_CHAN_OPEN: chan->retry_count = 0; ax25_chan_transmit_enquiry(chan); break; case AX25_CHAN_IN_OPEN: case AX25_CHAN_CLOSE_WAIT_DRAIN: case AX25_CHAN_IN_CLOSE: default: /* Just ignore this. */ break; } } static void ax25_chan_timeout(struct gensio_timer *timer, void *cb_data) { struct ax25_chan *chan = cb_data; struct gensio_os_funcs *o = chan->o; gensio_time t; int64_t now; o->get_monotonic_time(o, &t); now = gensio_time_to_msecs(&t); ax25_chan_lock(chan); /* Just in case the timer was started between the timeout and here. */ ax25_stop_timer(chan); /* We are in the handler. Make sure no one starts the timer. */ chan->curr_timeout = 1; if (chan->state == AX25_CHAN_CLOSED) goto out_unlock; if (chan->t1 && chan->t1 <= now) { chan->t1 = 0; ax25_t1_timeout(chan); } if (chan->t2 && chan->t2 <= now) { chan->t2 = 0; ax25_t2_timeout(chan); } if (chan->t3 && chan->t3 <= now) { chan->t3 = 0; ax25_t3_timeout(chan); } chan->curr_timeout = 0; if (chan->t1) chan->curr_timeout = chan->t1; if (chan->t2 && chan->t2 < chan->curr_timeout) chan->curr_timeout = chan->t2; if (chan->t3 && chan->t3 < chan->curr_timeout) chan->curr_timeout = chan->t3; if (chan->curr_timeout) { int64_t then = chan->curr_timeout - now; /* * Don't use an absolute timer here, the precision isn't really good * enough, especially on some OS handlers. */ gensio_msecs_to_time(&t, then); if (o->start_timer(chan->timer, &t) != 0) assert(0); ax25_chan_ref(chan); } out_unlock: ax25_chan_deref_and_unlock(chan); } static void ax25_chan_set_extended(struct ax25_chan *chan, bool extended, unsigned char *data, unsigned int len) { unsigned int max_pkt; chan->max_retries = chan->conf.max_retries; if (chan->extended >= 2 && extended && len >= 4) { chan->extended = 2; chan->modulo = 128; if (data[0]) chan->writewindow = data[0]; else if (chan->conf.writewindow > 7) chan->writewindow = 7; else chan->writewindow = chan->conf.writewindow; max_pkt = data[2] << 8 | data[1]; if (max_pkt < 256) chan->max_write_size = 256; else if (max_pkt > chan->conf.max_write_size) chan->max_write_size = chan->conf.max_write_size; else chan->max_write_size = max_pkt; chan->readwindow = chan->conf.readwindow; return; } chan->extended = extended; if (chan->conf.max_write_size > 256) chan->max_write_size = 256; else chan->max_write_size = chan->conf.max_write_size; if (chan->extended) { chan->modulo = 128; if (chan->conf.writewindow > 7) chan->writewindow = 7; else chan->writewindow = chan->conf.writewindow; if (chan->conf.readwindow > 7) chan->readwindow = 7; else chan->readwindow = chan->conf.readwindow; } else { chan->modulo = 8; if (chan->conf.writewindow_set && chan->conf.writewindow > 4) chan->writewindow = 4; else if (chan->conf.writewindow_set) chan->writewindow = chan->conf.writewindow; else /* Default to 2, because that's what RMS packet does. Sigh. */ chan->writewindow = 2; if (chan->conf.readwindow > 4) chan->readwindow = 4; else chan->readwindow = chan->conf.readwindow; } } /* Must be called with the channel and base lock held. */ static void ax25_chan_prestart_connect(struct ax25_chan *chan) { ax25_chan_reset_data(chan); if (chan->conf.addr) ax25_chan_set_state(chan, AX25_CHAN_IN_OPEN); else ax25_chan_set_state(chan, AX25_CHAN_NOCON_IN_OPEN); } /* Must be called with the channel lock held, but not the base lock. */ static void ax25_chan_start_connect(struct ax25_chan *chan) { if (chan->conf.addr) { ax25_chan_set_extended(chan, chan->conf.extended, NULL, 0); ax25_chan_send_sabm(chan); ax25_chan_start_t1(chan); chan->retry_count = 0; } else { /* A channel for only doing UI messages. */ ax25_chan_sched_deferred_op(chan); } } static void ax25_chan_report_raw(struct ax25_base *base, unsigned int port, unsigned char *data, unsigned int len) { struct gensio_list to_deliver; struct gensio_link *l, *l2; char portstr[10]; const char *auxdata[4] = { "oob", "raw", portstr, NULL }; gensiods rcount; if (len == 0 || !base->have_raw) return; snprintf(portstr, sizeof(portstr), "port:%d", port); gensio_list_init(&to_deliver); ax25_base_lock(base); gensio_list_for_each(&base->chans, l) { struct ax25_chan *chan = gensio_container_of(l, struct ax25_chan, link); if (!chan->conf.report_raw || !chan->read_enabled) continue; if (ax25_chan_ref_if_nz(chan)) gensio_list_add_tail(&to_deliver, &chan->hold_ui_link); } ax25_base_unlock(base); if (gensio_list_empty(&to_deliver)) return; gensio_list_for_each_safe(&to_deliver, l, l2) { struct ax25_chan *chan = gensio_container_of(l, struct ax25_chan, hold_ui_link); gensio_list_rm(&to_deliver, l); chan = ax25_chan_check_and_lock(chan, &chan->base->chans, true); if (!chan) continue; if (!chan->read_enabled) { ax25_chan_deref_and_unlock(chan); continue; } chan->in_ui = true; ax25_chan_unlock(chan); /* Errors from here don't matter, we don't loop. */ rcount = len; gensio_cb(chan->io, GENSIO_EVENT_READ, 0, data, &rcount, auxdata); ax25_chan_lock(chan); chan->in_ui = false; if (chan->state == AX25_CHAN_REPORT_CLOSE) ax25_chan_check_close(chan); ax25_chan_deref_and_unlock(chan); } } /* Reporting of heard and UI frames. */ static void ax25_chan_handle_report(struct ax25_base *base, struct gensio_ax25_addr *addr, uint8_t cmd, unsigned char *data, unsigned int len, uint8_t pf) { struct gensio_list to_deliver; struct gensio_link *l, *l2; char addrstr[GENSIO_AX25_MAX_ADDR_STR_LEN + 5]; char pidstr[10]; const char *auxdata_ui[4] = { "oob", addrstr, pidstr, NULL }; const char *auxdata_heard[4] = { "oob", "heard", addrstr, NULL }; gensiods rcount; snprintf(pidstr, sizeof(pidstr), "pid:%d", *data); data++; len--; gensio_list_init(&to_deliver); ax25_base_lock(base); gensio_list_for_each(&base->chans, l) { struct ax25_chan *chan = gensio_container_of(l, struct ax25_chan, link); bool found; if (!((cmd == X25_UI && chan->report_ui) || chan->conf.report_heard) || !chan->read_enabled) continue; if (!chan->conf.report_heard && chan->report_ui < 2) { ax25_ui_addr_lock(chan); found = ax25_iaddr_find(&chan->ui_addrs, &addr->dest); ax25_ui_addr_unlock(chan); if (!found) continue; } if (ax25_chan_ref_if_nz(chan)) gensio_list_add_tail(&to_deliver, &chan->hold_ui_link); } ax25_base_unlock(base); if (gensio_list_empty(&to_deliver)) return; strcpy(addrstr, "addr:"); gensio_addr_to_str(&addr->r, addrstr + 5, NULL, sizeof(addrstr) - 5); gensio_list_for_each_safe(&to_deliver, l, l2) { struct ax25_chan *chan = gensio_container_of(l, struct ax25_chan, hold_ui_link); bool report_ui; bool report_heard = false; gensio_list_rm(&to_deliver, l); chan = ax25_chan_check_and_lock(chan, &chan->base->chans, true); if (!chan) continue; if (!chan->read_enabled) { ax25_chan_deref_and_unlock(chan); continue; } ax25_ui_addr_lock(chan); report_ui = (cmd == X25_UI && (chan->report_ui >= 2 || ax25_iaddr_find(&chan->ui_addrs, &addr->dest))); ax25_ui_addr_unlock(chan); if (!report_ui) report_heard = chan->conf.report_heard; chan->in_ui = true; ax25_chan_unlock(chan); /* Return values from here don't matter, we don't hold the data. */ if (report_ui) { rcount = len; gensio_cb(chan->io, GENSIO_EVENT_READ, 0, data, &rcount, auxdata_ui); } else if (report_heard) { rcount = 0; gensio_cb(chan->io, GENSIO_EVENT_READ, 0, data, &rcount, auxdata_heard); } ax25_chan_lock(chan); chan->in_ui = false; if (chan->state == AX25_CHAN_REPORT_CLOSE) ax25_chan_check_close(chan); ax25_chan_deref_and_unlock(chan); } } static void ax25_construct_return_addr(struct gensio_ax25_addr *r, struct gensio_ax25_addr *a) { unsigned int i; r->r = a->r; r->o = a->o; r->tnc_port = a->tnc_port; r->nr_extra = a->nr_extra; r->dest = a->src; r->dest.ch = 0; r->src = a->dest; r->src.ch = 0; /* Reverse the extra for going back to the source. */ for (i = 0; i < r->nr_extra; i++) { r->extra[i] = a->extra[r->nr_extra - i - 1]; r->extra[i].ch = 0; } } static struct ax25_chan * ax25_base_first_chan(struct ax25_base *base) { struct ax25_chan *chan; ax25_base_lock(base); if (gensio_list_empty(&base->chans)) chan = NULL; else chan = gensio_container_of(gensio_list_first(&base->chans), struct ax25_chan, link); if (chan && !ax25_chan_ref_if_nz(chan)) chan = NULL; ax25_base_unlock(base); return chan; } /* * Call the event handler for the first registered channel. */ static int ax25_firstchan_event(struct ax25_base *base, int event, int err, unsigned char *buf, gensiods *buflen, const char * const * auxdata) { int rerr; struct ax25_chan *chan; retry: chan = ax25_base_first_chan(base); if (!chan) return GE_LOCALCLOSED; chan = ax25_chan_check_and_lock(chan, &base->chans, true); if (!chan) goto retry; ax25_chan_unlock(chan); rerr = gensio_cb(chan->io, event, err, buf, buflen, auxdata); ax25_chan_lock(chan); ax25_chan_deref_and_unlock(chan); return rerr; } /* * In an accepter, before startup the first channel is sitting in the * closed channel list. We need to convert it to an open channel. */ static struct ax25_chan * i_ax25_base_promote_first_chan(struct ax25_base *base) { struct ax25_chan *chan; assert(!gensio_list_empty(&base->chans_closed)); chan = gensio_container_of(gensio_list_first(&base->chans_closed), struct ax25_chan, link); gensio_list_rm(&base->chans_closed, &chan->link); gensio_list_add_tail(&base->chans, &chan->link); /* * Don't use set state here, the channel lock is not held, but it * doesn't matter. */ chan->state = AX25_CHAN_OPEN; return chan; } static struct ax25_chan * ax25_base_promote_first_chan(struct ax25_base *base) { struct ax25_chan *chan; ax25_base_lock(base); chan = i_ax25_base_promote_first_chan(base); ax25_base_unlock(base); return chan; } static struct ax25_chan * ax25_chan_handle_sabm(struct ax25_base *base, struct ax25_chan *chan, struct gensio_ax25_addr *addr, uint8_t pf, bool is_cmd, unsigned int extended, unsigned char *data, unsigned int len) { int rv; if (!chan) { if (extended && !base->conf.extended) { unsigned char extra[3]; extra[2] = X25_SABME; extra[1] = is_cmd << 4; extra[0] = 1; ax25_base_send_rsp(base, &addr->r, X25_FRMR, pf, extra, 3); return 0; } if (base->waiting_first_open) { /* * There is no base lock here. That should not be necessary, * the other code we can race with is in * i_ax25_base_handle_child_err(), but that can only be called * from the receive code (which we are already in and is single * threaded) or the write code, which shouldn't be able to be * called yet. */ base->waiting_first_open = false; chan = ax25_base_promote_first_chan(base); chan->conf.addr = gensio_addr_dup(&addr->r); if (!chan->conf.addr) { chan->err = GE_NOMEM; ax25_base_send_rsp(base, &addr->r, X25_DM, pf, NULL, 0); ax25_chan_report_open(chan); return NULL; } chan->encoded_addr_len = ax25_addr_encode(chan->encoded_addr, chan->conf.addr); ax25_chan_set_extended(chan, extended, data, len); ax25_chan_lock_and_ref(chan); ax25_chan_report_open(chan); } else { rv = ax25_chan_alloc(base, NULL, NULL, NULL, AX25_CHAN_OPEN, &addr->r, false, &chan); if (rv) { ax25_base_send_rsp(base, &addr->r, X25_DM, pf, NULL, 0); return NULL; } ax25_chan_set_extended(chan, extended, data, len); if (base->accepter) { gensio_acc_cb(base->accepter, GENSIO_ACC_EVENT_NEW_CONNECTION, chan->io); ax25_chan_lock(chan); } else { char addrstr[GENSIO_AX25_MAX_ADDR_STR_LEN + 5]; const char *auxdata[2] = { addrstr, NULL }; strcpy(addrstr, "addr:"); gensio_addr_to_str(&addr->r, addrstr + 5, NULL, sizeof(addrstr) - 5); chan->in_newchannel = 1; rv = ax25_firstchan_event(base, GENSIO_EVENT_NEW_CHANNEL, 0, (unsigned char *) chan->io, NULL, auxdata); ax25_chan_lock(chan); if (rv || chan->in_newchannel == 2) { if (chan->in_newchannel != 2) { ax25_chan_set_state(chan, AX25_CHAN_CLOSED); ax25_chan_move_to_closed(chan, &base->chans); } ax25_chan_deref_and_unlock(chan); ax25_base_send_rsp(base, &addr->r, X25_DM, pf, NULL, 0); chan->in_newchannel = 0; return NULL; } chan->in_newchannel = 0; } ax25_chan_ref(chan); } ax25_chan_send_rsp(chan, X25_UA, pf); if (chan->extended) ax25_chan_send_cmd(chan, X25_XID, 1); /* Increase the timeout for every hop through a digipeater. */ chan->srt = chan->conf.srtv * (addr->nr_extra + 1); chan->t1v = chan->srt * 2; ax25_chan_start_t3(chan); return chan; } switch (chan->state) { case AX25_CHAN_IN_OPEN: if (!chan->extended && extended) { unsigned char extra[3]; extra[2] = X25_SABME; extra[1] = is_cmd << 4; extra[0] = 1; ax25_chan_send_cr(chan, X25_FRMR, pf, is_cmd, extra, 3); } else { handle_in_open: ax25_chan_set_extended(chan, extended, data, len); ax25_chan_send_rsp(chan, X25_UA, pf); } break; case AX25_CHAN_OPEN: /* If no packets have been received, pretend this is a new sabm. */ if (!chan->got_firstmsg) goto handle_in_open; ax25_proto_err(base, chan, "Data Link Reset"); ax25_chan_send_rsp(chan, X25_DM, pf); chan->err = GE_PROTOERR; ax25_chan_do_err_close(chan, true); ax25_chan_stop_t3(chan); ax25_chan_stop_t1(chan); break; case AX25_CHAN_CLOSE_WAIT_DRAIN: /* Data has been lost, no need for drain wait, just shut down. */ case AX25_CHAN_IN_CLOSE: case AX25_CHAN_REM_DISC: case AX25_CHAN_REM_CLOSE: ax25_chan_send_rsp(chan, X25_DM, pf); ax25_chan_do_close(chan); break; default: assert(0); } return chan; } static void ax25_chan_handle_disc(struct ax25_base *base, struct ax25_chan *chan, struct gensio_ax25_addr *addr, uint8_t pf, bool is_cmd) { if (!chan) { ax25_base_send_rsp(base, &addr->r, X25_DM, pf, NULL, 0); return; } switch (chan->state) { case AX25_CHAN_IN_OPEN: ax25_chan_send_rsp(chan, X25_DM, pf); break; case AX25_CHAN_CLOSE_WAIT_DRAIN: case AX25_CHAN_IN_CLOSE: /* Channel will be closed, used the base queue. */ ax25_base_send_rsp(base, chan->conf.addr, X25_UA, pf, NULL, 0); ax25_chan_do_close(chan); break; case AX25_CHAN_OPEN: chan->err = GE_REMCLOSE; ax25_chan_set_state(chan, AX25_CHAN_REM_DISC); ax25_chan_send_rsp(chan, X25_UA, pf); ax25_chan_stop_t3(chan); ax25_chan_stop_t1(chan); break; case AX25_CHAN_REM_DISC: case AX25_CHAN_REM_CLOSE: ax25_chan_send_rsp(chan, X25_UA, pf); break; default: assert(0); } } static void ax25_chan_handle_fallback_response(struct ax25_chan *chan) { /* FIXME - handle subfields. */ if (chan->extended == 2) { chan->extended = 1; ax25_chan_send_sabm(chan); ax25_chan_start_t1(chan); } else if (chan->extended == 1) { chan->extended = 0; chan->modulo = 8; chan->writewindow = 2; chan->readwindow = 4; ax25_chan_send_sabm(chan); ax25_chan_start_t1(chan); } } static void ax25_chan_handle_dm(struct ax25_base *base, struct ax25_chan *chan, struct gensio_ax25_addr *addr, uint8_t pf, bool is_cmd) { if (!chan) /* Ignore this. */ return; switch (chan->state) { case AX25_CHAN_IN_OPEN: if (chan->extended > 0) { /* * Some broken stacks respond with DM, not FRMR, when they * receive a SABME but don't support it. */ ax25_chan_handle_fallback_response(chan); } else { if (pf) { chan->err = GE_REMCLOSE; ax25_chan_do_err_close(chan, false); ax25_chan_stop_t1(chan); ax25_chan_report_open(chan); } } break; case AX25_CHAN_OPEN: case AX25_CHAN_CLOSE_WAIT_DRAIN: chan->err = GE_REMCLOSE; ax25_chan_stop_t3(chan); ax25_chan_stop_t1(chan); if (chan->state == AX25_CHAN_CLOSE_WAIT_DRAIN) ax25_chan_do_close(chan); else ax25_chan_do_err_close(chan, true); break; case AX25_CHAN_IN_CLOSE: case AX25_CHAN_REM_DISC: case AX25_CHAN_REM_CLOSE: if (pf) { chan->err = GE_REMCLOSE; ax25_chan_stop_t1(chan); ax25_chan_do_close(chan); } break; default: assert(0); } } static void ax25_chan_handle_ua(struct ax25_base *base, struct ax25_chan *chan, struct gensio_ax25_addr *addr, uint8_t pf, bool is_cmd, unsigned char *data, unsigned int len) { if (!chan) { ax25_proto_err(base, chan, "Unexpected UA when disconnected"); /* Ignore this. */ return; } switch (chan->state) { case AX25_CHAN_IN_OPEN: if (pf) { if (len >= 4) ax25_chan_set_extended(chan, true, data, len); ax25_chan_stop_t1(chan); ax25_chan_start_t3(chan); ax25_chan_set_state(chan, AX25_CHAN_OPEN); ax25_chan_report_open(chan); } else { ax25_proto_err(base, chan, "UA received without F=1 when SABM or DISC was sent P=1"); } break; case AX25_CHAN_OPEN: /* If no packets have been received, just ignore this. */ ax25_proto_err(base, chan, "Unexpected UA when connected"); if (!chan->conf.ignore_embedded_ua) { ax25_chan_stop_t3(chan); ax25_chan_stop_t2(chan); ax25_chan_stop_t1(chan); ax25_chan_reset_data(chan); } break; case AX25_CHAN_CLOSE_WAIT_DRAIN: ax25_chan_send_cmd(chan, X25_DISC, 1); ax25_chan_start_t1(chan); ax25_chan_stop_t3(chan); ax25_chan_set_state(chan, AX25_CHAN_IN_CLOSE); break; case AX25_CHAN_IN_CLOSE: if (pf) { ax25_chan_stop_t1(chan); ax25_chan_do_close(chan); } else { ax25_proto_err(base, chan, "UA received without F=1 when SABM or DISC was sent P=1"); } break; case AX25_CHAN_REM_DISC: case AX25_CHAN_REM_CLOSE: break; default: assert(0); } } #define AX25_XID_SIZE 29 static void ax25_chan_format_xid(struct ax25_chan *chan, unsigned char *buf) { unsigned int i = 0; uint32_t val; /* Note that these are big endian, the rest of AX.25 is little. */ buf[i++] = 0x82; /* FI Format indicator */ buf[i++] = 0x80; /* GI Group indicator */ val = 25; /* Our group size */ buf[i++] = (val >> 8) & 0xff; buf[i++] = val & 0xff; buf[i++] = 2; /* PI Classes of Procedures */ buf[i++] = 2; val = 0x2100; /* Only half duplex and balanced mode. */ buf[i++] = (val >> 8) & 0xff; buf[i++] = val & 0xff; buf[i++] = 3; /* PI HDLC Optional Functions */ buf[i++] = 3; val = (0x800000 | /* Extended address */ 0x020000 | /* REJ */ 0x040000 | /* SREJ */ 0x008000 | /* 16 bit FCS */ 0x002000 | /* TEST cmd */ 0x000800 | /* Modulo 128 */ 0x000002); /* synchronous TX */ buf[i++] = (val >> 16) & 0xff; buf[i++] = (val >> 8) & 0xff; buf[i++] = val & 0xff; buf[i++] = 6; /* PI I Field Length RX */ buf[i++] = 2; val = chan->conf.max_read_size * 8; buf[i++] = (val >> 8) & 0xff; buf[i++] = val & 0xff; buf[i++] = 8; /* PI Window Size RX */ buf[i++] = 1; buf[i++] = chan->conf.readwindow; buf[i++] = 9; /* Ack Timeout */ buf[i++] = 4; val = chan->conf.srtv * 2; buf[i++] = (val >> 24) & 0xff; buf[i++] = (val >> 16) & 0xff; buf[i++] = (val >> 8) & 0xff; buf[i++] = val & 0xff; buf[i++] = 10; /* PI Retries */ buf[i++] = 1; buf[i++] = chan->conf.max_retries; assert(i == AX25_XID_SIZE); } static void ax25_chan_handle_xid(struct ax25_base *base, struct ax25_chan *chan, struct gensio_ax25_addr *addr, uint8_t pf, bool is_cmd, unsigned char *buf, unsigned int buflen) { unsigned int i = 0, group_len, len; if (!chan || chan->state != AX25_CHAN_OPEN) /* Ignore this. */ return; if (buflen < 4) return; if (buf[i++] != 0x82) /* FI Format indicator */ return; if (buf[i++] != 0x80) /* GI Group indicator */ return; group_len = buf[i++]; group_len = (group_len << 8) | buf[i++]; buf += 4; buflen -= 4; if (buflen < group_len) return; for (; group_len; group_len -= len, buf += len) { unsigned int ind, val, j; if (group_len < 2) return; i = 0; ind = buf[i++]; len = buf[i++]; if (len < 1 || len > 4) return; if (group_len < len + 2) return; for (j = 0, val = 0; j < len; j++) val = (val << 8) | buf[i++]; len += 2; switch(ind) { case 2: /* PI Classes of Procedures */ /* Ignore this, we only really do half duplex. */ break; case 3: /* PI HDLC Optional Functions */ /* Ignore this, we only send REJ. */ break; case 6: /* PI I Field Length RX */ if (val % 8 != 0) /* This is in bits, needs tobe multiple of 8 */ break; val /= 8; if (val <= 0) break; if (val > chan->conf.max_write_size) val = chan->conf.max_write_size; chan->writewindow = val; break; case 8: /* PI Window Size RX */ if (val <= 0) break; if (val > chan->conf.writewindow) val = chan->conf.writewindow; chan->writewindow = val; break; case 9: /* PI Ack Timer */ if (val <= 0) break; if (val / 2 > chan->conf.srtv) chan->srt = val / 2; break; case 10: /* PI Retries */ if (val <= 0) break; if (val > chan->conf.max_retries) chan->max_retries = val; break; } } if (is_cmd) ax25_chan_send_rsp(chan, X25_XID, pf); } static void ax25_chan_handle_test(struct ax25_base *base, struct ax25_chan *chan, struct gensio_ax25_addr *addr, uint8_t pf, bool is_cmd, unsigned char *buf, unsigned int buflen) { if (!chan || chan->state != AX25_CHAN_OPEN) /* Ignore this. */ return; if (buflen > AX25_CHAN_MAX_CMDRSP_EXTRA) buflen = AX25_CHAN_MAX_CMDRSP_EXTRA; ax25_chan_send_cr(chan, X25_TEST, pf, false, buf, buflen); } static void ax25_chan_handle_frmr(struct ax25_base *base, struct ax25_chan *chan, struct gensio_ax25_addr *addr, uint8_t pf, bool is_cmd, unsigned char *buf, unsigned int buflen) { if (!chan) /* Ignore this. */ return; switch (chan->state) { case AX25_CHAN_IN_OPEN: ax25_chan_handle_fallback_response(chan); break; case AX25_CHAN_OPEN: case AX25_CHAN_CLOSE_WAIT_DRAIN: case AX25_CHAN_IN_CLOSE: case AX25_CHAN_REM_DISC: case AX25_CHAN_REM_CLOSE: /* Just ignore these. */ break; default: assert(0); } } static void ax25_chan_update_va(struct ax25_chan *chan, uint8_t nr) { uint8_t first = sub_seq(chan->vs, chan->write_len, chan->modulo); uint8_t diff; chan->va = nr; diff = sub_seq(nr, first, chan->modulo); chan->write_len -= diff; if (chan->send_len > chan->write_len) /* * If we are re-sending and we get an ack for what we are * resending, just abort the resend for the packets that are * to be acked. */ chan->send_len = chan->write_len; if (chan->xmit_enabled && chan_can_write(chan)) ax25_chan_sched_deferred_op(chan); } static bool ax25_chan_seq_in_range(struct ax25_chan *chan, uint8_t nr) { uint8_t first = sub_seq(chan->vs, chan->write_len, chan->modulo); if (!seq_in_range(first, chan->vs, nr, chan->modulo)) { ax25_proto_err(chan->base, chan, "N(r) sequence error"); return false; } return true; } static int ax25_chan_handle_data(struct ax25_chan *chan, uint8_t ns, uint8_t pf, unsigned char *data, unsigned int len) { uint8_t pos = add_seq(chan->read_pos, chan->read_len, chan->conf.readwindow); struct ax25_data *d; uint8_t pid; if (chan->own_rcv_bsy) { if (pf) ax25_chan_send_ack(chan, pf, 1); return 0; } if (len == 0) { /* No PID. */ ax25_proto_err(chan->base, chan, "I frame too short"); return GE_PROTOERR; } pid = *data; data++; len--; if (ns == chan->vr) { /* It's what we expect, just deliver it. */ if (chan->read_len >= chan->conf.readwindow) { /* read window violation. */ ax25_proto_err(chan->base, chan, "Read window exceeded"); return GE_PROTOERR; } chan->in_rej = false; d = &(chan->read_data[pos]); memcpy(d->data, data, len); d->pid = pid; d->len = len; d->pos = 0; d->seq = ns; d->present = true; chan->read_len++; ax25_chan_deliver_read(chan); chan->vr = add_seq(chan->vr, 1, chan->modulo); /* We got some data, handle acks. */ if (pf) { ax25_chan_send_ack(chan, pf, false); } else if (chan->ack_pending > (chan->readwindow / 2)) { /* More than half the window is used, send an ack now. */ ax25_chan_send_ack(chan, 0, false); } else { if (!chan->ack_pending) /* The timer wasn't running, start it. */ ax25_chan_start_t2(chan); chan->ack_pending++; } } else { uint8_t end = add_seq(chan->vr, chan->readwindow - 1, chan->modulo); /* * Only consider sequences in our window for resends, ignore * everything else. */ if (seq_in_range(chan->vr, end, ns, chan->modulo)) { if (chan->in_rej) { if (pf) ax25_chan_send_ack(chan, pf, false); } else { chan->in_rej = true; ax25_chan_send_rsp(chan, X25_REJ, pf); chan->ack_pending = 0; } } } return 0; } static void ax25_chan_check_drain_done(struct ax25_chan *chan) { if (chan->vs == chan->va) { /* All data is acked in wait drain state, we can close. */ ax25_chan_send_cmd(chan, X25_DISC, 1); ax25_chan_start_t1(chan); ax25_chan_stop_t3(chan); ax25_chan_set_state(chan, AX25_CHAN_IN_CLOSE); } } static void ax25_chan_check_i_frame_acked(struct ax25_chan *chan, uint8_t nr) { if (chan->peer_rcv_bsy) { ax25_chan_update_va(chan, nr); ax25_chan_start_t3(chan); if (!chan->t1) ax25_chan_start_t1(chan); } else { if (chan->vs == nr) { ax25_chan_update_va(chan, nr); ax25_chan_recalc_t1(chan, false); ax25_chan_stop_t1(chan); ax25_chan_start_t3(chan); } else { if (chan->va != nr) { ax25_chan_update_va(chan, nr); ax25_chan_start_t1(chan); } } } } static int ax25_chan_handle_i(struct ax25_base *base, struct ax25_chan *chan, struct gensio_ax25_addr *addr, uint8_t nr, uint8_t ns, uint8_t pf, bool is_cmd, unsigned char *data, unsigned int len) { int rv = 0; chan->got_firstmsg = true; switch (chan->state) { case AX25_CHAN_IN_OPEN: case AX25_CHAN_REM_DISC: case AX25_CHAN_REM_CLOSE: break; case AX25_CHAN_IN_CLOSE: if (pf) ax25_chan_send_rsp(chan, X25_DM, pf); break; case AX25_CHAN_OPEN: case AX25_CHAN_CLOSE_WAIT_DRAIN: if (!is_cmd) { ax25_proto_err(base, chan, "Received response I frame"); return 0; } if (len > chan->conf.max_read_size + 1) { /* + 1 for PID */ ax25_proto_err(base, chan, "Received too large a packet"); return GE_PROTOERR; } if (!ax25_chan_seq_in_range(chan, nr)) return GE_PROTOERR; ax25_chan_check_i_frame_acked(chan, nr); if (chan->state == AX25_CHAN_OPEN) { /* Only handle data in open state, throw away in wait drain. */ rv = ax25_chan_handle_data(chan, ns, pf, data, len); } else { ax25_chan_check_drain_done(chan); } break; default: assert(0); } return rv; } static void ax25_chan_check_response_needed(struct ax25_chan *chan, uint8_t pf, bool is_cmd) { if (is_cmd && pf) { ax25_chan_send_ack(chan, pf, false); } else if (!is_cmd && pf) { if (chan->poll_pending) { chan->poll_pending = false; chan->retry_count = 0; } else if (chan->data_p_sent) { chan->data_p_sent = false; } else { ax25_proto_err(chan->base, chan, "F=1 but P=1 not outstanding"); } } } static void ax25_chan_rewind_seq(struct ax25_chan *chan, uint8_t nr, bool selective) { uint8_t diff, i; unsigned int pos; diff = sub_seq(chan->vs, nr, chan->modulo); if (diff > chan->send_len) { /* Only back up if we need to back up more. */ chan->send_len = diff; assert(chan->send_len <= chan->write_len); } pos = sub_seq(chan->write_pos, diff, chan->conf.writewindow); for (i = 0; i < diff; i++) { chan->write_data[pos].present = true; if (selective) /* In selective reject, we only mark the one. */ break; pos = add_seq(pos, 1, chan->conf.writewindow); } ax25_chan_schedule_write(chan); ax25_chan_start_t1(chan); } static int ax25_chan_handle_recovery_rsp(struct ax25_chan *chan, uint8_t nr, uint8_t pf, bool is_cmd) { if (!is_cmd && pf) { ax25_chan_recalc_t1(chan, false); ax25_chan_stop_t1(chan); if (!ax25_chan_seq_in_range(chan, nr)) return GE_PROTOERR; ax25_chan_update_va(chan, nr); if (chan->vs == chan->va) { chan->poll_pending = false; chan->retry_count = 0; ax25_chan_start_t3(chan); } else { ax25_chan_rewind_seq(chan, nr, false); } } else { if (is_cmd && pf) ax25_chan_send_ack(chan, pf, false); if (!ax25_chan_seq_in_range(chan, nr)) return GE_PROTOERR; ax25_chan_update_va(chan, nr); } return 0; } static void ax25_chan_clr_peer_rcv_bsy(struct ax25_chan *chan) { chan->peer_rcv_bsy = false; if (chan->send_len > 0) ax25_chan_schedule_write(chan); } static int ax25_chan_handle_rr_rnr(struct ax25_chan *chan, uint8_t nr, uint8_t pf, bool is_cmd) { int rv; if (chan->poll_pending) { rv = ax25_chan_handle_recovery_rsp(chan, nr, pf, is_cmd); if (rv) return rv; } else { ax25_chan_check_response_needed(chan, pf, is_cmd); if (!ax25_chan_seq_in_range(chan, nr)) return GE_PROTOERR; ax25_chan_check_i_frame_acked(chan, nr); } if (chan->state == AX25_CHAN_CLOSE_WAIT_DRAIN) ax25_chan_check_drain_done(chan); return 0; } static int ax25_chan_handle_rr(struct ax25_base *base, struct ax25_chan *chan, uint8_t nr, uint8_t pf, bool is_cmd) { int rv = 0; assert(chan); /* Keep scan-build happy. */ switch (chan->state) { case AX25_CHAN_IN_OPEN: case AX25_CHAN_REM_DISC: case AX25_CHAN_REM_CLOSE: break; case AX25_CHAN_IN_CLOSE: if (pf) ax25_chan_send_rsp(chan, X25_DM, pf); break; case AX25_CHAN_OPEN: case AX25_CHAN_CLOSE_WAIT_DRAIN: ax25_chan_clr_peer_rcv_bsy(chan); rv = ax25_chan_handle_rr_rnr(chan, nr, pf, is_cmd); break; default: assert(0); } return rv; } static int ax25_chan_handle_rnr(struct ax25_base *base, struct ax25_chan *chan, uint8_t nr, uint8_t pf, bool is_cmd) { int rv = 0; assert(chan); /* Keep scan-build happy. */ switch (chan->state) { case AX25_CHAN_IN_OPEN: case AX25_CHAN_REM_DISC: case AX25_CHAN_REM_CLOSE: break; case AX25_CHAN_IN_CLOSE: if (pf) ax25_chan_send_rsp(chan, X25_DM, pf); break; case AX25_CHAN_OPEN: case AX25_CHAN_CLOSE_WAIT_DRAIN: chan->peer_rcv_bsy = true; rv = ax25_chan_handle_rr_rnr(chan, nr, pf, is_cmd); break; default: assert(0); } return rv; } static int ax25_chan_handle_rej(struct ax25_base *base, struct ax25_chan *chan, uint8_t nr, uint8_t pf, bool is_cmd) { assert(chan); /* Keep scan-build happy. */ switch (chan->state) { case AX25_CHAN_IN_OPEN: case AX25_CHAN_REM_DISC: case AX25_CHAN_REM_CLOSE: break; case AX25_CHAN_IN_CLOSE: if (pf) ax25_chan_send_rsp(chan, X25_DM, pf); break; case AX25_CHAN_OPEN: case AX25_CHAN_CLOSE_WAIT_DRAIN: if (chan->poll_pending) { if (!is_cmd && pf) { ax25_chan_recalc_t1(chan, false); ax25_chan_stop_t1(chan); } else if (is_cmd && pf) { ax25_chan_send_ack(chan, pf, false); } if (!ax25_chan_seq_in_range(chan, nr)) return GE_PROTOERR; chan->va = nr; if (chan->va == chan->vs) { if (!is_cmd && pf) ax25_chan_start_t3(chan); } else { ax25_chan_rewind_seq(chan, nr, false); } } else { ax25_chan_check_response_needed(chan, pf, is_cmd); if (!ax25_chan_seq_in_range(chan, nr)) return GE_PROTOERR; ax25_chan_recalc_t1(chan, false); ax25_chan_stop_t1(chan); ax25_chan_stop_t3(chan); ax25_chan_rewind_seq(chan, nr, false); } break; default: assert(0); } return 0; } static int ax25_chan_handle_srej(struct ax25_base *base, struct ax25_chan *chan, uint8_t nr, uint8_t pf, bool is_cmd) { assert(chan); /* Keep scan-build happy. */ switch (chan->state) { case AX25_CHAN_IN_OPEN: case AX25_CHAN_REM_DISC: case AX25_CHAN_REM_CLOSE: break; case AX25_CHAN_IN_CLOSE: if (pf) ax25_chan_send_rsp(chan, X25_DM, pf); break; case AX25_CHAN_OPEN: case AX25_CHAN_CLOSE_WAIT_DRAIN: if (chan->poll_pending) { if (!is_cmd) { ax25_chan_recalc_t1(chan, false); ax25_chan_stop_t1(chan); } if (!ax25_chan_seq_in_range(chan, nr)) return GE_PROTOERR; if (pf) chan->va = nr; if (chan->va == chan->vs) { if (!is_cmd) ax25_chan_start_t3(chan); } else { ax25_chan_rewind_seq(chan, nr, true); } } else { ax25_chan_check_response_needed(chan, pf, is_cmd); if (!ax25_chan_seq_in_range(chan, nr)) return GE_PROTOERR; ax25_chan_recalc_t1(chan, false); ax25_chan_stop_t1(chan); ax25_chan_stop_t3(chan); ax25_chan_rewind_seq(chan, nr, true); } break; default: assert(0); } return 0; } static void i_ax25_base_handle_child_err(struct ax25_base *base, int err) { struct gensio_list to_deliver; struct gensio_link *l, *l2; if (base->child_err) return; base->child_err = err; gensio_set_read_callback_enable(base->child, false); gensio_set_write_callback_enable(base->child, false); gensio_list_init(&to_deliver); ax25_base_set_state(base, AX25_BASE_CHILD_IO_ERR); if (base->waiting_first_open) { struct ax25_chan *chan = i_ax25_base_promote_first_chan(base); /* * Don't use set state here, chan lock isn't held, but it * doesn't matter. */ chan->state = AX25_CHAN_IN_OPEN; base->waiting_first_open = false; } gensio_list_for_each(&base->chans, l) { struct ax25_chan *chan = gensio_container_of(l, struct ax25_chan, link); if (ax25_chan_ref_if_nz(chan)) gensio_list_add_tail(&to_deliver, &chan->hold_err_link); } ax25_base_unlock(base); gensio_list_for_each_safe(&to_deliver, l, l2) { struct ax25_chan *chan = gensio_container_of(l, struct ax25_chan, hold_err_link); gensio_list_rm(&to_deliver, l); chan = ax25_chan_check_and_lock(chan, &base->chans, false); if (!chan) continue; chan->err = err; ax25_chan_do_err_close(chan, true); ax25_chan_deref_and_unlock(chan); } ax25_base_lock(base); ax25_base_child_close(base); } static void ax25_base_handle_child_err(struct ax25_base *base, int err) { ax25_base_lock_and_ref(base); i_ax25_base_handle_child_err(base, err); ax25_base_deref_and_unlock(base); } static int ax25_child_read(struct ax25_base *base, int ierr, unsigned char *buf, gensiods *ibuflen, const char *const *auxdata) { uint16_t crc; unsigned int port = 0, i; gensiods pos = 0, buflen; struct gensio_ax25_addr iaddr, addr; struct ax25_chan *chan; int err = 0; uint8_t cmd = 0, pf = 0, nr = 0, ns = 0; bool is_cmd; if (ierr) { ax25_base_handle_child_err(base, ierr); return 0; } buflen = *ibuflen; for (i = 0; auxdata && auxdata[i]; i++) { if (strncmp(auxdata[i], "tnc:", 4) == 0) port = strtoul(auxdata[i] + 4, NULL, 10); } /* We will always process the whole buffer, don't modify ibuflen. */ if (base->conf.do_crc) { uint16_t msgcrc; if (buflen < 2) return 0; msgcrc = (buf[buflen - 1] << 8) | buf[buflen - 2]; crc = 0xffff; crc16_ccitt(buf, buflen - 2, &crc); crc ^= 0xffff; if (msgcrc != crc) { if (base->conf.debug & GENSIO_AX25_DEBUG_MSG) printf(" CRC fails, was %4.4x, expected %4.4x", msgcrc, crc); return 0; } buflen -= 2; } if (base->conf.debug & GENSIO_AX25_DEBUG_MSG) ax25_print_msg(base, "R", buf, *ibuflen); ax25_chan_report_raw(base, port, buf, buflen); if (buflen < 14) return 0; pos = 0; err = decode_ax25_addr(base->o, buf, &pos, buflen, port, &iaddr); if (err) return 0; ax25_construct_return_addr(&addr, &iaddr); buflen -= pos; /* Ignore packets with subaddresses that have not yet been repeated. */ for (i = 0; i < iaddr.nr_extra; i++) { if (!iaddr.extra[i].ch) return 0; } if (buflen < 1) return 0; /* If it's an unumbered frame, it's always 1 byte. */ if ((buf[pos] & 0x3) == 0x3) { /* Unnumbered frame. */ pf = (buf[pos] >> 4) & 1; cmd = buf[pos++] & 0xef; buflen--; } /* * UI frames and heard reports are the only thing we let through * without a matching dest. */ ax25_chan_handle_report(base, &iaddr, cmd, buf + pos, buflen, pf); if (cmd == X25_UI) return 0; /* In both old and new protocol version, dest.ch sets if it's a cmd. */ is_cmd = iaddr.dest.ch; ax25_base_lock(base); chan = ax25_base_lookup_chan_by_addr(base, &addr.r); if (chan && !ax25_chan_ref_if_nz(chan)) chan = NULL; ax25_base_unlock(base); if (!chan) { bool match; ax25_addr_lock(base); match = ax25_iaddr_find(&base->listen_addrs, &iaddr.dest); ax25_addr_unlock(base); if (!match) /* No existing channel, not listening to this address. */ return 0; } if (chan) chan = ax25_chan_check_and_lock(chan, &base->chans, true); if (!cmd) { /* Extract data from I and S frames. */ if (chan) ax25_chan_trace_msg(chan, RCVD, is_cmd, cmd, buf + pos, buflen); else /* These are ignored if a connection isn't established. */ goto out_unlock; if (chan->extended && buflen < 2) goto out_unlock; if (chan->extended) { if ((buf[pos] & 0x1) == 0) { /* Information frame. */ cmd = X25_I; ns = (buf[pos] >> 1) & 0x7f; } else { /* Supervisory frame. */ cmd = buf[pos]; } } else { if ((buf[pos] & 0x1) == 0) { cmd = X25_I; ns = (buf[pos] >> 1) & 7; } else { /* Supervisory frame. */ cmd = buf[pos] & 0xf; } } if (chan->extended) { nr = (buf[pos + 1] >> 1) & 0x7f; pf = buf[pos + 1] & 1; pos += 2; buflen -= 2; } else { nr = (buf[pos] >> 5) & 7; pf = (buf[pos] >> 4) & 1; pos++; buflen--; } } else { if (chan) ax25_chan_trace_msg(chan, RCVD, is_cmd, cmd, buf + pos - 1, buflen + 1); } switch (cmd) { case X25_SABME: chan = ax25_chan_handle_sabm(base, chan, &addr, pf, is_cmd, true, buf + pos, buflen); break; case X25_SABM: chan = ax25_chan_handle_sabm(base, chan, &addr, pf, is_cmd, false, buf + pos, buflen); break; case X25_DISC: ax25_chan_handle_disc(base, chan, &addr, pf, is_cmd); break; case X25_DM: ax25_chan_handle_dm(base, chan, &addr, pf, is_cmd); break; case X25_UA: ax25_chan_handle_ua(base, chan, &addr, pf, is_cmd, buf + pos, buflen); break; case X25_FRMR: ax25_chan_handle_frmr(base, chan, &addr, pf, is_cmd, buf + pos, buflen); break; case X25_XID: ax25_chan_handle_xid(base, chan, &addr, pf, is_cmd, buf + pos, buflen); break; case X25_TEST: ax25_chan_handle_test(base, chan, &addr, pf, is_cmd, buf + pos, buflen); break; case X25_I: err = ax25_chan_handle_i(base, chan, &addr, nr, ns, pf, is_cmd, buf + pos, buflen); break; case X25_RR: err = ax25_chan_handle_rr(base, chan, nr, pf, is_cmd); break; case X25_RNR: err = ax25_chan_handle_rnr(base, chan, nr, pf, is_cmd); break; case X25_REJ: err = ax25_chan_handle_rej(base, chan, nr, pf, is_cmd); break; case X25_SREJ: err = ax25_chan_handle_srej(base, chan, nr, pf, is_cmd); break; default: break; } if (err && chan) { chan->err = err; ax25_chan_do_err_close(chan, true); ax25_chan_stop_t3(chan); ax25_chan_stop_t1(chan); } out_unlock: if (chan) ax25_chan_deref_and_unlock(chan); return 0; } static void crc16_sg(const struct gensio_sg *sg, gensiods sglen, unsigned char *outcrc) { uint16_t crc = 0xffff; gensiods i; for (i = 0; i < sglen; i++) crc16_ccitt(sg[i].buf, sg[i].buflen, &crc); crc ^= 0xffff; outcrc[0] = crc & 0xff; outcrc[1] = (crc >> 8) & 0xff; } static bool ax25_chan_in_writable_state(struct ax25_chan *chan) { switch (chan->state) { case AX25_CHAN_IN_OPEN: case AX25_CHAN_OPEN: case AX25_CHAN_CLOSE_WAIT_DRAIN: case AX25_CHAN_IN_CLOSE: case AX25_CHAN_REM_DISC: case AX25_CHAN_REM_CLOSE: return true; default: return false; } } static int ax25_child_write_ready(struct ax25_base *base) { struct gensio_link *l; struct ax25_chan *chan = NULL; struct ax25_data *d; struct ax25_chan_cmdrsp *ccr; struct ax25_base_cmdrsp *bcr; struct ax25_raw_data *raw; unsigned char crv[3], crc[2], xid[AX25_XID_SIZE]; struct gensio_sg sg[4]; gensiods sglen, len, sendcnt; int rv; bool re_add_chan; ax25_base_lock_and_ref(base); gensio_set_write_callback_enable(base->child, false); while (!gensio_list_empty(&base->send_list)) { l = gensio_list_first(&base->send_list); gensio_list_rm(&base->send_list, l); chan = gensio_container_of(l, struct ax25_chan, sendlink); /* Already refcounted. */ ax25_base_unlock(base); chan = ax25_chan_check_and_lock(chan, &base->chans, false); if (!chan) goto skip; if (chan->cmdrsp_len > 0) { ccr = &(chan->cmdrsp[chan->cmdrsp_pos]); /* Set command/response. */ if (ccr->is_cmd) { chan->encoded_addr[6] |= 0x80; chan->encoded_addr[13] &= ~0x80; } else { chan->encoded_addr[6] &= ~0x80; chan->encoded_addr[13] |= 0x80; } sg[0].buf = chan->encoded_addr; sg[0].buflen = chan->encoded_addr_len; len = sg[0].buflen; sg[1].buf = crv; if ((ccr->cr & 0x3) == 0x1) { uint8_t cmd = ccr->cr; /* * Wait until the last possible moment to decide to * send an RNR. */ if (ccr->cr == X25_RR && chan->own_rcv_bsy) cmd = X25_RNR; /* * If sending a REJ, there's no point if the rej is * already cleared. */ else if (ccr->cr == X25_REJ && !chan->in_rej) goto skip_cmdrsp; /* Supervisory message, put ack value into it. */ if (chan->extended) { crv[0] = cmd; crv[1] = (chan->vr << 1) | ccr->pf; sg[1].buflen = 2; } else { crv[0] = (chan->vr << 5) | (ccr->pf << 4) | cmd; sg[1].buflen = 1; } } else { crv[0] = (ccr->pf << 4) | ccr->cr; sg[1].buflen = 1; } ax25_chan_trace_msg(chan, SENT, ccr->is_cmd, ccr->cr, crv, sg[1].buflen); len += sg[1].buflen; sglen = 2; if (ccr->cr == X25_XID) { sg[sglen].buf = xid; sg[sglen].buflen = sizeof(xid); ax25_chan_format_xid(chan, xid); sglen++; len += sizeof(xid); } else if (ccr->extra_data_size) { sg[sglen].buf = ccr->extra_data; sg[sglen].buflen = ccr->extra_data_size; sglen++; len += ccr->extra_data_size; } if (base->conf.do_crc) { crc16_sg(sg, sglen, crc); sg[sglen].buf = crc; sg[sglen].buflen = 2; sglen++; len += 2; } if (base->conf.debug & GENSIO_AX25_DEBUG_MSG) ax25_print_msg_sg(base, "W", sg, sglen); rv = gensio_write_sg(base->child, &sendcnt, sg, sglen, NULL); if (rv) goto out_err_chan; if (sendcnt == 0) goto out_reenable_chan; if (sendcnt != len) { rv = GE_IOERR; goto out_err_chan; } skip_cmdrsp: chan->cmdrsp_pos = (chan->cmdrsp_pos + 1) % AX25_CHAN_MAX_CMDRSP; chan->cmdrsp_len--; if (chan->state == AX25_CHAN_REM_DISC || chan->state == AX25_CHAN_REM_CLOSE) { if (chan->state == AX25_CHAN_REM_DISC) ax25_chan_do_err_close(chan, true); else if (chan->state == AX25_CHAN_REM_CLOSE) ax25_chan_do_close(chan); } } else if (!chan->peer_rcv_bsy && chan->send_len > 0) { unsigned int pos = sub_seq(chan->write_pos, chan->send_len, chan->conf.writewindow); unsigned int p = 0; d = &(chan->write_data[pos]); if (!d->present) { chan->send_len--; goto skip; } /* Set command. */ chan->encoded_addr[6] |= 0x80; chan->encoded_addr[13] &= ~0x80; sg[0].buf = chan->encoded_addr; sg[0].buflen = chan->encoded_addr_len; len = sg[0].buflen; sg[1].buf = crv; /* * If our transmit window is closing with this packet, set the * p bit to get an immediate response. */ if (sub_seq(chan->vs, chan->va, chan->modulo) >= chan->writewindow){ p = 1; chan->data_p_sent = true; } if (chan->extended) { crv[0] = d->seq << 1; crv[1] = chan->vr << 1 | p; crv[2] = d->pid; sg[1].buflen = 3; len += 3; } else { crv[0] = (chan->vr << 5) | (p << 4) | (d->seq << 1); crv[1] = d->pid; sg[1].buflen = 2; len += 2; } chan->ack_pending = 0; /* Sent an ack. */ ax25_chan_stop_t2(chan); ax25_chan_trace_msg(chan, SENT, true, 0, crv, sg[1].buflen); sg[2].buf = d->data; sg[2].buflen = d->len; len += d->len; sglen = 3; if (base->conf.do_crc) { crc16_sg(sg, sglen, crc); sg[3].buf = crc; sg[3].buflen = 2; sglen++; len += 2; } if (chan->conf.drop_pos && chan->curr_drop == chan->conf.drop_pos) { rv = 0; chan->curr_drop = 0; sendcnt = len; } else { if (base->conf.debug & GENSIO_AX25_DEBUG_MSG) ax25_print_msg_sg(base, "W", sg, sglen); rv = gensio_write_sg(base->child, &sendcnt, sg, sglen, NULL); chan->curr_drop++; } if (rv) goto out_err_chan; if (sendcnt == 0) goto out_reenable_chan; d->present = false; if (sendcnt != len) { rv = GE_IOERR; goto out_err_chan; } chan->send_len--; if (!chan->t1) { ax25_chan_stop_t3(chan); ax25_chan_start_t1(chan); } if (chan->state == AX25_CHAN_CLOSE_WAIT_DRAIN && chan->send_len == 0) { /* We abuse timer recovery to get a quick response. */ chan->retry_count = 1; chan->poll_pending = true; ax25_chan_transmit_enquiry(chan); } } else if (!gensio_list_empty(&chan->raws)) { unsigned char *buf; l = gensio_list_first(&chan->raws); raw = gensio_container_of(l, struct ax25_raw_data, link); buf = ((unsigned char *) raw) + sizeof(*raw); if (base->conf.debug & GENSIO_AX25_DEBUG_MSG) ax25_print_msg(base, "W", buf, raw->len); rv = gensio_write(base->child, &sendcnt, buf, raw->len, NULL); if (rv) goto out_err_chan; if (sendcnt == 0) goto out_reenable_chan; if (sendcnt != raw->len) { rv = GE_IOERR; goto out_err_chan; } gensio_list_rm(&chan->raws, l); chan->o->free(chan->o, raw); } skip: re_add_chan = false; if (chan) { re_add_chan = ((!chan->peer_rcv_bsy && chan->send_len > 0) || chan->cmdrsp_len > 0 || !gensio_list_empty(&chan->raws)); if (re_add_chan) ax25_chan_unlock(chan); else ax25_chan_deref_and_unlock(chan); } ax25_base_lock(base); if (re_add_chan) { if (gensio_list_link_inlist(&chan->sendlink)) ax25_chan_deref(chan); /* Another queue operation ref-ed it. */ else gensio_list_add_tail(&base->send_list, &chan->sendlink); } chan = NULL; } while (base->cmdrsp_len > 0) { bcr = &(base->cmdrsp[base->cmdrsp_pos]); sg[0].buf = bcr->addr; sg[0].buflen = bcr->addrlen; len = sg[0].buflen; sg[1].buf = crv; crv[0] = bcr->cr; sg[1].buflen = 1; len += 1; sglen = 2; if (bcr->extra_data_size) { sg[sglen].buf = bcr->extra_data; sg[sglen].buflen = bcr->extra_data_size; sglen++; len += bcr->extra_data_size; } if (base->conf.do_crc) { crc16_sg(sg, sglen, crc); sg[sglen].buf = crc; sg[sglen].buflen = 2; sglen++; len += 2; } rv = gensio_write_sg(base->child, &sendcnt, sg, sglen, NULL); if (rv) goto out_err_base; if (sendcnt == 0) goto out_reenable_base; if (sendcnt != len) { rv = GE_IOERR; goto out_err_base; } base->cmdrsp_pos = add_seq(base->cmdrsp_pos, 1, AX25_BASE_MAX_CMDRSP); base->cmdrsp_len--; } if (base->state == AX25_BASE_CLOSE_WAIT_DRAIN) ax25_base_child_close(base); ax25_base_deref_and_unlock(base); return 0; out_reenable_chan: /* A write didn't complete, Reenable so we can know when we can finish. */ ax25_base_lock(base); re_add_chan = true; if (!gensio_list_link_inlist(&chan->sendlink)) gensio_list_add_head(&base->send_list, &chan->sendlink); else re_add_chan = false; if (ax25_chan_in_writable_state(chan)) gensio_set_write_callback_enable(base->child, true); ax25_base_deref_and_unlock(base); if (re_add_chan) ax25_chan_unlock(chan); /* requeued, don't deref. */ else ax25_chan_deref_and_unlock(chan); return 0; out_err_chan: ax25_chan_deref_and_unlock(chan); ax25_base_lock(base); i_ax25_base_handle_child_err(base, rv); ax25_base_deref_and_unlock(base); return 0; out_reenable_base: /* A write didn't complete, Reenable so we can know when we can finish. */ if (base->state == AX25_BASE_OPEN) gensio_set_write_callback_enable(base->child, true); ax25_base_deref_and_unlock(base); return 0; out_err_base: i_ax25_base_handle_child_err(base, rv); ax25_base_deref_and_unlock(base); return 0; } static int ax25_child_cb(struct gensio *io, void *user_data, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) { struct ax25_base *base = user_data; int rv; switch (event) { case GENSIO_EVENT_READ: return ax25_child_read(base, err, buf, buflen, auxdata); case GENSIO_EVENT_WRITE_READY: return ax25_child_write_ready(base); case GENSIO_EVENT_NEW_CHANNEL: return GE_NOTSUP; default: rv = ax25_firstchan_event(base, event, err, buf, buflen, auxdata); return rv; } } static gensiods ax25_add_crc(unsigned char *buf, gensiods len) { uint16_t crc = 0xffff; crc16_ccitt(buf, len, &crc); crc ^= 0xffff; buf[len++] = crc & 0xff; buf[len++] = (crc >> 8) & 0xff; return len; } static int ax25_chan_send_raw(struct ax25_chan *chan, gensiods *rcount, unsigned int tnc_port, gensiods datalen, const struct gensio_sg *sg, gensiods sglen) { struct ax25_raw_data *raw; unsigned char *buf; unsigned int i, len, pos; len = sizeof(*raw) + datalen; if (chan->base->conf.do_crc) len += 2; raw = chan->o->zalloc(chan->o, len); if (!raw) return 0; buf = ((unsigned char *) raw) + sizeof(*raw); for (pos = 0, i = 0; i < sglen; i++) { memcpy(buf + pos, sg[i].buf, sg[i].buflen); pos += sg[i].buflen; } if (chan->base->conf.do_crc) pos = ax25_add_crc(buf, pos); raw->len = pos; ax25_base_lock(chan->base); gensio_list_add_tail(&chan->raws, &raw->link); i_ax25_chan_schedule_write(chan); ax25_base_unlock(chan->base); *rcount = datalen; return 0; } static int ax25_chan_send_ui(struct ax25_chan *chan, struct gensio_addr *addr, gensiods *rcount, uint8_t pid, gensiods datalen, const struct gensio_sg *sg, gensiods sglen) { struct ax25_raw_data *raw; unsigned char *buf; gensiods len, pos; unsigned int i; /* + 2 for the UI and PID */ len = sizeof(*raw) + datalen + ax25_addr_encode_len(addr) + 2; if (chan->base->conf.do_crc) len += 2; raw = chan->o->zalloc(chan->o, len); if (!raw) return 0; buf = ((unsigned char *) raw) + sizeof(*raw); pos = ax25_addr_encode(buf, addr); buf[pos++] = 0x03; /* UI with P/F clear */ buf[pos++] = pid; for (i = 0; i < sglen; i++) { memcpy(buf + pos, sg[i].buf, sg[i].buflen); pos += sg[i].buflen; } /* Set the C/R bits to response. */ buf[6] &= ~0x80; buf[13] |= 0x80; if (chan->base->conf.do_crc) pos = ax25_add_crc(buf, pos); raw->len = pos; ax25_base_lock(chan->base); gensio_list_add_tail(&chan->raws, &raw->link); i_ax25_chan_schedule_write(chan); ax25_base_unlock(chan->base); *rcount = datalen; return 0; } static int ax25_chan_write(struct ax25_chan *chan, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { int rv = 0; struct ax25_data *d; gensiods len, left, pos; unsigned int i, tnc_port = 0; uint8_t pid = chan->conf.pid; bool raw = false; bool oob = false; for (len = 0, i = 0; i < sglen; i++) len += sg[i].buflen; for (i = 0; auxdata && auxdata[i]; i++) { if (strncmp(auxdata[i], "pid:", 4) == 0) pid = strtoul(auxdata[i] + 4, NULL, 0); if (strncmp(auxdata[i], "tnc:", 5) == 0) tnc_port = strtoul(auxdata[i] + 5, NULL, 0); if (strcmp(auxdata[i], "raw") == 0) raw = true; if (strcmp(auxdata[i], "oob") == 0) oob = true; } if (raw) { if (len > chan->conf.max_write_size) len = chan->conf.max_write_size; ax25_chan_lock(chan); rv = ax25_chan_send_raw(chan, rcount, tnc_port, len, sg, sglen); goto out_unlock; } if (oob) { const char *addrstr = NULL; struct gensio_addr *addr; if (len > chan->conf.max_write_size) len = chan->conf.max_write_size; ax25_chan_lock(chan); if (chan->state != AX25_CHAN_OPEN && chan->state != AX25_CHAN_NOCON) { rv = GE_NOTREADY; goto out_unlock; } for (i = 0; auxdata && auxdata[i]; i++) { if (strncmp(auxdata[i], "addr:", 5) == 0) { addrstr = auxdata[i] + 5; break; } } if (!addrstr) { rv = GE_INVAL; goto out_unlock; } rv = gensio_ax25_str_to_addr(chan->o, addrstr, &addr); if (rv) { rv = 0; goto out_unlock; } rv = ax25_chan_send_ui(chan, addr, rcount, pid, len, sg, sglen); gensio_addr_free(addr); goto out_unlock; } if (len > chan->max_write_size) len = chan->max_write_size; ax25_chan_lock(chan); if (chan->state != AX25_CHAN_OPEN) { if (chan->err) rv = chan->err; else rv = GE_NOTREADY; goto out_unlock; } if (chan->write_len >= chan->writewindow) { *rcount = 0; goto out_unlock; } d = &(chan->write_data[chan->write_pos]); d->pid = pid; for (left = len, pos = 0, i = 0; i < sglen; i++) { if (sg[i].buflen > left) { memcpy(((char *) d->data) + pos, sg[i].buf, left); } else { memcpy(((char *) d->data) + pos, sg[i].buf, sg[i].buflen); } left -= sg[i].buflen; pos += sg[i].buflen; } *rcount = len; d->len = len; d->seq = chan->vs; d->present = true; chan->vs = add_seq(chan->vs, 1, chan->modulo); chan->write_pos = add_seq(chan->write_pos, 1, chan->conf.writewindow); chan->write_len++; chan->send_len++; assert(chan->send_len <= chan->conf.writewindow); if (!chan->peer_rcv_bsy) ax25_chan_schedule_write(chan); out_unlock: ax25_chan_unlock(chan); return rv; } /* Must be called with the channel lock held. */ static int i_ax25_chan_open(struct ax25_chan *chan, gensio_done_err open_done, void *open_data) { struct ax25_base *base = chan->base; int err = 0; if (chan->state != AX25_CHAN_CLOSED) return GE_INUSE; ax25_base_lock(base); if (chan->conf.addr && ax25_base_lookup_chan_by_addr(base, chan->conf.addr)) { ax25_base_unlock(base); /* There's already a non-closed connection with this address. */ return GE_ADDRINUSE; } chan->writewindow = chan->conf.writewindow; chan->readwindow = chan->conf.readwindow; chan->max_write_size = chan->conf.max_write_size; chan->max_retries = chan->conf.max_retries; chan->err = 0; switch (base->state) { case AX25_BASE_CHILD_IO_ERR: case AX25_BASE_IN_CHILD_CLOSE: ax25_chan_set_state(chan, AX25_CHAN_WAITING_OPEN); gensio_list_rm(&base->chans_closed, &chan->link); gensio_list_add_tail(&base->chans_waiting_open, &chan->link); break; case AX25_BASE_CLOSED: err = ax25_base_start_open(base); if (err) break; /* fallthrough */ case AX25_BASE_IN_CHILD_OPEN: ax25_chan_set_state(chan, AX25_CHAN_WAITING_OPEN); gensio_list_rm(&base->chans_closed, &chan->link); gensio_list_add_tail(&base->chans_waiting_open, &chan->link); break; case AX25_BASE_OPEN: gensio_list_rm(&base->chans_closed, &chan->link); gensio_list_add_tail(&base->chans, &chan->link); ax25_chan_prestart_connect(chan); ax25_base_unlock(base); ax25_chan_start_connect(chan); ax25_base_lock(base); break; default: assert(0); } ax25_base_unlock(base); if (!err) { chan->open_done = open_done; chan->open_data = open_data; } return err; } static int ax25_chan_open(struct ax25_chan *chan, gensio_done_err open_done, void *open_data) { int err; if (!open_done) return GE_INVAL; ax25_chan_lock(chan); err = i_ax25_chan_open(chan, open_done, open_data); ax25_chan_unlock(chan); return err; } static int ax25_chan_open_nochild(struct ax25_chan *chan, gensio_done_err open_done, void *open_data) { struct ax25_base *base = chan->base; int err; if (!open_done) return GE_INVAL; ax25_chan_lock(chan); if (base->state != AX25_BASE_CLOSED) { err = GE_NOTREADY; } else { base->child_err = 0; ax25_base_set_state(base, AX25_BASE_OPEN); ax25_base_ref(chan->base); err = i_ax25_chan_open(chan, open_done, open_data); if (err) ax25_base_set_state(base, AX25_BASE_CLOSED); else gensio_set_read_callback_enable(base->child, true); } ax25_chan_unlock(chan); return err; } /* Must be called with the channel lock held. */ static int i_ax25_chan_close(struct ax25_chan *chan, gensio_done close_done, void *close_data) { struct ax25_base *base = chan->base; int err = 0; switch (chan->state) { case AX25_CHAN_CLOSED: case AX25_CHAN_IN_CLOSE: case AX25_CHAN_REPORT_CLOSE: case AX25_CHAN_CLOSE_WAIT_DRAIN: case AX25_CHAN_REM_CLOSE: err = GE_NOTREADY; break; case AX25_CHAN_REM_DISC: ax25_chan_set_state(chan, AX25_CHAN_REM_CLOSE); break; case AX25_CHAN_WAITING_OPEN: ax25_chan_set_state(chan, AX25_CHAN_REPORT_CLOSE); ax25_chan_move_to_closed(chan, &base->chans_waiting_open); ax25_chan_sched_deferred_op(chan); break; case AX25_CHAN_NOCON_IN_OPEN: case AX25_CHAN_NOCON: ax25_chan_set_state(chan, AX25_CHAN_REPORT_CLOSE); ax25_chan_move_to_closed(chan, &base->chans); ax25_chan_sched_deferred_op(chan); break; case AX25_CHAN_IO_ERR: ax25_chan_set_state(chan, AX25_CHAN_REPORT_CLOSE); ax25_chan_sched_deferred_op(chan); break; case AX25_CHAN_IN_OPEN: case AX25_CHAN_OPEN: if (chan->in_newchannel == 1) { ax25_chan_set_state(chan, AX25_CHAN_CLOSED); ax25_chan_move_to_closed(chan, &base->chans); chan->in_newchannel = 2; } else if (chan->in_newchannel == 0) { if (chan->state == AX25_CHAN_IN_OPEN) { chan->retry_count = 0; chan->err = GE_LOCALCLOSED; ax25_chan_send_cmd(chan, X25_DM, 1); ax25_chan_set_state(chan, AX25_CHAN_REPORT_CLOSE); ax25_chan_move_to_closed(chan, &base->chans); ax25_chan_sched_deferred_op(chan); } else if (chan->write_len > 0) { /* We abuse timer recovery to get a quick response. */ chan->retry_count = 1; chan->poll_pending = true; ax25_chan_transmit_enquiry(chan); ax25_chan_set_state(chan, AX25_CHAN_CLOSE_WAIT_DRAIN); } else { chan->retry_count = 0; if (chan->ack_pending) /* Make sure to ack anything pending. */ ax25_chan_send_ack(chan, 0, 0); ax25_chan_send_cmd(chan, X25_DISC, 1); ax25_chan_set_state(chan, AX25_CHAN_IN_CLOSE); } ax25_chan_start_t1(chan); ax25_chan_stop_t3(chan); } break; default: assert(0); } if (!err) { ax25_chan_ref(chan); chan->close_done = close_done; chan->close_data = close_data; } return err; } static int ax25_chan_close(struct ax25_chan *chan, gensio_done close_done, void *close_data) { int err; ax25_chan_lock(chan); err = i_ax25_chan_close(chan, close_done, close_data); ax25_chan_unlock(chan); return err; } static void ax25_chan_free(struct ax25_chan *chan) { ax25_chan_lock(chan); switch (chan->state) { case AX25_CHAN_REPORT_CLOSE: /* Undo the close call and just free it. */ ax25_chan_deref(chan); chan->open_done = NULL; chan->close_done = NULL; break; case AX25_CHAN_IO_ERR: case AX25_CHAN_CLOSED: /* We can free immediately. */ break; case AX25_CHAN_IN_OPEN: case AX25_CHAN_OPEN: /* Need to close before we can free */ i_ax25_chan_close(chan, NULL, NULL); break; case AX25_CHAN_IN_CLOSE: case AX25_CHAN_REM_DISC: case AX25_CHAN_REM_CLOSE: case AX25_CHAN_CLOSE_WAIT_DRAIN: /* In the close process, lose a ref so it will free when done. */ /* Don't call the done */ chan->close_done = NULL; break; default: assert(0); } chan->freed = true; /* Lose the initial ref so it will be freed when done. */ ax25_chan_deref_and_unlock(chan); } static void ax25_chan_set_read_callback_enable(struct ax25_chan *chan, bool enabled) { ax25_chan_lock(chan); if (chan->read_enabled != enabled) { chan->read_enabled = enabled; if (enabled && chan_can_read(chan)) ax25_chan_sched_deferred_op(chan); } ax25_chan_unlock(chan); } static void ax25_chan_set_write_callback_enable(struct ax25_chan *chan, bool enabled) { ax25_chan_lock(chan); if (chan->xmit_enabled != enabled) { chan->xmit_enabled = enabled; if (enabled && chan_can_write(chan)) ax25_chan_sched_deferred_op(chan); } ax25_chan_unlock(chan); } static int ax25_alloc_channel(struct ax25_chan *dummy, struct gensio_func_alloc_channel_data *ocdata) { struct ax25_base *base = dummy->base; struct ax25_chan *chan; int rv; rv = ax25_chan_alloc(base, ocdata->args, ocdata->cb, ocdata->user_data, AX25_CHAN_CLOSED, NULL, false, &chan); if (rv) return rv; ocdata->new_io = chan->io; return 0; } static int ax25_chan_control(struct ax25_chan *chan, bool get, int option, char *data, gensiods *datalen) { int rv = 0; gensiods pos; unsigned int i; struct gensio_link *l, *l2; struct gensio_ax25_subaddr addr; switch (option) { case GENSIO_CONTROL_ENABLE_OOB: if (get) *datalen = snprintf(data, *datalen, "%u", chan->report_ui); else chan->report_ui = strtoul(data, NULL, 0); break; case GENSIO_CONTROL_MAX_WRITE_PACKET: if (!get) return GE_NOTSUP; *datalen = snprintf(data, *datalen, "%u", chan->max_write_size); break; case GENSIO_CONTROL_LADDR: if (!get) return GE_NOTSUP; i = strtoul(data, NULL, 0); rv = GE_NOTFOUND; ax25_addr_lock(chan->base); gensio_list_for_each(&chan->base->listen_addrs, l) { if (i == 0) { struct ax25_iaddr *iaddr = to_ax25_iaddr(l); pos = 0; rv = ax25_subaddr_to_str(&iaddr->addr, data, &pos, *datalen, false); if (!rv) *datalen = pos; break; } i--; } ax25_addr_unlock(chan->base); return rv; case GENSIO_CONTROL_ADD_LADDR: if (get) return GE_NOTSUP; rv = ax25_str_to_subaddr((char *) data, &addr, false); if (rv) break; ax25_addr_lock(chan->base); if (ax25_iaddr_find(&chan->base->listen_addrs, &addr)) rv = GE_EXISTS; else rv = ax25_add_iaddr(chan->o, &chan->base->listen_addrs, &addr); ax25_addr_unlock(chan->base); return rv; case GENSIO_CONTROL_DEL_LADDR: if (get) return GE_NOTSUP; rv = ax25_str_to_subaddr((char *) data, &addr, false); if (rv) break; ax25_addr_lock(chan->base); rv = ax25_del_iaddr(chan->o, &chan->base->listen_addrs, &addr); ax25_addr_unlock(chan->base); return rv; case GENSIO_CONTROL_GET_MCAST: if (!get) return GE_NOTSUP; i = strtoul(data, NULL, 0); rv = GE_NOTFOUND; ax25_ui_addr_lock(chan); gensio_list_for_each(&chan->ui_addrs, l) { if (i == 0) { struct ax25_iaddr *iaddr = to_ax25_iaddr(l); pos = 0; rv = ax25_subaddr_to_str(&iaddr->addr, data, &pos, *datalen, false); if (!rv) *datalen = pos; break; } i--; } ax25_ui_addr_unlock(chan); return rv; case GENSIO_CONTROL_ADD_MCAST: if (get) return GE_NOTSUP; rv = ax25_str_to_subaddr((char *) data, &addr, false); if (rv) break; ax25_ui_addr_lock(chan); if (ax25_iaddr_find(&chan->ui_addrs, &addr)) rv = GE_EXISTS; else rv = ax25_add_iaddr(chan->o, &chan->ui_addrs, &addr); ax25_ui_addr_unlock(chan); return rv; case GENSIO_CONTROL_DEL_MCAST: if (get) return GE_NOTSUP; rv = ax25_str_to_subaddr((char *) data, &addr, false); if (rv) break; ax25_ui_addr_lock(chan); rv = ax25_del_iaddr(chan->o, &chan->ui_addrs, &addr); ax25_ui_addr_unlock(chan); return rv; case GENSIO_CONTROL_RADDR: if (!get) return GE_NOTSUP; i = strtoul(data, NULL, 0); if (i > 0 || !chan->conf.addr) return GE_NOTFOUND; pos = 0; rv = gensio_addr_to_str(chan->conf.addr, data, &pos, *datalen); if (!rv) *datalen = pos; break; case GENSIO_CONTROL_RADDR_BIN: if (!get) return GE_NOTSUP; i = strtoul(data, NULL, 0); if (i > 0 || !chan->conf.addr) return GE_NOTFOUND; gensio_addr_getaddr(chan->conf.addr, data, datalen); break; case GENSIO_CONTROL_DRAIN_COUNT: if (!get) return GE_NOTSUP; i = strtoul(data, NULL, 0); if (i == 0) { ax25_chan_lock(chan); i = chan->write_len; gensio_list_for_each(&chan->raws, l) i++; ax25_chan_unlock(chan); *datalen = snprintf(data, *datalen, "%u", i); } else if (i == 1) { struct ax25_base *base = chan->base; struct gensio_list to_count; i = 0; gensio_list_init(&to_count); ax25_base_lock(base); gensio_list_for_each(&base->chans, l) { struct ax25_chan *chan; chan = gensio_container_of(l, struct ax25_chan, link); if (ax25_chan_ref_if_nz(chan)) gensio_list_add_tail(&to_count, &chan->hold_count_link); } ax25_base_unlock(base); gensio_list_for_each_safe(&to_count, l, l2) { struct ax25_chan *chan2; chan2 = gensio_container_of(l, struct ax25_chan, hold_count_link); gensio_list_rm(&to_count, l); chan2 = ax25_chan_check_and_lock(chan2, &chan2->base->chans, true); if (!chan2) continue; i += chan2->write_len; gensio_list_for_each(&chan2->raws, l) i++; ax25_chan_deref_and_unlock(chan2); } *datalen = snprintf(data, *datalen, "%u", i); } else { return GE_NOTFOUND; } break; default: rv = GE_NOTSUP; break; } return rv; } static int ax25_chan_func(struct gensio *io, int func, gensiods *count, const void *cbuf, gensiods buflen, void *buf, const char *const *auxdata) { struct ax25_chan *chan = gensio_get_gensio_data(io); struct ax25_base *base = chan->base; switch (func) { case GENSIO_FUNC_WRITE_SG: return ax25_chan_write(chan, count, cbuf, buflen, auxdata); case GENSIO_FUNC_OPEN: return ax25_chan_open(chan, (void *) cbuf, buf); case GENSIO_FUNC_OPEN_NOCHILD: return ax25_chan_open_nochild(chan, (void *) cbuf, buf); case GENSIO_FUNC_ALLOC_CHANNEL: return ax25_alloc_channel(chan, buf); case GENSIO_FUNC_CLOSE: return ax25_chan_close(chan, (void *) cbuf, buf); case GENSIO_FUNC_FREE: ax25_chan_free(chan); return 0; case GENSIO_FUNC_SET_READ_CALLBACK: ax25_chan_set_read_callback_enable(chan, buflen); return 0; case GENSIO_FUNC_SET_WRITE_CALLBACK: ax25_chan_set_write_callback_enable(chan, buflen); return 0; case GENSIO_FUNC_CONTROL: return ax25_chan_control(chan, *((bool *) cbuf), buflen, buf, count); case GENSIO_FUNC_DISABLE: if (chan->state != AX25_CHAN_CLOSED) { ax25_chan_reset_data(chan); ax25_chan_set_state(chan, AX25_CHAN_CLOSED); if (base->child) gensio_disable(base->child); } return 0; default: return GE_NOTSUP; } } static int ax25_scan_laddrs(struct gensio_os_funcs *o, const char *str, struct gensio_ax25_subaddr **raddrs, unsigned int *rnum_addrs) { char addrstr[10], *s2; unsigned int count = 1, i, len; int rv; struct gensio_ax25_subaddr *addrs; s2 = strchr(str, ';'); while (s2) { s2 = strchr(s2 + 1, ';'); count++; } addrs = o->zalloc(o, sizeof(*addrs) * count); if (!addrs) return GE_NOMEM; for (i = 0; i < count; i++) { s2 = strchr(str, ';'); if (s2) len = s2 - str; else len = strlen(str); if (len > 9) { o->free(o, addrs); return GE_INVAL; } memcpy(addrstr, str, len); addrstr[len] = '\0'; rv = ax25_str_to_subaddr(str, &(addrs[i]), false); if (rv) { o->free(o, addrs); return rv; } if (s2) str = s2 + 1; } if (*raddrs) o->free(o, *raddrs); *raddrs = addrs; *rnum_addrs = count; return 0; } static int ax25_readconf(struct gensio_pparm_info *p, struct gensio_os_funcs *o, bool firstchan, bool noaddr, struct ax25_conf_data *conf, const char *const args[]) { int rv = 0; unsigned int i; const char *str; for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(p, args[i], "readbuf", &conf->max_read_size) > 0) continue; if (gensio_pparm_ds(p, args[i], "writebuf", &conf->max_write_size) > 0) continue; if (gensio_pparm_uint(p, args[i], "readwindow", &conf->readwindow) > 0) continue; if (gensio_pparm_uint(p, args[i], "writewindow", &conf->writewindow) > 0) { conf->writewindow_set = true; continue; } if (gensio_pparm_uint(p, args[i], "debug", &conf->debug) > 0) continue; if (gensio_pparm_uint(p, args[i], "extended", &conf->extended) > 0) { if (conf->extended > 2) goto out_err; continue; } if (!noaddr &&!conf->addr && gensio_pparm_value(p, args[i], "addr", &str)) { rv = gensio_ax25_str_to_addr(o, str, &conf->addr); if (rv) goto out_err; continue; } if (firstchan && gensio_pparm_value(p, args[i], "uiaddr", &str)) { rv = ax25_scan_laddrs(o, str, &conf->conf_uiaddrs, &conf->num_conf_uiaddrs); if (rv) goto out_err; continue; } /* Only pick up listen addresses from the first allocation. */ if (firstchan && gensio_pparm_value(p, args[i], "laddr", &str)) { rv = ax25_scan_laddrs(o, str, &conf->conf_laddrs, &conf->num_conf_laddrs); if (rv) goto out_err; continue; } /* * "crc" has to do with the TNC connections, so it's only applicable * on the initial allocation. */ if (firstchan & gensio_pparm_bool(p, args[i], "crc", &conf->do_crc)) continue; if (gensio_pparm_bool(p, args[i], "ign_emb_ua", &conf->ignore_embedded_ua)) continue; if (gensio_pparm_uint(p, args[i], "srt", &conf->srtv) > 0) continue; if (gensio_pparm_uint(p, args[i], "t2", &conf->t2v) > 0) continue; if (gensio_pparm_uint(p, args[i], "t3", &conf->t3v) > 0) continue; if (gensio_pparm_uint(p, args[i], "retries", &conf->max_retries) > 0) continue; if (gensio_pparm_uint(p, args[i], "pid", &conf->pid) > 0) continue; if (gensio_pparm_bool(p, args[i], "heard", &conf->report_heard) > 0) continue; if (gensio_pparm_bool(p, args[i], "raw", &conf->report_raw) > 0) continue; /* Undocumented, used for testing. */ if (gensio_pparm_uint(p, args[i], "drop", &conf->drop_pos) > 0) continue; gensio_pparm_unknown_parm(p, args[i]); rv = GE_INVAL; goto out_err; } if (conf->srtv == 0) { gensio_pparm_slog(p, "srt cannot be zero"); rv = GE_INVAL; goto out_err; } if (conf->t2v == 0) { gensio_pparm_slog(p, "t2 cannot be zero"); rv = GE_INVAL; goto out_err; } if (conf->t3v == 0) { gensio_pparm_slog(p, "t3 cannot be zero"); rv = GE_INVAL; goto out_err; } if (conf->readwindow == 0) { gensio_pparm_slog(p, "readwindow cannot be zero"); rv = GE_INVAL; goto out_err; } if (conf->writewindow == 0) { gensio_pparm_slog(p, "writewindow cannot be zero"); rv = GE_INVAL; goto out_err; } if (conf->extended) { if (conf->writewindow > 127) { gensio_pparm_slog(p, "writewindow must be <= 127"); rv = GE_INVAL; goto out_err; } if (conf->readwindow > 127) { gensio_pparm_slog(p, "readwindow must be <= 127"); rv = GE_INVAL; goto out_err; } } else { if (conf->writewindow > 7) { gensio_pparm_slog(p, "writewindow must be <= 7"); rv = GE_INVAL; goto out_err; } if (conf->readwindow > 7) { gensio_pparm_slog(p, "readwindow must be <= 7"); rv = GE_INVAL; goto out_err; } } out_err: return rv; } static void ax25_defconf(struct ax25_conf_data *conf) { memset(conf, 0, sizeof(*conf)); conf->max_read_size = 256; conf->max_write_size = 256; conf->readwindow = 7; conf->writewindow = 7; conf->extended = 1; conf->ignore_embedded_ua = true; conf->srtv = 4000; /* 4 seconds (t1 is 8 seconds). */ conf->t2v = 2000; /* 2 seconds. */ conf->t3v = 300000; /* 300 seconds. */ conf->max_retries = 10; conf->drop_pos = 0; conf->pid = 0xf0; } static int ax25_chan_alloc(struct ax25_base *base, const char *const args[], gensio_event cb, void *user_data, enum ax25_chan_state start_state, struct gensio_addr *addr, bool firstchan, struct ax25_chan **rchan) { struct gensio_os_funcs *o = base->o; struct ax25_chan *chan = NULL; unsigned int i; int rv; GENSIO_DECLARE_PPGENSIO(p, o, cb, "ax25", user_data); chan = o->zalloc(o, sizeof(*chan)); if (!chan) goto out_nomem; chan->o = o; gensio_list_init(&chan->ui_addrs); chan->conf = base->conf; chan->conf.pid = 0xf0; chan->conf.report_heard = false; chan->conf.report_raw = false; chan->conf.conf_laddrs = NULL; chan->conf.num_conf_laddrs = 0; chan->conf.conf_uiaddrs = NULL; chan->conf.num_conf_uiaddrs = 0; chan->conf.addr = NULL; /* * This is subtle, we pick up the address from what is configured * in the base if we come in as an accepter, but only for the * first channel. */ if (firstchan && !addr && base->conf.addr) addr = base->conf.addr; if (addr) { chan->conf.addr = gensio_addr_dup(addr); if (!chan->conf.addr) return GE_NOMEM; } rv = ax25_readconf(&p, base->o, firstchan, false, &chan->conf, args); if (rv) goto out_err; if (chan->conf.addr) { chan->encoded_addr_len = ax25_addr_encode(chan->encoded_addr, chan->conf.addr); } if (chan->conf.report_raw) base->have_raw = true; rv = gensio_refcount_init(o, &chan->refcount, 1); if (rv) goto out_err; gensio_list_init(&chan->raws); /* After this point we can use ax25_chan_finish_free to free it. */ if (chan->conf.num_conf_uiaddrs) { /* Add the ui listen addresses to the list. */ for (i = 0; i < chan->conf.num_conf_uiaddrs; i++) { rv = ax25_add_iaddr(base->o, &chan->ui_addrs, &chan->conf.conf_uiaddrs[i]); if (rv) goto out_err; } } chan->ui_addr_lock = o->alloc_lock(o); if (!chan->ui_addr_lock) goto out_nomem; chan->read_data = o->zalloc(o, (sizeof(struct ax25_data) * chan->conf.readwindow)); if (!chan->read_data) goto out_nomem; for (i = 0; i < chan->conf.readwindow; i++) { chan->read_data[i].data = o->zalloc(o, chan->conf.max_read_size); if (!chan->read_data[i].data) goto out_nomem; } chan->write_data = o->zalloc(o, (sizeof(struct ax25_data) * chan->conf.writewindow)); if (!chan->write_data) goto out_nomem; for (i = 0; i < chan->conf.writewindow; i++) { chan->write_data[i].data = o->zalloc(o, chan->conf.max_write_size); if (!chan->write_data[i].data) goto out_nomem; } chan->lock = o->alloc_lock(o); if (!chan->lock) goto out_nomem; rv = gensio_refcount_init(o, &chan->deferred_op_pending, 1); if (rv) goto out_err; chan->timer = o->alloc_timer(o, ax25_chan_timeout, chan); if (!chan->timer) goto out_nomem; chan->deferred_op_runner = o->alloc_runner(o, ax25_chan_deferred_op, chan); if (!chan->deferred_op_runner) goto out_nomem; chan->io = gensio_data_alloc(o, cb, user_data, ax25_chan_func, base->child, "ax25", chan); if (!chan->io) goto out_nomem; gensio_set_is_client(chan->io, true); /* FIXME */ gensio_set_attr_from_child(chan->io, base->child); gensio_set_is_packet(chan->io, true); gensio_set_is_reliable(chan->io, true); gensio_set_is_mux(chan->io, true); ax25_base_lock(base); chan->base = base; ax25_base_ref(base); chan->state = start_state; if (start_state == AX25_CHAN_CLOSED) /* Should never allocate with report close or io err state. */ gensio_list_add_tail(&base->chans_closed, &chan->link); else gensio_list_add_tail(&base->chans, &chan->link); ax25_base_unlock(base); *rchan = chan; return 0; out_nomem: rv = GE_NOMEM; out_err: if (addr) gensio_addr_free(addr); if (chan) ax25_chan_finish_free(chan, false); return rv; } static int ax25_gensio_alloc_base(struct gensio *child, const char *const args[], struct ax25_conf_data *conf, struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct ax25_chan **rchan) { int rv; struct ax25_base *base; struct ax25_chan *chan; struct gensio_ax25_subaddr *my_addrs = NULL; unsigned int num_my_addrs = 0, i; base = o->zalloc(o, sizeof(*base)); if (!base) return GE_NOMEM; base->o = o; base->state = AX25_BASE_CLOSED; gensio_list_init(&base->listen_addrs); gensio_list_init(&base->chans); gensio_list_init(&base->chans_waiting_open); gensio_list_init(&base->chans_closed); gensio_list_init(&base->send_list); rv = gensio_refcount_init(o, &base->refcount, 1); if (rv) goto out_err; base->conf = *conf; /* * If conf_laddrs is set, this comes from an accepter and will not * have any arguments. So we can just set our conf_laddrs. * Otherwise find our addresses from the arguments. */ if (conf->conf_laddrs) { unsigned int size = conf->num_conf_laddrs * sizeof(*(conf->conf_laddrs)); my_addrs = o->zalloc(o, size); if (!my_addrs) goto out_nomem; memcpy(my_addrs, conf->conf_laddrs, size); num_my_addrs = conf->num_conf_laddrs; } base->lock = o->alloc_lock(o); if (!base->lock) goto out_nomem; #ifdef DEBUG_STATE base->trace_lock = o->alloc_lock(o); if (!base->trace_lock) goto out_nomem; #endif base->addrlock = o->alloc_lock(o); if (!base->addrlock) goto out_nomem; base->child = child; rv = ax25_chan_alloc(base, args, cb, user_data, AX25_CHAN_CLOSED, NULL, true, &chan); if (rv) { base->child = NULL; /* Caller will free this. */ goto out_err; } /* * chan alloc will increment the refcount, but we want the * refcount to match the number of channels here. */ gensio_refcount_dec(&base->refcount); gensio_set_callback(child, ax25_child_cb, base); base->conf = chan->conf; /* Restore proper setting for things that need to be kept. */ chan->conf.conf_laddrs = NULL; chan->conf.num_conf_laddrs = 0; base->conf.conf_uiaddrs = NULL; base->conf.num_conf_uiaddrs = 0; base->conf.addr = NULL; if (!my_addrs) { /* * No need to check for existing conf_laddrs, if my_addrs is set * then there can't have been any listen channels from the child. */ my_addrs = base->conf.conf_laddrs; num_my_addrs = base->conf.num_conf_laddrs; base->conf.conf_laddrs = NULL; base->conf.num_conf_laddrs = 0; } if (num_my_addrs) { /* Add the listen addresses to the list. */ for (i = 0; i < num_my_addrs; i++) { rv = ax25_add_iaddr(base->o, &base->listen_addrs, &my_addrs[i]); if (rv) goto out_err; } o->free(o, my_addrs); } *rchan = chan; return 0; out_nomem: rv = GE_NOMEM; out_err: if (my_addrs) o->free(o, my_addrs); ax25_base_finish_free(base); return rv; } static int ax25_gensio_alloc(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **net) { struct ax25_conf_data conf; struct ax25_chan *chan; int err; ax25_defconf(&conf); err = ax25_gensio_alloc_base(child, args, &conf, o, cb, user_data, &chan); if (err) return err; *net = chan->io; return 0; } static int str_to_ax25_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct gensio *io2; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio(str, o, cb, user_data, &io2); if (err) return err; err = ax25_gensio_alloc(io2, args, o, cb, user_data, new_gensio); if (err) gensio_free(io2); return err; } struct ax25a_data { struct gensio_accepter *acc; struct ax25_conf_data conf; struct gensio_os_funcs *o; }; static void ax25a_free(struct ax25a_data *nadata) { ax25_cleanup_conf(nadata->o, &nadata->conf); nadata->o->free(nadata->o, nadata); } static int ax25a_alloc_gensio(struct ax25a_data *nadata, const char * const *iargs, struct gensio *child, struct gensio **rio) { return ax25_gensio_alloc(child, iargs, nadata->o, NULL, NULL, rio); } /* * On an accepter, when a new child comes in we do not immediately * start things up. Instead, we wait for an incoming connection * first, then deliver the gensio for that connection as a newly * accepted gensio. */ static int ax25a_new_child(struct ax25a_data *adata, void **finish_data, struct gensio_new_child_io *ncio) { struct ax25_chan *chan; struct ax25_base *base; struct ax25_conf_data conf = adata->conf; int err; err = ax25_gensio_alloc_base(ncio->child, NULL, &conf, adata->o, NULL, NULL, &chan); if (err) return err; base = chan->base; base->accepter = adata->acc; ncio->new_io = chan->io; base->state = AX25_BASE_OPEN; gensio_refcount_inc(&base->refcount); base->waiting_first_open = true; chan->open_done = ncio->open_done; chan->open_data = ncio->open_data; *finish_data = chan; return err; } static int ax25a_finish_parent(struct ax25_chan *chan) { gensio_set_read_callback_enable(chan->base->child, true); return 0; } static int gensio_gensio_acc_ax25_cb(void *acc_data, int op, void *data1, void *data2, void *data3, const void *data4) { switch (op) { case GENSIO_GENSIO_ACC_ALLOC_GENSIO: return ax25a_alloc_gensio(acc_data, data4, data1, data2); case GENSIO_GENSIO_ACC_NEW_CHILD_IO: return ax25a_new_child(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FREE: ax25a_free(acc_data); return 0; case GENSIO_GENSIO_ACC_FINISH_PARENT: return ax25a_finish_parent(data1); default: return GE_NOTSUP; } } static int ax25_gensio_accepter_alloc(struct gensio_accepter *child, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { struct ax25a_data *adata; int err; GENSIO_DECLARE_PPACCEPTER(p, o, cb, "ax25", user_data); adata = o->zalloc(o, sizeof(*adata)); if (!adata) return GE_NOMEM; adata->o = o; ax25_defconf(&adata->conf); err = ax25_readconf(&p, o, true, true, &adata->conf, args); if (err) { ax25_cleanup_conf(o, &adata->conf); o->free(o, adata); return err; } err = gensio_gensio_accepter_alloc(child, o, "ax25", cb, user_data, gensio_gensio_acc_ax25_cb, adata, &adata->acc); if (err) goto out_err; gensio_acc_set_is_packet(adata->acc, true); gensio_acc_set_is_reliable(adata->acc, true); gensio_acc_set_is_mux(adata->acc, true); *accepter = adata->acc; return 0; out_err: ax25a_free(adata); return err; } static int str_to_ax25_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { int err; struct gensio_accepter *acc2 = NULL; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio_accepter(str, o, cb, user_data, &acc2); if (!err) { err = ax25_gensio_accepter_alloc(acc2, args, o, cb, user_data, acc); if (err) gensio_acc_free(acc2); } return err; } int gensio_init_ax25(struct gensio_os_funcs *o) { int rv; rv = register_filter_gensio(o, "ax25", str_to_ax25_gensio, ax25_gensio_alloc); if (rv) return rv; rv = register_filter_gensio_accepter(o, "ax25", str_to_ax25_gensio_accepter, ax25_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/README.rst0000664000175000017500000000740614747451760010744 =========================== gensio library =========================== This directory holds the code for the gensio library proper. gensio.c ======== gensio.c provides the central interface for all gensios. The interface to the raw gensio themselves is through a single function that takes an operation parameter that specifies what you want to do. This is a little clunky, sure, but it provides easy forwards and backwards compatibility. The interface from the gensio back to the user is also through a single function that the user provides, again providing easy forwards and backwards compatibility. gensio.c provides pretty much all the user interface, including some helper functions, the blocking interface, and a few other small things. gensio_base.c ============= gensio_base.c provides basic handling for a gensio state machine, keeping track of if it's in open, close, or opened, or closed, etc. This is harder than you might imagine, and having a lot of gensios share this code has been a good thing. Some gensios use it, and some do not. The gensio_base.c code takes a required low-level (ll) interface (talking to whatever is below the gensio) and an optional filter, which is used for processing the data going between the user and the ll. The interface for gensio_base.c is in the main include directory under gensio_base.h and is available for users implementing their own gensios. Various gensio files ==================== The files name gensio_ll_xxx.c are ll interfaces. gensio_ll_fd.c is used by several gensios that deal with sockets and pipe-type things (tcp, sctp, unix, pty, serialdev). So, for instance, gensio_sctp.c sets up the sctp sockets, gensio_base.c provides the state machine, and gensio_ll_fd.c provides the code for talking to the file descriptor. Note that tcp and unix sockets are in the same file: gensio_net.c The code was so common that they were merged. gensio_ll_gensio.c and gensio_ll_fd.c have include files in the main include directory and are available for users implementing their own gensios. The files named gensio_filter_xxx.[ch] are filters. They all stack on top of other gensios (read the main documentation if you want to know about this). They all use gensio_ll_gensio.c for talking to a child gensio. For instance, gensio_ssl.c use gensio_ll_gensio.c for the ll, gensio_filter_ssl.[ch] for the ssl processing (which in turn uses openssl) and gensio_base.c provides the state machine handling. The files name sergensio_xxx.c are gensios that provide a serial interface class. The main docs talk about this. The following gensios use gensio_base.c: certauth, ssl, telnet, tcp, unix, sctp, serialdev, pty, ipmisol The following do not: dummy, echo, file These are just too simple to have a meaningful state machine. udp UDP is just too wierd to fit into anything standard. UDP is kind of weird for a stream interface, anyway, but I needed it for ser2net. Tons of users use it. stdio The handling of stderr and having a separate fd for stdin and stdout makes it too hard to fit into gensio_ll_fd.c. mux The mux handling is a mix of a base state machine and a state machine for each instance. acc.c ============ This file implements an accepter state machine to simplify implementation of an accepter. It handles the locking and validation of states so basically, anything that uses only has to do the basic operations specific to that gensio. This is used by gensio_acc_gensio.c, gensio_net.c, and gensio_sctp.c. acc_gensio.c =================== Finally for accepters that stack over other accepter gensios (certauth, ssl, telnet, mux) use gensio_acc_gensio.c for this interface. gensio_class.h ============== For users implementing their own gensios, gensio_class.h provides the interface between gensio.c and the connecter/accepters. gensio-3.0.0/lib/gensio_ratelimit.c0000664000175000017500000003344315055560731012747 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2020-2025 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include struct ratelimit_config { gensiods xmit_buf_len; gensio_time delay; }; struct ratelimit_filter { struct gensio_filter *filter; struct gensio_os_funcs *o; struct gensio_lock *lock; struct ratelimit_config config; gensio_filter_cb filter_cb; void *filter_cb_data; unsigned char *xmit_buf; bool xmit_ready; }; #define filter_to_ratelimit(v) ((struct ratelimit_filter *) \ gensio_filter_get_user_data(v)) static void ratelimit_lock(struct ratelimit_filter *rfilter) { rfilter->o->lock(rfilter->lock); } static void ratelimit_unlock(struct ratelimit_filter *rfilter) { rfilter->o->unlock(rfilter->lock); } static void ratelimit_filter_start_timer(struct ratelimit_filter *rfilter) { rfilter->filter_cb(rfilter->filter_cb_data, GENSIO_FILTER_CB_START_TIMER, &rfilter->config.delay); } static void ratelimit_set_callbacks(struct ratelimit_filter *rfilter, gensio_filter_cb cb, void *cb_data) { rfilter->filter_cb = cb; rfilter->filter_cb_data = cb_data; } static bool ratelimit_ul_read_pending(struct ratelimit_filter *rfilter) { return false; /* We don't hold any read data. */ } static bool ratelimit_ll_write_pending(struct ratelimit_filter *rfilter) { return false; /* We don't hold any write data. */ } static int ratelimit_ul_can_write(struct ratelimit_filter *rfilter, bool *rv) { *rv = rfilter->xmit_ready; return 0; } static bool ratelimit_ll_read_needed(struct ratelimit_filter *rfilter) { return false; } static int ratelimit_check_open_done(struct ratelimit_filter *rfilter, struct gensio *io) { return 0; } static int ratelimit_try_connect(struct ratelimit_filter *rfilter, gensio_time *timeout, bool was_timeout) { rfilter->xmit_ready = true; return 0; } static int ratelimit_try_disconnect(struct ratelimit_filter *rfilter, gensio_time *timeout, bool was_timeout) { return 0; } static int ratelimit_ul_write(struct ratelimit_filter *rfilter, gensio_ul_filter_data_handler handler, void *cb_data, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { gensiods i, count = 0; struct gensio_sg xsg; int err = 0; ratelimit_lock(rfilter); if (!rfilter->xmit_ready) goto out; for (i = 0; i < sglen && count < rfilter->config.xmit_buf_len; i++) { gensiods len = sg[i].buflen; if (len > rfilter->config.xmit_buf_len - count) len = rfilter->config.xmit_buf_len - count; memcpy(rfilter->xmit_buf + count, sg[i].buf, len); count += len; } xsg.buf = rfilter->xmit_buf; xsg.buflen = count; ratelimit_unlock(rfilter); err = handler(cb_data, &count, &xsg, 1, auxdata); ratelimit_lock(rfilter); if (!err && count > 0) { rfilter->xmit_ready = false; ratelimit_filter_start_timer(rfilter); } out: ratelimit_unlock(rfilter); if (!err && rcount) *rcount = count; return err; } static int ratelimit_ll_write(struct ratelimit_filter *rfilter, gensio_ll_filter_data_handler handler, void *cb_data, gensiods *rcount, unsigned char *buf, gensiods buflen, const char *const *auxdata) { return handler(cb_data, rcount, buf, buflen, auxdata); } static int ratelimit_setup(struct ratelimit_filter *rfilter) { return 0; } static void ratelimit_filter_cleanup(struct ratelimit_filter *rfilter) { } static void ratelimit_free(struct ratelimit_filter *rfilter) { struct gensio_os_funcs *o = rfilter->o; if (rfilter->lock) o->free_lock(rfilter->lock); if (rfilter->xmit_buf) o->free(o, rfilter->xmit_buf); if (rfilter->filter) gensio_filter_free_data(rfilter->filter); o->free(o, rfilter); } static int ratelimit_filter_timeout(struct ratelimit_filter *rfilter) { ratelimit_lock(rfilter); rfilter->xmit_ready = true; rfilter->filter_cb(rfilter->filter_cb_data, GENSIO_FILTER_CB_OUTPUT_READY, NULL); ratelimit_unlock(rfilter); return 0; } static int gensio_ratelimit_filter_func(struct gensio_filter *filter, int op, void *func, void *data, gensiods *count, void *buf, const void *cbuf, gensiods buflen, const char *const *auxdata) { struct ratelimit_filter *rfilter = filter_to_ratelimit(filter); switch (op) { case GENSIO_FILTER_FUNC_SET_CALLBACK: ratelimit_set_callbacks(rfilter, func, data); return 0; case GENSIO_FILTER_FUNC_UL_READ_PENDING: return ratelimit_ul_read_pending(rfilter); case GENSIO_FILTER_FUNC_LL_WRITE_PENDING: return ratelimit_ll_write_pending(rfilter); case GENSIO_FILTER_FUNC_UL_CAN_WRITE: return ratelimit_ul_can_write(rfilter, data); case GENSIO_FILTER_FUNC_LL_READ_NEEDED: return ratelimit_ll_read_needed(rfilter); case GENSIO_FILTER_FUNC_CHECK_OPEN_DONE: return ratelimit_check_open_done(rfilter, data); case GENSIO_FILTER_FUNC_TRY_CONNECT: return ratelimit_try_connect(rfilter, data, buflen); case GENSIO_FILTER_FUNC_TRY_DISCONNECT: return ratelimit_try_disconnect(rfilter, data, buflen); case GENSIO_FILTER_FUNC_UL_WRITE_SG: return ratelimit_ul_write(rfilter, func, data, count, cbuf, buflen, auxdata); case GENSIO_FILTER_FUNC_LL_WRITE: return ratelimit_ll_write(rfilter, func, data, count, buf, buflen, auxdata); case GENSIO_FILTER_FUNC_SETUP: return ratelimit_setup(rfilter); case GENSIO_FILTER_FUNC_CLEANUP: ratelimit_filter_cleanup(rfilter); return 0; case GENSIO_FILTER_FUNC_FREE: ratelimit_free(rfilter); return 0; case GENSIO_FILTER_FUNC_TIMEOUT: return ratelimit_filter_timeout(rfilter); default: return GE_NOTSUP; } } static struct gensio_filter * gensio_ratelimit_filter_raw_alloc(struct gensio_os_funcs *o, struct ratelimit_config *config) { struct ratelimit_filter *rfilter; rfilter = o->zalloc(o, sizeof(*rfilter)); if (!rfilter) return NULL; rfilter->o = o; rfilter->config = *config; rfilter->xmit_buf = o->zalloc(o, config->xmit_buf_len); if (!rfilter->xmit_buf) goto out_nomem; rfilter->lock = o->alloc_lock(o); if (!rfilter->lock) goto out_nomem; rfilter->filter = gensio_filter_alloc_data(o, gensio_ratelimit_filter_func, rfilter); if (!rfilter->filter) goto out_nomem; return rfilter->filter; out_nomem: ratelimit_free(rfilter); return NULL; } static int gensio_ratelimit_config(struct gensio_pparm_info *p, struct gensio_os_funcs *o, const char * const args[], struct gensio_base_parms *parms, struct ratelimit_config *config) { unsigned int i; config->xmit_buf_len = 1; for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(p, args[i], "xmit_len", &config->xmit_buf_len) > 0) continue; if (gensio_pparm_time(p, args[i], "xmit_delay", 0, &config->delay) > 0) continue; if (gensio_base_parm(parms, p, args[i]) > 0) continue; gensio_pparm_unknown_parm(p, args[i]); return GE_INVAL; } if (config->delay.secs == 0 && config->delay.nsecs == 0) { gensio_pparm_slog(p, "xmit_delay cannot be zero"); return GE_INVAL; } return 0; } static int gensio_ratelimit_filter_alloc(struct gensio_os_funcs *o, struct ratelimit_config *config, struct gensio_filter **rfilter) { struct gensio_filter *filter; filter = gensio_ratelimit_filter_raw_alloc(o, config); if (!filter) return GE_NOMEM; *rfilter = filter; return 0; } static int ratelimit_gensio_alloc2(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio_base_parms **parms, struct gensio **net) { int err; struct gensio_filter *filter; struct gensio_ll *ll; struct gensio *io; struct ratelimit_config config; GENSIO_DECLARE_PPGENSIO(p, o, cb, "ratelimit", user_data); memset(&config, 0, sizeof(config)); err = gensio_ratelimit_config(&p, 0, args, *parms, &config); if (err) return err; err = gensio_ratelimit_filter_alloc(o, &config, &filter); if (err) return err; ll = gensio_gensio_ll_alloc(o, child); if (!ll) { gensio_filter_free(filter); return GE_NOMEM; } gensio_ref(child); /* So gensio_ll_free doesn't free the child if fail */ io = base_gensio_alloc(o, ll, filter, child, "ratelimit", cb, user_data); if (!io) { gensio_ll_free(ll); gensio_filter_free(filter); return GE_NOMEM; } gensio_free(child); /* Lose the ref we acquired. */ err = gensio_base_parms_set(io, parms); if (err) { gensio_free(io); return err; } *net = io; return 0; } static int ratelimit_gensio_alloc(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **net) { struct gensio_base_parms *parms; int err; err = gensio_base_parms_alloc(o, true, "ratelimit", &parms); if (err) return err; err = ratelimit_gensio_alloc2(child, args, o, cb, user_data, &parms, net); if (parms) gensio_base_parms_free(&parms); return err; } static int str_to_ratelimit_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct gensio *io2; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio(str, o, cb, user_data, &io2); if (err) return err; err = ratelimit_gensio_alloc(io2, args, o, cb, user_data, new_gensio); if (err) gensio_free(io2); return err; } struct ratelimitna_data { struct gensio_accepter *acc; struct ratelimit_config config; struct gensio_os_funcs *o; gensio_accepter_event cb; void *user_data; }; static void ratelimitna_free(void *acc_data) { struct ratelimitna_data *nadata = acc_data; nadata->o->free(nadata->o, nadata); } static int ratelimitna_alloc_gensio(void *acc_data, const char * const *iargs, struct gensio *child, struct gensio **rio) { struct ratelimitna_data *nadata = acc_data; struct gensio_base_parms *parms = NULL; int err; parms = gensio_acc_base_parms_dup(nadata->acc); if (!parms) return GE_NOMEM; err = ratelimit_gensio_alloc(child, iargs, nadata->o, NULL, NULL, rio); if (parms) gensio_base_parms_free(&parms); return err; } static int ratelimitna_new_child(void *acc_data, void **finish_data, struct gensio_filter **filter) { struct ratelimitna_data *nadata = acc_data; return gensio_ratelimit_filter_alloc(nadata->o, &nadata->config, filter); } static int ratelimitna_finish_parent(void *acc_data, void *finish_data, struct gensio *io) { struct ratelimitna_data *nadata = acc_data; int err; err = gensio_acc_base_parms_apply(nadata->acc, io); if (err) return err; return 0; } static int gensio_gensio_acc_ratelimit_cb(void *acc_data, int op, void *data1, void *data2, void *data3, const void *data4) { switch (op) { case GENSIO_GENSIO_ACC_ALLOC_GENSIO: return ratelimitna_alloc_gensio(acc_data, data4, data1, data2); case GENSIO_GENSIO_ACC_NEW_CHILD: return ratelimitna_new_child(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FINISH_PARENT: return ratelimitna_finish_parent(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FREE: ratelimitna_free(acc_data); return 0; default: return GE_NOTSUP; } } static int ratelimit_gensio_accepter_alloc(struct gensio_accepter *child, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { struct ratelimitna_data *nadata = NULL; int err; struct gensio_base_parms *parms = NULL; GENSIO_DECLARE_PPACCEPTER(p, o, cb, "ratelimit", user_data); err = gensio_base_parms_alloc(o, true, "ratelimit", &parms); if (err) goto out_err; nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) goto out_nomem; err = gensio_ratelimit_config(&p, o, args, parms, &nadata->config); if (err) goto out_err; nadata->o = o; nadata->cb = cb; nadata->user_data = user_data; err = gensio_gensio_accepter_alloc(child, o, "ratelimit", cb, user_data, gensio_gensio_acc_ratelimit_cb, nadata, &nadata->acc); if (err) goto out_err; *accepter = nadata->acc; err = gensio_acc_base_parms_set(nadata->acc, &parms); if (err) goto out_err; return 0; out_nomem: err = GE_NOMEM; out_err: if (nadata) { if (nadata->acc) gensio_acc_free(nadata->acc); else ratelimitna_free(nadata); } if (parms) gensio_base_parms_free(&parms); return err; } static int str_to_ratelimit_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { int err; struct gensio_accepter *acc2 = NULL; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio_accepter(str, o, cb, user_data, &acc2); if (!err) { err = ratelimit_gensio_accepter_alloc(acc2, args, o, cb, user_data, acc); if (err) gensio_acc_free(acc2); } return err; } int gensio_init_ratelimit(struct gensio_os_funcs *o) { int rv; rv = register_filter_gensio(o, "ratelimit", str_to_ratelimit_gensio, ratelimit_gensio_alloc); if (rv) return rv; rv = register_filter_gensio_accepter(o, "ratelimit", str_to_ratelimit_gensio_accepter, ratelimit_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/libgensioosh.pc.in0000664000175000017500000000034414664224267012663 prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libgensioosh Description: OS handler library for gensio Version: @VERSION@ Libs: -L${libdir} -lgensioosh -lgensio Libs.private: @OSH_LIBS@ gensio-3.0.0/lib/gensio_sound_file.h0000664000175000017500000001005314747451760013111 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2022 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ struct file_info { FILE *f; bool finished; bool is_stdio; }; static void gensio_sound_file_api_close_dev(struct sound_info *si) { struct file_info *a = si->pinfo; if (a && a->f) { if (!a->is_stdio) fclose(a->f); a->f = NULL; } } static void gensio_sound_file_api_next_read(struct sound_info *si) { struct file_info *a = si->pinfo; size_t rv; if (si->len > 0) return; if (si->cnv.enabled) rv = fread(si->cnv.buf, si->cnv.pframesize, si->bufsize, a->f); else rv = fread(si->buf, si->framesize, si->bufsize, a->f); if (rv != si->bufsize) { si->soundll->err = GE_REMCLOSE; return; } if (si->cnv.enabled) { const unsigned char *ibuf = si->cnv.buf; unsigned char *obuf = si->buf; gensiods i; for (i = 0; i < si->bufsize * si->chans; i++) si->cnv.convin(&ibuf, &obuf, &si->cnv); } si->len = si->bufsize; si->ready = true; } static void gensio_sound_file_api_set_read(struct sound_info *si, bool enable) { if (enable) gensio_sound_file_api_next_read(si); } static void gensio_sound_file_api_set_write(struct sound_info *si, bool enable) { } static unsigned int gensio_sound_file_api_start_close(struct sound_info *si) { struct file_info *a = si->pinfo; if (a->f) { if (!a->is_stdio) fclose(a->f); a->f = NULL; } return 0; } static int gensio_sound_file_api_write(struct sound_info *out, const unsigned char *buf, gensiods buflen, gensiods *nr_written) { struct file_info *a = out->pinfo; size_t rv; int err = 0; if (out->cnv.enabled) rv = fwrite(buf, out->cnv.pframesize, buflen, a->f); else rv = fwrite(buf, out->framesize, buflen, a->f); if (rv != buflen) err = GE_IOERR; else *nr_written = buflen; return err; } static int gensio_sound_file_api_open_dev(struct sound_info *si) { struct file_info *a = si->pinfo; struct gensio_os_funcs *o = si->soundll->o; if (strcmp(si->devname, "-") == 0) { a->is_stdio = true; if (si->is_input) a->f = stdin; else a->f = stdout; } else { a->is_stdio = false; a->f = fopen(si->devname, si->is_input ? "r" : "w"); if (!a->f) return GE_NOTFOUND; } if (si->cnv.enabled) { si->cnv.pframesize = (gensiods) si->cnv.psize * si->chans; si->cnv.buf = o->zalloc(o, si->bufsize * si->cnv.pframesize); if (!si->cnv.buf) { if (!a->is_stdio) fclose(a->f); a->f = NULL; return GE_NOMEM; } } if (!si->is_input) si->ready = true; /* Write is always ready. */ return 0; } int gensio_sound_file_api_devices(struct gensio_os_funcs *o, char ***rnames, char ***rspecs, gensiods *rcount) { *rnames = NULL; *rspecs = NULL; *rcount = 0; return 0; } static int gensio_sound_file_api_setup(struct gensio_pparm_info *p, struct sound_info *si, struct gensio_sound_info *io) { struct gensio_os_funcs *o = si->soundll->o; si->cardname = gensio_strdup(o, io->devname); if (!si->cardname) return GE_NOMEM; si->pinfo = o->zalloc(o, sizeof(struct file_info)); if (!si->pinfo) { o->free(o, si->cardname); si->cardname = NULL; return GE_NOMEM; } return 0; } static void gensio_sound_file_api_cleanup(struct sound_info *si) { struct gensio_os_funcs *o = si->soundll->o; if (si->pinfo) o->free(o, si->pinfo); } static struct sound_type file_sound_type = { "file", .setup = gensio_sound_file_api_setup, .cleanup = gensio_sound_file_api_cleanup, .open_dev = gensio_sound_file_api_open_dev, .close_dev = gensio_sound_file_api_close_dev, .sub_write = gensio_sound_file_api_write, .write = gensio_sound_api_default_write, .set_write_enable = gensio_sound_file_api_set_write, .set_read_enable = gensio_sound_file_api_set_read, .next_read = gensio_sound_file_api_next_read, .start_close = gensio_sound_file_api_start_close, .devices = gensio_sound_file_api_devices }; #define FILE_INIT &file_sound_type, gensio-3.0.0/lib/circbuf.c0000664000175000017500000000654114747600704011027 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include #include #include #include struct gensio_circbuf { struct gensio_os_funcs *o; gensiods pos; gensiods size; gensiods bufsize; unsigned char *cbuf; }; gensiods gensio_circbuf_room_left(struct gensio_circbuf *c) { return c->bufsize - c->size; } void gensio_circbuf_next_write_area(struct gensio_circbuf *c, void **pos, gensiods *size) { gensiods end; end = (c->pos + c->size) % c->bufsize; if (c->size == c->bufsize) *size = 0; else if (end >= c->pos) /* Unwrapped or empty buffer, write to the end. */ *size = c->bufsize - end; else /* Wrapped or full buffer, write between end and iopos. */ *size = c->pos - end; *pos = c->cbuf + end; } void gensio_circbuf_data_added(struct gensio_circbuf *c, gensiods len) { assert(len + c->size <= c->bufsize); c->size += len; } void gensio_circbuf_next_read_area(struct gensio_circbuf *c, void **pos, gensiods *size) { gensiods end; end = (c->pos + c->size) % c->bufsize; if (c->size == 0) *size = 0; else if (end > c->pos) /* Unwrapped buffer, read the whole thing. */ *size = c->size; else /* Wrapped buffer, read to end. */ *size = c->bufsize - c->pos; *pos = c->cbuf + c->pos; } void gensio_circbuf_data_removed(struct gensio_circbuf *c, gensiods len) { assert(len <= c->size); c->size -= len; c->pos = (c->pos + len) % c->bufsize; } gensiods gensio_circbuf_datalen(struct gensio_circbuf *c) { return c->size; } void gensio_circbuf_reset(struct gensio_circbuf *c) { c->pos = 0; c->size = 0; } void gensio_circbuf_sg_write(struct gensio_circbuf *c, const struct gensio_sg *sg, gensiods sglen, gensiods *rcount) { gensiods i, count = 0; for (i = 0; i < sglen && gensio_circbuf_room_left(c) > 0; i++) { gensiods buflen = sg[i].buflen; const unsigned char *buf = sg[i].buf; while (gensio_circbuf_room_left(c) && buflen > 0) { gensiods size; void *pos; gensio_circbuf_next_write_area(c, &pos, &size); if (size > buflen) size = buflen; memcpy(pos, buf, size); gensio_circbuf_data_added(c, size); buf += size; buflen -= size; count += size; } } if (rcount) *rcount = count; } void gensio_circbuf_read(struct gensio_circbuf *c, void *ibuf, gensiods buflen, gensiods *rcount) { gensiods count = 0; unsigned char *buf = ibuf; while (buflen > 0 && gensio_circbuf_datalen(c)) { void *pos; gensiods size; gensio_circbuf_next_read_area(c, &pos, &size); if (size > buflen) size = buflen; if (buf) memcpy(buf, pos, size); buflen -= size; count += size; if (buf) buf += size; gensio_circbuf_data_removed(c, size); } if (rcount) *rcount = count; } struct gensio_circbuf * gensio_circbuf_alloc(struct gensio_os_funcs *o, gensiods size) { struct gensio_circbuf *c; c = o->zalloc(o, sizeof(*c)); if (!c) return NULL; c->o = o; c->cbuf = o->zalloc(o, size); if (!c->cbuf) { o->free(o, c); return NULL; } c->bufsize = size; return c; } void gensio_circbuf_free(struct gensio_circbuf *c) { c->o->free(c->o, c->cbuf); c->o->free(c->o, c); } gensio-3.0.0/lib/gensio_sctp.c0000664000175000017500000006561714664632152011740 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* This code handles SCTP network I/O. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct sctp_data { struct gensio_os_funcs *o; struct gensio_ll *ll; struct gensio_iod *iod; struct gensio_addr *addr; struct gensio_addr *laddr; /* Local address, NULL if not set. */ struct sctp_initmsg initmsg; struct sctp_sack_info sackinfo; bool nodelay; bool do_oob; unsigned int instreams; unsigned int ostreams; char **strind; const char *auxdata[3]; }; static int sctp_setup(struct sctp_data *tdata) { struct gensio_os_funcs *o = tdata->o; struct sctp_status status; unsigned int i; int err; err = o->sctp_get_socket_status(tdata->iod, &status); if (err) return err; tdata->instreams = status.sstat_instrms; tdata->ostreams = status.sstat_outstrms; tdata->strind = o->zalloc(o, sizeof(char *) * tdata->instreams); if (!tdata->strind) return GE_NOMEM; for (i = 1; i < tdata->instreams; i++) { tdata->strind[i] = o->zalloc(o, 17); if (!tdata->strind[i]) return GE_NOMEM; snprintf(tdata->strind[i], 17, "stream=%d", i); } return 0; } static int sctp_check_open(void *handler_data, struct gensio_iod *iod, gensio_time *timeval) { struct sctp_data *tdata = handler_data; int err; err = tdata->o->sock_control(iod, GENSIO_SOCKCTL_CHECK_OPEN, NULL, NULL); if (!err) err = sctp_setup(tdata); return err; } static int sctp_socket_setup(struct sctp_data *tdata, struct gensio_iod *iod) { int err; unsigned int setup = (GENSIO_SET_OPENSOCK_REUSEADDR | GENSIO_OPENSOCK_REUSEADDR | GENSIO_SET_OPENSOCK_KEEPALIVE | GENSIO_OPENSOCK_KEEPALIVE | GENSIO_SET_OPENSOCK_NODELAY); if (tdata->nodelay) setup |= GENSIO_OPENSOCK_NODELAY; err = tdata->o->socket_set_setup(iod, setup, tdata->laddr); if (err) return err; return tdata->o->sctp_socket_setup(iod, true, &tdata->initmsg, &tdata->sackinfo); } static int sctp_try_open(struct sctp_data *tdata, struct gensio_iod **iod) { int err = GE_INUSE; err = tdata->o->socket_open(tdata->o, tdata->addr, GENSIO_NET_PROTOCOL_SCTP, &tdata->iod); if (err) goto out; err = sctp_socket_setup(tdata, tdata->iod); if (err) goto out; err = tdata->o->sctp_connectx(tdata->iod, tdata->addr); if (err == GE_INPROGRESS) { *iod = tdata->iod; goto out_return; } else if (err) { goto out; } err = sctp_setup(tdata); out: if (err) { if (tdata->iod) tdata->o->close(&tdata->iod); } else { *iod = tdata->iod; } out_return: return err; } static int sctp_sub_open(void *handler_data, struct gensio_iod **iod, gensio_time *timeout) { struct sctp_data *tdata = handler_data; return sctp_try_open(tdata, iod); } static void sctp_free(void *handler_data) { struct sctp_data *tdata = handler_data; if (tdata->addr) gensio_addr_free(tdata->addr); if (tdata->laddr) gensio_addr_free(tdata->laddr); if (tdata->strind) { unsigned int i; for (i = 1; i < tdata->instreams; i++) { if (tdata->strind[i]) tdata->o->free(tdata->o, tdata->strind[i]); } tdata->o->free(tdata->o, tdata->strind); } tdata->o->free(tdata->o, tdata); } static int sctp_control(void *handler_data, struct gensio_iod *iod, bool get, unsigned int option, char *data, gensiods *datalen) { struct sctp_data *tdata = handler_data; int rv, val; unsigned int i, setup; gensiods pos, size; struct gensio_addr *addr; switch (option) { case GENSIO_CONTROL_NODELAY: if (get) { if (iod) { setup = GENSIO_SET_OPENSOCK_NODELAY; rv = tdata->o->socket_get_setup(iod, &setup); if (rv) return rv; val = !!(setup & GENSIO_OPENSOCK_NODELAY); } else { val = tdata->nodelay; } *datalen = snprintf(data, *datalen, "%d", val); } else { val = strtoul(data, NULL, 0); if (iod) { setup = GENSIO_SET_OPENSOCK_NODELAY; if (val) setup |= GENSIO_OPENSOCK_NODELAY; rv = tdata->o->socket_set_setup(iod, val, NULL); if (rv) return rv; } tdata->nodelay = val; } return 0; case GENSIO_CONTROL_STREAMS: if (!get) return GE_INVAL; *datalen = snprintf(data, *datalen, "instreams=%u,ostreams=%u", tdata->instreams, tdata->ostreams); return 0; case GENSIO_CONTROL_LADDR: if (!get) return GE_NOTSUP; i = strtoul(data, NULL, 0); if (i > 0) return GE_NOTFOUND; rv = tdata->o->sock_control(iod, GENSIO_SOCKCTL_GET_SOCKNAME, &addr, NULL); if (rv) return rv; pos = 0; rv = gensio_addr_to_str_all(addr, data, &pos, *datalen); gensio_addr_free(addr); if (rv) return rv; *datalen = pos; return 0; case GENSIO_CONTROL_RADDR: if (!get) return GE_NOTSUP; i = strtoul(data, NULL, 0); if (i > 0) return GE_NOTFOUND; rv = tdata->o->sock_control(iod, GENSIO_SOCKCTL_GET_PEERNAME, &addr, NULL); if (rv) return rv; pos = 0; rv = gensio_addr_to_str_all(addr, data, &pos, *datalen); gensio_addr_free(addr); if (rv) return rv; *datalen = pos; return 0; case GENSIO_CONTROL_RADDR_BIN: if (!get) return GE_NOTSUP; return tdata->o->sock_control(tdata->iod, GENSIO_SOCKCTL_GET_PEERRAW, data, datalen); case GENSIO_CONTROL_LPORT: size = sizeof(unsigned int); rv = tdata->o->sock_control(iod, GENSIO_SOCKCTL_GET_PORT, &i, &size); if (rv) return rv; *datalen = snprintf(data, *datalen, "%d", i); return 0; case GENSIO_CONTROL_CONNECT_ADDR_STR: if (!get) return GE_INVAL; pos = 0; rv = gensio_addr_to_str_all(tdata->addr, data, &pos, *datalen); if (rv) return rv; *datalen = pos; return 0; case GENSIO_CONTROL_ENABLE_OOB: if (get) *datalen = snprintf(data, *datalen, "%u", tdata->do_oob); else tdata->do_oob = !!strtoul(data, NULL, 0); return 0; default: return GE_NOTSUP; } } static int sctp_write(void *handler_data, struct gensio_iod *iod, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { struct sctp_data *tdata = handler_data; struct sctp_sndrcvinfo sinfo; unsigned int stream = 0, i; memset(&sinfo, 0, sizeof(sinfo)); if (auxdata) { for (i = 0; auxdata[i]; i++) { if (gensio_check_keyuint(auxdata[i], "stream", &stream) > 0) continue; if (strcasecmp(auxdata[i], "oob") == 0) { sinfo.sinfo_flags |= SCTP_UNORDERED; continue; } return GE_INVAL; } } sinfo.sinfo_stream = stream; return tdata->o->sctp_send(tdata->iod, sg, sglen, rcount, &sinfo, 0); } static int sctp_do_read(struct gensio_iod *iod, void *data, gensiods count, gensiods *rcount, const char ***auxdata, void *cb_data) { struct sctp_data *tdata = cb_data; int rv; struct sctp_sndrcvinfo sinfo; int flags = 0; unsigned int stream; unsigned int i; restart: rv = tdata->o->sctp_recvmsg(iod, data, count, rcount, &sinfo, &flags); /* If the data length is zero, we won't have any info. */ if (rv || *rcount == 0) return rv; stream = sinfo.sinfo_stream; /* Shouldn't happen, but just in case. */ assert(stream < tdata->instreams); i = 0; if (tdata->strind[stream]) (*auxdata)[i++] = tdata->strind[stream]; if (sinfo.sinfo_flags && SCTP_UNORDERED) { if (!tdata->do_oob) goto restart; (*auxdata)[i++] = "oob"; } (*auxdata)[i] = NULL; return rv; } static void sctp_read_ready(void *handler_data, struct gensio_iod *iod) { struct sctp_data *tdata = handler_data; gensio_fd_ll_handle_incoming(tdata->ll, sctp_do_read, tdata->auxdata, tdata); } static const struct gensio_fd_ll_ops sctp_fd_ll_ops = { .sub_open = sctp_sub_open, .check_open = sctp_check_open, .free = sctp_free, .control = sctp_control, .write = sctp_write, .read_ready = sctp_read_ready }; static int sctp_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { const struct gensio_addr *iai = gdata; struct sctp_data *tdata = NULL; struct gensio *io; gensiods max_read_size = GENSIO_DEFAULT_BUF_SIZE; unsigned int instreams = 1, ostreams = 1; unsigned int sack_freq = 1, sack_delay = 10; int i, err, ival; struct gensio_addr *addr, *laddr = NULL; bool nodelay = false; GENSIO_DECLARE_PPGENSIO(p, o, cb, "sctp", user_data); err = gensio_get_default(o, "sctp", "nodelay", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (err) return err; nodelay = ival; err = gensio_get_default(o, "sctp", "instreams", false, GENSIO_DEFAULT_INT, NULL, &ival); if (err) return err; instreams = ival; err = gensio_get_default(o, "sctp", "ostreams", false, GENSIO_DEFAULT_INT, NULL, &ival); if (err) return err; ostreams = ival; err = gensio_get_default(o, "sctp", "sack_freq", false, GENSIO_DEFAULT_INT, NULL, &ival); if (err) return err; sack_freq = ival; err = gensio_get_default(o, "sctp", "sack_delay", false, GENSIO_DEFAULT_INT, NULL, &ival); if (err) return err; sack_delay = ival; err = gensio_get_defaultaddr(o, "sctp", "laddr", false, GENSIO_NET_PROTOCOL_SCTP, true, false, &laddr); if (err && err != GE_NOTSUP) { gensio_log(o, GENSIO_LOG_ERR, "Invalid default sctp laddr: %s", gensio_err_to_str(err)); return err; } for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(&p, args[i], "readbuf", &max_read_size) > 0) continue; if (gensio_pparm_addrs(&p, args[i], "laddr", GENSIO_NET_PROTOCOL_SCTP, true, false, &laddr) > 0) continue; if (gensio_pparm_bool(&p, args[i], "nodelay", &nodelay) > 0) continue; if (gensio_pparm_uint(&p, args[i], "instreams", &instreams) > 0) continue; if (gensio_pparm_uint(&p, args[i], "ostreams", &ostreams) > 0) continue; if (gensio_pparm_uint(&p, args[i], "sack_freq", &sack_freq) > 0) continue; if (gensio_pparm_uint(&p, args[i], "sack_delay", &sack_delay) > 0) continue; gensio_pparm_unknown_parm(&p, args[i]); err = GE_INVAL; goto out_err; } tdata = o->zalloc(o, sizeof(*tdata)); if (!tdata) { err = GE_NOMEM; goto out_err; } addr = gensio_addr_dup(iai); if (!addr) goto out_nomem; tdata->o = o; tdata->addr = addr; tdata->laddr = laddr; tdata->initmsg.sinit_max_instreams = instreams; tdata->initmsg.sinit_num_ostreams = ostreams; tdata->sackinfo.sack_freq = sack_freq; tdata->sackinfo.sack_delay = sack_delay; tdata->nodelay = nodelay; tdata->ll = fd_gensio_ll_alloc(o, NULL, &sctp_fd_ll_ops, tdata, max_read_size, false, false); if (!tdata->ll) goto out_nomem; io = base_gensio_alloc(o, tdata->ll, NULL, NULL, "sctp", cb, user_data); if (!io) goto out_nomem; gensio_set_is_reliable(io, true); /* * We can't really support packet unless we have working * SCTP_EXPLICIT_EOR capability. I'll need that in something * I can test with to add this. */ /* gensio_set_is_packet(io, true); */ *new_gensio = io; return 0; out_nomem: if (tdata) { if (tdata->ll) { gensio_ll_free(tdata->ll); } else { if (tdata->addr) gensio_addr_free(tdata->addr); o->free(o, tdata); } } err = GE_NOMEM; out_err: if (laddr) gensio_addr_free(laddr); return err; } static int str_to_sctp_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { struct gensio_addr *addr; int err; err = gensio_os_scan_netaddr(o, str, false, GENSIO_NET_PROTOCOL_SCTP, &addr); if (err) return err; err = sctp_gensio_alloc(addr, args, o, cb, user_data, new_gensio); gensio_addr_free(addr); return err; } struct sctpna_data { struct gensio_accepter *acc; struct gensio_os_funcs *o; struct gensio_lock *lock; struct gensio_runner *cb_en_done_runner; gensiods max_read_size; bool nodelay; unsigned int opensock_flags; gensio_acc_done shutdown_done; gensio_acc_done cb_en_done; struct gensio_addr *ai; struct gensio_opensocks *acceptfds; unsigned int nr_acceptfds; unsigned int nr_accept_close_waiting; struct sctp_initmsg initmsg; struct sctp_sack_info sackinfo; }; static const struct gensio_fd_ll_ops sctp_server_fd_ll_ops = { .free = sctp_free, .control = sctp_control, .write = sctp_write, .read_ready = sctp_read_ready }; static void sctpna_fd_cleared(struct gensio_iod *iod, void *cbdata) { struct sctpna_data *nadata = cbdata; unsigned int num_left, i; for (i = 0; i < nadata->nr_acceptfds; i++) { if (iod == nadata->acceptfds[i].iod) break; } assert(i < nadata->nr_acceptfds); nadata->o->close(&nadata->acceptfds[i].iod); nadata->o->lock(nadata->lock); assert(nadata->nr_accept_close_waiting > 0); num_left = --nadata->nr_accept_close_waiting; if (num_left == 0) { nadata->o->free(nadata->o, nadata->acceptfds); nadata->acceptfds = NULL; } nadata->o->unlock(nadata->lock); if (num_left == 0) nadata->shutdown_done(nadata->acc, NULL); } static void sctpna_set_fd_enables(struct sctpna_data *nadata, bool enable) { unsigned int i; for (i = 0; i < nadata->nr_acceptfds; i++) nadata->o->set_read_handler(nadata->acceptfds[i].iod, enable); } static void sctpna_finish_server_open(struct gensio *net, int err, void *cb_data) { struct sctpna_data *nadata = cb_data; base_gensio_server_open_done(nadata->acc, net, err); } static void sctpna_readhandler(struct gensio_iod *iod, void *cbdata) { struct sctpna_data *nadata = cbdata; struct gensio_iod *new_iod = NULL; struct sctp_data *tdata = NULL; struct gensio *io = NULL; int err; err = nadata->o->accept(iod, NULL, &new_iod); if (err) { if (err != GE_NODATA) /* FIXME - maybe shut down the socket I/O? */ gensio_acc_log(nadata->acc, GENSIO_LOG_ERR, "Error accepting sctp gensio: %s", gensio_err_to_str(err)); return; } err = base_gensio_accepter_new_child_start(nadata->acc); if (err) { nadata->o->close(&new_iod); return; } tdata = nadata->o->zalloc(nadata->o, sizeof(*tdata)); if (!tdata) { gensio_acc_log(nadata->acc, GENSIO_LOG_INFO, "Error accepting net gensio: out of memory"); err = GE_NOMEM; goto out_err; } tdata->o = nadata->o; tdata->iod = new_iod; tdata->nodelay = nadata->nodelay; tdata->initmsg = nadata->initmsg; tdata->sackinfo = nadata->sackinfo; err = sctp_socket_setup(tdata, new_iod); if (!err) err = sctp_setup(tdata); if (err) { gensio_acc_log(nadata->acc, GENSIO_LOG_ERR, "Error setting up sctp port: %s", gensio_err_to_str(err)); goto out_err; } tdata->ll = fd_gensio_ll_alloc(nadata->o, new_iod, &sctp_server_fd_ll_ops, tdata, nadata->max_read_size, false, false); if (!tdata->ll) { gensio_acc_log(nadata->acc, GENSIO_LOG_ERR, "Out of memory allocating net ll"); err = GE_NOMEM; goto out_err; } io = base_gensio_server_alloc(nadata->o, tdata->ll, NULL, NULL, "sctp", sctpna_finish_server_open, nadata); if (!io) { gensio_acc_log(nadata->acc, GENSIO_LOG_ERR, "Out of memory allocating net base"); err = GE_NOMEM; goto out_err; } gensio_set_is_reliable(io, true); err = base_gensio_server_start(io); if (err) goto out_err; base_gensio_accepter_new_child_end(nadata->acc, io, 0); return; out_err: base_gensio_accepter_new_child_end(nadata->acc, NULL, err); if (io) { gensio_free(io); return; } if (tdata) { if (tdata->ll) { gensio_ll_free(tdata->ll); return; } sctp_free(tdata); } if (new_iod) nadata->o->close(&new_iod); } static int sctpna_setup_socket(struct gensio_iod *iod, void *data) { struct sctpna_data *nadata = data; return iod->f->sctp_socket_setup(iod, false, &nadata->initmsg, &nadata->sackinfo); } static int sctpna_startup(struct gensio_accepter *accepter, struct sctpna_data *nadata) { int rv; rv = gensio_os_open_listen_sockets(nadata->o, nadata->ai, sctpna_readhandler, NULL, sctpna_fd_cleared, sctpna_setup_socket, nadata, nadata->opensock_flags, &nadata->acceptfds, &nadata->nr_acceptfds); if (!rv) sctpna_set_fd_enables(nadata, true); return rv; } static int sctpna_shutdown(struct gensio_accepter *accepter, struct sctpna_data *nadata, gensio_acc_done shutdown_done) { unsigned int i; nadata->shutdown_done = shutdown_done; nadata->nr_accept_close_waiting = nadata->nr_acceptfds; for (i = 0; i < nadata->nr_acceptfds; i++) nadata->o->clear_fd_handlers(nadata->acceptfds[i].iod); return 0; } static void sctpna_cb_en_done(struct gensio_runner *runner, void *cb_data) { struct sctpna_data *nadata = cb_data; gensio_acc_done done = nadata->cb_en_done; nadata->cb_en_done = NULL; done(nadata->acc, NULL); } static int sctpna_set_accept_callback_enable(struct gensio_accepter *accepter, struct sctpna_data *nadata, bool enabled, gensio_acc_done done) { unsigned int i; if (nadata->cb_en_done) return GE_INUSE; nadata->cb_en_done = done; for (i = 0; i < nadata->nr_acceptfds; i++) sctpna_set_fd_enables(nadata, enabled); if (done) nadata->o->run(nadata->cb_en_done_runner); return 0; } static void sctpna_free(struct gensio_accepter *accepter, struct sctpna_data *nadata) { if (nadata->lock) nadata->o->free_lock(nadata->lock); if (nadata->cb_en_done_runner) nadata->o->free_runner(nadata->cb_en_done_runner); if (nadata->ai) gensio_addr_free(nadata->ai); nadata->o->free(nadata->o, nadata); } static int sctpna_str_to_gensio(struct gensio_accepter *accepter, struct sctpna_data *nadata, const char *addr, gensio_event cb, void *user_data, struct gensio **new_io) { int err; const char *args[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; char buf[100], buf2[100], buf3[100], buf4[100], buf5[100]; gensiods max_read_size = nadata->max_read_size; unsigned int instreams = nadata->initmsg.sinit_max_instreams; unsigned int ostreams = nadata->initmsg.sinit_num_ostreams; unsigned int sack_freq = nadata->sackinfo.sack_freq; unsigned int sack_delay = nadata->sackinfo.sack_delay; unsigned int i; const char **iargs; int iargc; struct gensio_addr *ai; const char *laddr = NULL, *dummy; bool is_port_set; int protocol = GENSIO_NET_PROTOCOL_SCTP; bool nodelay = false; GENSIO_DECLARE_PPGENSIO(p, nadata->o, cb, "sctp", user_data); err = gensio_scan_network_port(nadata->o, addr, false, &ai, &protocol, &is_port_set, &iargc, &iargs); if (err) return err; err = GE_INVAL; if (protocol != GENSIO_NET_PROTOCOL_SCTP || !is_port_set) goto out_err; for (i = 0; iargs && iargs[i]; i++) { if (gensio_pparm_ds(&p, iargs[i], "readbuf", &max_read_size) > 0) continue; if (gensio_pparm_value(&p, iargs[i], "laddr", &dummy) > 0) { laddr = iargs[i]; continue; } if (gensio_pparm_bool(&p, iargs[i], "nodelay", &nodelay) > 0) continue; if (gensio_pparm_uint(&p, iargs[i], "instreams", &instreams) > 0) continue; if (gensio_pparm_uint(&p, iargs[i], "ostreams", &ostreams) > 0) continue; if (gensio_pparm_uint(&p, iargs[i], "sack_freq", &sack_freq) > 0) continue; if (gensio_pparm_uint(&p, iargs[i], "sack_delay", &sack_delay) > 0) continue; gensio_pparm_unknown_parm(&p, iargs[i]); goto out_err; } i = 0; if (nadata->max_read_size != GENSIO_DEFAULT_BUF_SIZE) { snprintf(buf, 100, "readbuf=%lu", (unsigned long) max_read_size); args[i++] = buf; } if (laddr) args[i++] = laddr; if (instreams > 1) { snprintf(buf2, 100, "instreams=%u", instreams); args[i++] = buf2; } if (ostreams > 1) { snprintf(buf3, 100, "ostreams=%u", ostreams); args[i++] = buf3; } snprintf(buf4, 100, "sack_freq=%u", sack_freq); args[i++] = buf4; snprintf(buf5, 100, "sack_delay=%u", sack_delay); args[i++] = buf5; if (nodelay) args[i++] = "nodelay"; err = sctp_gensio_alloc(ai, args, nadata->o, cb, user_data, new_io); out_err: if (iargs) gensio_argv_free(nadata->o, iargs); gensio_addr_free(ai); return err; } static int sctpna_control_laddr(struct sctpna_data *nadata, bool get, char *data, gensiods *datalen) { unsigned int i; gensiods pos = 0; int rv; struct gensio_addr *addrs; if (!get) return GE_NOTSUP; if (nadata->nr_acceptfds == 0) return GE_NOTREADY; i = strtoul(data, NULL, 0); if (i >= nadata->nr_acceptfds) return GE_NOTFOUND; rv = nadata->o->sock_control(nadata->acceptfds[i].iod, GENSIO_SOCKCTL_GET_SOCKNAME, &addrs, NULL); if (rv) return rv; rv = gensio_addr_to_str_all(addrs, data, &pos, *datalen); gensio_addr_free(addrs); if (!rv) *datalen = pos; return rv; } static int sctpna_control_lport(struct sctpna_data *nadata, bool get, char *data, gensiods *datalen) { unsigned int i; if (!get) return GE_NOTSUP; if (nadata->nr_acceptfds == 0) return GE_NOTREADY; i = strtoul(data, NULL, 0); if (i >= nadata->nr_acceptfds) return GE_NOTFOUND; *datalen = snprintf(data, *datalen, "%d", nadata->acceptfds[i].port); return 0; } static int sctpna_control(struct gensio_accepter *accepter, struct sctpna_data *nadata, bool get, unsigned int option, char *data, gensiods *datalen) { switch (option) { case GENSIO_ACC_CONTROL_LADDR: return sctpna_control_laddr(nadata, get, data, datalen); case GENSIO_ACC_CONTROL_LPORT: return sctpna_control_lport(nadata, get, data, datalen); default: return GE_NOTSUP; } } static void sctpna_disable(struct gensio_accepter *accepter, struct sctpna_data *nadata) { unsigned int i; for (i = 0; i < nadata->nr_acceptfds; i++) nadata->o->clear_fd_handlers_norpt(nadata->acceptfds[i].iod); for (i = 0; i < nadata->nr_acceptfds; i++) nadata->o->close(&nadata->acceptfds[i].iod); } static int sctpna_base_acc_op(struct gensio_accepter *acc, int op, void *acc_op_data, void *done, int val1, void *data, void *data2, void *ret) { switch(op) { case GENSIO_BASE_ACC_STARTUP: return sctpna_startup(acc, acc_op_data); case GENSIO_BASE_ACC_SHUTDOWN: return sctpna_shutdown(acc, acc_op_data, done); case GENSIO_BASE_ACC_SET_CB_ENABLE: return sctpna_set_accept_callback_enable(acc, acc_op_data, val1, done); case GENSIO_BASE_ACC_FREE: sctpna_free(acc, acc_op_data); return 0; case GENSIO_BASE_ACC_CONTROL: return sctpna_control(acc, acc_op_data, val1, *((unsigned int *) done), data, ret); case GENSIO_BASE_ACC_STR_TO_GENSIO: return sctpna_str_to_gensio(acc, acc_op_data, (const char *) data, (gensio_event) done, data2, ret); case GENSIO_BASE_ACC_DISABLE: sctpna_disable(acc, acc_op_data); return 0; default: return GE_NOTSUP; } } static int sctp_gensio_accepter_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { const struct gensio_addr *iai = gdata; struct sctpna_data *nadata; gensiods max_read_size = GENSIO_DEFAULT_BUF_SIZE; unsigned int instreams = 1, ostreams = 1; unsigned int sack_freq = 1, sack_delay = 10; bool nodelay = false, reuseaddr = true; unsigned int i; int err, ival; GENSIO_DECLARE_PPACCEPTER(p, o, cb, "sctp", user_data); err = gensio_get_default(o, "sctp", "reuseaddr", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (err) return err; reuseaddr = ival; err = gensio_get_default(o, "sctp", "sack_freq", false, GENSIO_DEFAULT_INT, NULL, &ival); if (err) return err; sack_freq = ival; err = gensio_get_default(o, "sctp", "sack_delay", false, GENSIO_DEFAULT_INT, NULL, &ival); if (err) return err; sack_delay = ival; for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(&p, args[i], "readbuf", &max_read_size) > 0) continue; if (gensio_pparm_bool(&p, args[i], "nodelay", &nodelay) > 0) continue; if (gensio_pparm_uint(&p, args[i], "instreams", &instreams) > 0) continue; if (gensio_pparm_uint(&p, args[i], "ostreams", &ostreams) > 0) continue; if (gensio_pparm_uint(&p, args[i], "sack_freq", &sack_freq) > 0) continue; if (gensio_pparm_uint(&p, args[i], "sack_delay", &sack_delay) > 0) continue; if (gensio_pparm_bool(&p, args[i], "reuseaddr", &reuseaddr) > 0) continue; gensio_pparm_unknown_parm(&p, args[i]); return GE_INVAL; } nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) return GE_NOMEM; nadata->o = o; nadata->initmsg.sinit_max_instreams = instreams; nadata->initmsg.sinit_num_ostreams = ostreams; nadata->sackinfo.sack_freq = sack_freq; nadata->sackinfo.sack_delay = sack_delay; if (reuseaddr) nadata->opensock_flags |= GENSIO_OPENSOCK_REUSEADDR; err = GE_NOMEM; nadata->ai = gensio_addr_dup(iai); if (!nadata->ai) goto out_err; nadata->lock = o->alloc_lock(o); if (!nadata->lock) goto out_err; nadata->cb_en_done_runner = o->alloc_runner(o, sctpna_cb_en_done, nadata); if (!nadata->cb_en_done_runner) goto out_err; err = base_gensio_accepter_alloc(NULL, sctpna_base_acc_op, nadata, o, "sctp", cb, user_data, accepter); if (err) goto out_err; nadata->acc = *accepter; gensio_acc_set_is_reliable(nadata->acc, true); /* See comment on gensio_set_is_packet() above. */ /* gensio_acc_set_is_packet(nadata->acc, true); */ nadata->max_read_size = max_read_size; nadata->nodelay = nodelay; return 0; out_err: sctpna_free(NULL, nadata); return err; } static int str_to_sctp_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { int err; struct gensio_addr *ai; err = gensio_os_scan_netaddr(o, str, true, GENSIO_NET_PROTOCOL_SCTP, &ai); if (err) return err; err = sctp_gensio_accepter_alloc(ai, args, o, cb, user_data, acc); gensio_addr_free(ai); return err; } int gensio_init_sctp(struct gensio_os_funcs *o) { int rv; rv = register_gensio(o, "sctp", str_to_sctp_gensio, sctp_gensio_alloc); if (rv) return rv; rv = register_gensio_accepter(o, "sctp", str_to_sctp_gensio_accepter, sctp_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/acc_gensio.c0000664000175000017500000002005115011213546011461 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include #include #include struct gensna_data { struct gensio_accepter *acc; struct gensio_os_funcs *o; struct gensio_accepter *child; gensio_acc_done shutdown_done; gensio_acc_done cb_en_done; gensio_gensio_acc_cb acc_cb; void *acc_data; }; static int gensna_startup(struct gensio_accepter *accepter, struct gensna_data *nadata) { return gensio_acc_startup(nadata->child); } static void gensna_child_shutdown(struct gensio_accepter *accepter, void *shutdown_data) { struct gensna_data *nadata = shutdown_data; nadata->shutdown_done(nadata->acc, NULL); } static int gensna_shutdown(struct gensio_accepter *accepter, struct gensna_data *nadata, gensio_acc_done shutdown_done) { nadata->shutdown_done = shutdown_done; return gensio_acc_shutdown(nadata->child, gensna_child_shutdown, nadata); } static void gensna_cb_en_done(struct gensio_accepter *accepter, void *cb_data) { struct gensna_data *nadata = cb_data; nadata->cb_en_done(nadata->acc, NULL); } static int gensna_set_accept_callback_enable(struct gensio_accepter *accepter, struct gensna_data *nadata, bool enabled, gensio_acc_done done) { gensio_acc_done ldone = NULL; nadata->cb_en_done = done; if (done) ldone = gensna_cb_en_done; return gensio_acc_set_accept_callback_enable_cb(nadata->child, enabled, ldone, nadata); } static void gensna_free(struct gensio_accepter *accepter, struct gensna_data *nadata) { if (nadata->child) gensio_acc_free(nadata->child); if (nadata->acc_cb) nadata->acc_cb(nadata->acc_data, GENSIO_GENSIO_ACC_FREE, NULL, NULL, NULL, NULL); nadata->o->free(nadata->o, nadata); } void gensio_gensio_acc_free_nochild(struct gensio_accepter *accepter) { struct gensna_data *nadata = base_gensio_accepter_get_op_data(accepter); nadata->child = NULL; gensio_acc_free(accepter); } static int gensna_str_to_gensio(struct gensio_accepter *accepter, struct gensna_data *nadata, const char *addr, gensio_event cb, void *user_data, struct gensio **new_io) { int err; struct gensio *child = NULL, *io; const char *type = gensio_acc_get_type(accepter, 0); size_t typelen = strlen(type); int argc = 0; const char **args = NULL; if (strncmp(addr, type, typelen) != 0 || (addr[typelen] != ',' && addr[typelen] != '(' && addr[typelen])) return GE_INVAL; addr += typelen; if (*addr == '(') { err = gensio_scan_args(nadata->o, &addr, &argc, &args); if (err) return err; } else if (*addr) { addr++; /* Skip the ',' */ } err = gensio_acc_str_to_gensio(nadata->child, addr, NULL, NULL, &child); if (err) goto out; err = nadata->acc_cb(nadata->acc_data, GENSIO_GENSIO_ACC_ALLOC_GENSIO, child, &io, NULL, args); if (!err) { gensio_set_callback(io, cb, user_data); *new_io = io; } out: if (args) gensio_argv_free(nadata->o, args); if (err) { if (child) gensio_free(child); } return err; } static int gensna_control(struct gensio_accepter *accepter, struct gensna_data *nadata, bool get, unsigned int option, char *data, gensiods *datalen) { return nadata->acc_cb(nadata->acc_data, GENSIO_GENSIO_ACC_CONTROL, &get, data, datalen, &option); } static void gensna_disable(struct gensio_accepter *accepter, struct gensna_data *nadata) { nadata->acc_cb(nadata->acc_data, GENSIO_GENSIO_ACC_DISABLE, NULL, NULL, NULL, NULL); } static int gensio_gensio_base_acc_op(struct gensio_accepter *acc, int op, void *acc_op_data, void *done, int val1, void *data, void *data2, void *ret) { switch(op) { case GENSIO_BASE_ACC_STARTUP: return gensna_startup(acc, acc_op_data); case GENSIO_BASE_ACC_SHUTDOWN: return gensna_shutdown(acc, acc_op_data, done); case GENSIO_BASE_ACC_SET_CB_ENABLE: return gensna_set_accept_callback_enable(acc, acc_op_data, val1, done); case GENSIO_BASE_ACC_FREE: gensna_free(acc, acc_op_data); return 0; case GENSIO_BASE_ACC_CONTROL: return gensna_control(acc, acc_op_data, val1, *((unsigned int *) done), data, ret); case GENSIO_BASE_ACC_STR_TO_GENSIO: return gensna_str_to_gensio(acc, acc_op_data, (const char *) data, (gensio_event) done, data2, ret); case GENSIO_BASE_ACC_DISABLE: gensna_disable(acc, acc_op_data); return 0; default: return GE_NOTSUP; } } static void gensna_finish_server_open(struct gensio *net, int err, void *cb_data) { struct gensna_data *nadata = cb_data; base_gensio_server_open_done(nadata->acc, net, err); } static int gensna_child_event(struct gensio_accepter *accepter, void *user_data, int event, void *data) { struct gensna_data *nadata = user_data; struct gensio_os_funcs *o = nadata->o; struct gensio_filter *filter = NULL; struct gensio_ll *ll = NULL; struct gensio *io = NULL, *child; void *finish_data; bool base_allocated = true; int err; if (event != GENSIO_ACC_EVENT_NEW_CONNECTION) return gensio_acc_cb(nadata->acc, event, data); child = data; err = base_gensio_accepter_new_child_start(nadata->acc); if (err) goto out_err; err = nadata->acc_cb(nadata->acc_data, GENSIO_GENSIO_ACC_NEW_CHILD, &finish_data, &filter, child, NULL); if (err == GE_NOTSUP) { struct gensio_new_child_io ncio; ncio.child = child; ncio.open_done = gensna_finish_server_open; ncio.open_data = nadata; err = nadata->acc_cb(nadata->acc_data, GENSIO_GENSIO_ACC_NEW_CHILD_IO, &finish_data, &ncio, NULL, NULL); if (!err) io = ncio.new_io; if (io) base_allocated = false; } if (err) goto out_err_unlock; if (filter) { ll = gensio_gensio_ll_alloc(o, child); if (!ll) goto out_nomem; } if (filter) io = base_gensio_server_alloc(o, ll, filter, child, gensio_acc_get_type(nadata->acc, 0), gensna_finish_server_open, nadata); if (!io) goto out_nomem; if (gensio_is_reliable(child)) gensio_set_is_reliable(io, true); if (gensio_is_authenticated(child)) gensio_set_is_authenticated(io, true); if (gensio_is_encrypted(child)) gensio_set_is_encrypted(io, true); err = nadata->acc_cb(nadata->acc_data, GENSIO_GENSIO_ACC_FINISH_PARENT, finish_data, io, child, NULL); if (err && err != GE_NOTSUP) goto out_err_unlock; if (base_allocated) { err = base_gensio_server_start(io); if (err) goto out_err_unlock; } base_gensio_accepter_new_child_end(nadata->acc, io, 0); return 0; out_nomem: err = GE_NOMEM; out_err_unlock: base_gensio_accepter_new_child_end(nadata->acc, NULL, err); out_err: if (io) { gensio_free(io); } else { if (ll) gensio_ll_free(ll); else gensio_free(child); if (filter) gensio_filter_free(filter); } gensio_acc_log(nadata->acc, GENSIO_LOG_ERR, "Error allocating gensna gensio: %s", gensio_err_to_str(err)); return err; } int gensio_gensio_accepter_alloc(struct gensio_accepter *child, struct gensio_os_funcs *o, const char *typename, gensio_accepter_event cb, void *user_data, gensio_gensio_acc_cb acc_cb, void *acc_data, struct gensio_accepter **accepter) { struct gensna_data *nadata; int rv; nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) return GE_NOMEM; nadata->o = o; rv = base_gensio_accepter_alloc(child, gensio_gensio_base_acc_op, nadata, o, typename, cb, user_data, accepter); if (rv) { o->free(o, nadata); goto out; } nadata->acc_cb = acc_cb; nadata->acc_data = acc_data; nadata->child = child; nadata->acc = *accepter; gensio_acc_set_callback(child, gensna_child_event, nadata); out: return rv; } gensio-3.0.0/lib/gensio_mux.c0000664000175000017500000023647114665640166011603 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include /* * The protocol consists of messages. The first byte of a message * is the message id. The contents of the message depend on the * message id. * * The protocol is completely symmetric, there is no server or client * side. * * When a side of the protocol comes up, the first thing it does is * send an init message. It then waits for an init message from the * other end. A side will fall back to the minimum protocol version * of the two sides. * * After the init messages are exchanged, the connection is up. To * start a channel, a new channel message is sent. The other end will * respond with a new channel response message. * * The protocol identifies channel by a 16-bit channel number. Each * end assigns the channel number that the remote end sends for a * connection. So in the new channel message, the channel number sent * is the channel id that the remote end will send in data message as * the remote channel id. Same with the new channel response. The * ids for a channel may be different for each side. * * Flow control is done with bytes and message counts. Each side * sends a total number of outstanding bytes that are allowed. Acks * are done by returning the number of bytes that the user has * accepted. Note that the flags (1 byte) and data size (2 bytes) is * considered part of the outstanding bytes for each message, so it * can be stored in the buffer with the data. */ enum mux_msgs { /* * The init messages carries just a single-byte version for now. * An instance must send a mux init message and wait for a mux * init message from the remote end before sending anything else. * The size is the header size in 32-bit increments. If a newer * version adds data after the version, older version should * ignore it. * * This is version 1 of the protocol. * * +----------------+--------+-------+----------------+----------------+ * | 1 |size(1) | reserved | version | reserved | * +----------------+--------+-------+----------------+----------------+ */ MUX_INIT = 1, /* * The new channel message carries a local channel number, a * receive window byte size, a receive window message count, and a * service string. The remote end will create a channel with its * own channel number and respond with a new channel response. * The service string is not part of the header, and is thus not in * the size. * * +----------------+--------+-------+----------------+----------------+ * | 2 |size(2) | reserved | channel id | * +----------------+--------+-------+----------------+----------------+ * | byte count window | * +----------------+----------------+----------------+----------------+ * | service string size | service string data... | * +----------------+----------------+----------------+----------------+ * | service string data... | * +----------------+----------------+----------------+----------------+ */ MUX_NEW_CHANNEL = 2, /* * The new channel response carries a local channel number, a * remote channel number (the value send in the new channel * message), a receive window byte size, a receive window message * count, and an error number. After this is received/sent with a * zero error code, data may be sent on the channel. * * If the error code is non-zero, it is a gensio error describing * why the request was denied. * * +----------------+----------------+----------------+----------------+ * | 3 |size(3) | reserved | remote channel id | * +----------------+----------------+----------------+----------------+ * | byte count window | * +----------------+----------------+----------------+----------------+ * | channel id | error code | * +----------------+----------------+----------------+----------------+ */ MUX_NEW_CHANNEL_RSP = 3, /* * The close channel message carries a remote channel number. if * the remote end is not already closing, it will respond with a * close message. It has a close code is a gensio error that has * the reason for the close. Zero means the remote end requested * it. * * +----------------+----------------+----------------+----------------+ * | 4 |size(2) | reserved | remote channel id | * +----------------+----------------+----------------+----------------+ * | close code | reserved | * +----------------+----------------+----------------+----------------+ */ MUX_CLOSE_CHANNEL = 4, /* * Data for a channel. This carries a remote channel number, a * data ack, some flags, and a block of data. The block of data * is "data size" long. The data size and data are not part of * the header. * * +----------------+----------------+----------------+----------------+ * | 5 |size(2) | flags | remote channel id | * +----------------+----------------+----------------+----------------+ * | Ack count (number of bytes received by user) | * +----------------+----------------+----------------+----------------+ * | data size | data.... | * +----------------+----------------+----------------+----------------+ * | data... | * +----------------+----------------+----------------+----------------+ */ MUX_DATA = 5, }; #define MUX_MAX_MSG_NUM MUX_DATA static unsigned int mux_msg_hdr_sizes[] = { 0, 1, 2, 3, 2, 2 }; /* External flags for MUX_DATA */ #define MUX_FLAG_END_OF_MESSAGE (1 << 0) #define MUX_FLAG_OUT_OF_BOUND (1 << 1) #define MUX_MAX_HDR_SIZE 12 #define MUX_MIN_SEND_WINDOW_SIZE 128 #ifdef ENABLE_INTERNAL_TRACE #define MUX_TRACING #endif struct mux_data; enum mux_inst_state { MUX_INST_CLOSED, /* * Channel has been allocated on a received new channel message * it, but channel data has not been fully received. */ MUX_INST_PENDING_OPEN, /* open channel called for this instance, response not received. */ MUX_INST_IN_OPEN, MUX_INST_OPEN, /* Channel was closed before the open was complete. */ MUX_INST_IN_OPEN_CLOSE, /* Local end requested a close. */ MUX_INST_IN_CLOSE, /* Remote end requested a close, or the child gensio returned an error. */ MUX_INST_IN_REM_CLOSE, /* * Close is sent/received or the child has closed, but there is * still a read callback pending or the close result has not * been delivered. */ MUX_INST_IN_CLOSE_FINAL, }; struct mux_inst { struct gensio_os_funcs *o; struct gensio *io; struct mux_data *mux; unsigned int refcount; unsigned int id; unsigned int remote_id; enum mux_inst_state state; int errcode; /* If an error occurs, it is stored here. */ bool send_new_channel; bool send_close; bool is_client; bool close_sent; bool do_oob; /* * The service, either the local one or the remote one. */ char *service; size_t service_len; unsigned char *read_data; gensiods read_data_pos; gensiods read_data_len; gensiods max_read_size; bool read_enabled; bool in_read_report; int in_newchannel; /* Number of bytes we need to send an ack for. */ gensiods received_unacked; unsigned char *write_data; gensiods write_data_pos; gensiods write_data_len; gensiods max_write_size; bool write_ready_enabled; bool in_write_ready; /* Number of bytes we have sent that are not acked. */ gensiods sent_unacked; /* * Maximum number of bytes the remote end told us we can have * outstanding. */ unsigned int send_window_size; bool deferred_op_pending; struct gensio_runner *deferred_op_runner; /* Used for current message being transmitted. */ unsigned char hdr[MUX_MAX_HDR_SIZE]; struct gensio_sg sg[3]; unsigned int sgpos; unsigned int sglen; gensiods cur_msg_len; gensio_done_err open_done; void *open_data; gensio_done close_done; void *close_data; bool close_called; bool freed; /* Link for list of channels waiting write. */ struct gensio_link wrlink; bool wr_ready; /* Also true if chan == muxdata->sending_chan. */ bool in_wrlist; bool in_open_chan; struct gensio_link link; }; static gensiods chan_next_write_pos(struct mux_inst *chan, unsigned int count) { unsigned rv = chan->write_data_pos + count; if (rv >= chan->max_write_size) rv -= chan->max_write_size; return rv; } static void chan_incr_write_pos(struct mux_inst *chan, unsigned int count) { chan->write_data_pos = chan_next_write_pos(chan, count); chan->write_data_len -= count; } static void chan_addwrbuf(struct mux_inst *chan, const unsigned char *data, gensiods len) { gensiods epos = chan->write_data_pos + chan->write_data_len; if (epos >= chan->max_write_size) epos -= chan->max_write_size; if (len + epos > chan->max_write_size) { gensiods plen = chan->max_write_size - epos; memcpy(chan->write_data + epos, data, plen); data += plen; len -= plen; epos = 0; chan->write_data_len += plen; } memcpy(chan->write_data + epos, data, len); chan->write_data_len += len; } static gensiods chan_next_read_pos(struct mux_inst *chan, unsigned int count) { unsigned rv = chan->read_data_pos + count; if (rv >= chan->max_read_size) rv -= chan->max_read_size; return rv; } static void chan_addrdbuf(struct mux_inst *chan, const unsigned char *data, gensiods len) { gensiods epos = chan->read_data_pos + chan->read_data_len; if (epos >= chan->max_read_size) epos -= chan->max_read_size; if (len + epos > chan->max_read_size) { gensiods plen = chan->max_read_size - epos; memcpy(chan->read_data + epos, data, plen); data += plen; len -= plen; epos = 0; chan->read_data_len += plen; } memcpy(chan->read_data + epos, data, len); chan->read_data_len += len; } static void chan_addrdbyte(struct mux_inst *chan, unsigned char data) { chan_addrdbuf(chan, &data, 1); } static gensiods chan_rdbufleft(struct mux_inst *chan) { return chan->max_read_size - chan->read_data_len; } struct gensio_mux_config { struct gensio_os_funcs *o; gensiods max_read_size; gensiods max_write_size; char *service; size_t service_len; unsigned int max_channels; bool is_client; }; enum mux_state { /* * Mux is in allocation. */ MUX_IN_ALLOC, /* * Mux has been allocated but not opened or all channels are closed. */ MUX_CLOSED, /* * Mux child open was done, but has not yet finished. */ MUX_WAITING_CHILD_OPEN, /* * Mux is started, but has not received an init message yet. */ MUX_UNINITIALIZED, /* * Server only, mux has received init message but has not received * a new channel message yet. */ MUX_WAITING_OPEN, /* * Client only, mux has received init message and sent a new channel * message, but has not received the response. */ MUX_IN_OPEN, /* * Mux is operational. */ MUX_OPEN, /* * Mux has closed the child gensio but has not received the close_done. */ MUX_IN_CLOSE, }; #ifdef MUX_TRACING struct mux_trace_info { struct mux_inst *chan; enum mux_state state; enum mux_state new_state; enum mux_inst_state cstate; enum mux_inst_state new_cstate; int line; }; #define MUX_TRACE_SIZE 256 #endif struct mux_data { struct gensio *child; struct gensio_os_funcs *o; struct gensio_lock *lock; unsigned int refcount; gensiods max_read_size; gensiods max_write_size; int exit_err; enum mux_state exit_state; unsigned int max_channels; /* Number of channels that are not closed. */ unsigned int nr_not_closed; bool is_client; /* * Small piece of data for sending new channel responses. It's * separate in case the channel data could not be allocated. The * protocol only allows one new channel request at a time. */ unsigned char xmit_data[MUX_MAX_HDR_SIZE]; gensiods xmit_data_pos; gensiods xmit_data_len; /* * This is for calling the gensio_acc_gensio's open done handler * when the mux is completely opened in server mode. */ gensio_done_err acc_open_done; void *acc_open_data; /* * Channel I am currently sending data on. */ struct mux_inst *sending_chan; enum mux_state state; /* If the mux was shutdown due to an error, this is set. */ bool err_shutdown; /* Am I currently receiving header or data? */ bool in_hdr; /* Current working incoming header. */ unsigned char hdr[MUX_MAX_HDR_SIZE]; unsigned int hdr_pos; unsigned int hdr_size; enum mux_msgs msgid; /* Working info when receiving the beginning of the data. */ unsigned int data_pos; unsigned int data_size; /* * Channel I am currently receiving for. */ struct mux_inst *curr_chan; /* The last id we chose for a channel. */ unsigned int last_id; /* Mux instances with write pending. */ struct gensio_list wrchans; /* Muxes waiting to open. */ struct gensio_list openchans; unsigned int opencount; /* * Used when doing an error close and we get a normal close in the * mean time. This will cause the error close to invoke the * normal close. */ bool do_normal_close; struct mux_inst *do_normal_close_chan; /* * All the channels in the mux. The channels are kept in id * order. */ struct gensio_list chans; #ifdef MUX_TRACING struct mux_trace_info trace[MUX_TRACE_SIZE]; unsigned int trace_pos; #endif }; static void i_mux_set_state(struct mux_data *mux, enum mux_state state) { mux->state = state; } static void i_muxc_set_state(struct mux_inst *chan, enum mux_inst_state state) { chan->state = state; } #ifdef MUX_TRACING static void i_mux_add_trace(struct mux_data *mux, struct mux_inst *chan, enum mux_state state, enum mux_state new_state, enum mux_inst_state cstate, enum mux_inst_state new_cstate, int line) { unsigned int pos = mux->trace_pos; mux->trace[pos].chan = chan; mux->trace[pos].state = state; mux->trace[pos].new_state = new_state; mux->trace[pos].cstate = cstate; mux->trace[pos].new_cstate = new_cstate; mux->trace[pos].line = line; if (pos >= MUX_TRACE_SIZE - 1) mux->trace_pos = 0; else mux->trace_pos = pos + 1; } #define mux_add_trace(mux, chan, new_state, new_cstate) \ i_mux_add_trace(mux, chan, mux->state, new_state, chan->state, \ new_cstate, __LINE__) #define mux_set_state(mux, nstate) do { \ i_mux_add_trace(mux, NULL, mux->state, nstate, 99, 99, __LINE__);\ i_mux_set_state(mux, nstate); \ } while(false) #define muxc_set_state(chan, nstate) do { \ i_mux_add_trace(chan->mux, chan, chan->mux->state, 99, \ chan->state, nstate, __LINE__); \ i_muxc_set_state(chan, nstate); \ } while(false) #else #define i_mux_add_trace(mux, chan, state, cstate, new_state, new_cstate, line) #define mux_add_trace(mux, chan, cstate, new_cstate) #define mux_set_state i_mux_set_state #define muxc_set_state i_muxc_set_state #endif static void chan_sched_deferred_op(struct mux_inst *chan); static int muxc_gensio_handler(struct gensio *io, int func, gensiods *count, const void *cbuf, gensiods buflen, void *buf, const char *const *auxdata); static void muxc_add_to_wrlist(struct mux_inst *chan); static void mux_shutdown_channels(struct mux_data *muxdata, int err); static int mux_firstchan_event(struct mux_data *muxdata, int event, int err, unsigned char *buf, gensiods *buflen, const char * const * auxdata); static void gmux_log_err(struct mux_data *f, const char *fmt, ...) { int rv; struct gensio_log_data d; d.level = GENSIO_LOG_ERR; d.log = fmt; va_start(d.args, fmt); rv = mux_firstchan_event(f, GENSIO_EVENT_LOG, 0, (unsigned char *) &d, NULL, NULL); if (rv == GE_NOTSUP) gensio_vlog(f->o, GENSIO_LOG_ERR, fmt, d.args); va_end(d.args); } static void muxdata_free(struct mux_data *muxdata) { assert(gensio_list_empty(&muxdata->chans)); if (muxdata->lock) muxdata->o->free_lock(muxdata->lock); if (muxdata->child) gensio_free(muxdata->child); muxdata->o->free(muxdata->o, muxdata); } static void i_mux_lock(struct mux_data *muxdata) { muxdata->o->lock(muxdata->lock); } static void i_mux_unlock(struct mux_data *muxdata) { muxdata->o->unlock(muxdata->lock); } #ifdef MUX_TRACING #define mux_lock(m) do { \ i_mux_lock(m); \ i_mux_add_trace(m, NULL, m->state, 99, 99, 100, __LINE__); \ } while (false) #define mux_unlock(m) do { \ i_mux_add_trace(m, NULL, m->state, 99, 99, 101, __LINE__); \ i_mux_unlock(m); \ } while (false) #else #define mux_lock i_mux_lock #define mux_unlock i_mux_unlock #endif static void i_mux_ref(struct mux_data *mux) { assert(mux->refcount > 0); mux->refcount++; } static bool i_mux_deref(struct mux_data *mux) { assert(mux->refcount > 0); if (--mux->refcount == 0) { muxdata_free(mux); return true; } return false; } static bool i_mux_deref_and_unlock(struct mux_data *mux) { assert(mux->refcount > 0); if (--mux->refcount == 0) { i_mux_unlock(mux); muxdata_free(mux); return true; } i_mux_unlock(mux); return false; } #ifdef MUX_TRACING #define mux_ref(m) do { \ i_mux_add_trace(m, NULL, m->state, 99, 104, \ m->refcount + 2000, __LINE__); \ i_mux_ref(m); \ } while (false) #define mux_deref(m) do { \ i_mux_add_trace(m, NULL, m->state, 99, 105, \ m->refcount + 2000, __LINE__); \ i_mux_deref(m); \ } while (false) #else #define mux_ref i_mux_ref #define mux_deref i_mux_deref #endif static void chan_free(struct mux_inst *chan) { struct gensio_os_funcs *o = chan->o; if (chan->io) gensio_data_free(chan->io); if (chan->read_data) o->free(o, chan->read_data); if (chan->write_data) o->free(o, chan->write_data); if (chan->service) o->free(o, chan->service); if (chan->deferred_op_runner) o->free_runner(chan->deferred_op_runner); o->free(o, chan); } static void i_chan_ref(struct mux_inst *chan) { assert(chan->refcount > 0); chan->refcount++; } static bool i_chan_deref(struct mux_inst *chan) { assert(chan->refcount > 0); if (--chan->refcount == 0) { struct mux_data *mux = chan->mux; gensio_list_rm(&mux->chans, &chan->link); chan_free(chan); i_mux_deref(mux); return true; } return false; } #ifdef MUX_TRACING #define chan_ref(c) do { \ i_mux_add_trace(c->mux, c, c->mux->state, 106, \ c->state, c->refcount + 3000, __LINE__); \ i_chan_ref(c); \ } while (false) static bool i2_chan_deref(struct mux_inst *chan, int line) { i_mux_add_trace(chan->mux, chan, chan->mux->state, 107, chan->state, chan->refcount + 3000, line); return i_chan_deref(chan); } #define chan_deref(c) i2_chan_deref(c, __LINE__) #else #define chan_ref i_chan_ref #define chan_deref i_chan_deref #endif #ifdef MUX_TRACING #define mux_lock_and_ref(m) do { \ i_mux_lock(m); \ i_mux_add_trace(m, NULL, m->state, 99, 102, 2000 + m->refcount, \ __LINE__); \ i_mux_ref(m); \ } while (false) #define mux_deref_and_unlock(m) do { \ i_mux_add_trace(m, NULL, m->state, 99, 103, 2000 + m->refcount, \ __LINE__); \ i_mux_deref_and_unlock(m); \ } while (false) #else #define mux_lock_and_ref(m) do { \ i_mux_lock(m); \ i_mux_ref(m); \ } while (false) #define mux_deref_and_unlock(m) i_mux_deref_and_unlock(m) #endif static struct mux_inst * mux_chan0(struct mux_data *muxdata) { return gensio_container_of(gensio_list_first(&muxdata->chans), struct mux_inst, link); } static struct mux_inst * mux_firstchan(struct mux_data *muxdata) { struct gensio_link *l; struct mux_inst *chan; gensio_list_for_each(&muxdata->chans, l) { chan = gensio_container_of(l, struct mux_inst, link); if (chan->state != MUX_INST_CLOSED && chan->state != MUX_INST_PENDING_OPEN) return chan; } abort(); } static int mux_firstchan_event(struct mux_data *muxdata, int event, int err, unsigned char *buf, gensiods *buflen, const char * const * auxdata) { int rerr; struct mux_inst *chan; chan = mux_firstchan(muxdata); chan_ref(chan); mux_unlock(muxdata); rerr = gensio_cb(chan->io, event, err, buf, buflen, auxdata); mux_lock(muxdata); chan_deref(chan); return rerr; } static bool mux_channel_set_closed(struct mux_inst *chan, gensio_done close_done, void *close_data) { struct mux_data *muxdata = chan->mux; int err; muxc_set_state(chan, MUX_INST_CLOSED); assert(muxdata->nr_not_closed > 0); muxdata->nr_not_closed--; mux_add_trace(muxdata, chan, 150, muxdata->nr_not_closed); if (muxdata->nr_not_closed == 0) { /* There are no open instances, shut the mux down. */ if (muxdata->state == MUX_IN_CLOSE) { muxdata->do_normal_close = true; muxdata->do_normal_close_chan = chan; return true; } mux_set_state(muxdata, MUX_IN_CLOSE); err = gensio_close(muxdata->child, close_done, close_data); if (!err) return true; } return false; } static void finish_close(struct mux_inst *chan) { struct mux_data *muxdata = chan->mux; if (chan->close_done) { gensio_done close_done = chan->close_done; chan->close_done = NULL; /* * Note that we already have ref-ed the channel when the close * started, no need to ref it again here. */ mux_unlock(muxdata); close_done(chan->io, chan->close_data); mux_lock(muxdata); } chan_deref(chan); } static void i_finish_close_close_done(struct mux_inst *chan, struct mux_data *muxdata) { mux_set_state(muxdata, MUX_CLOSED); finish_close(chan); } static void finish_close_close_done(struct gensio *child, void *close_data) { struct mux_inst *chan = close_data; struct mux_data *muxdata = chan->mux; mux_lock_and_ref(muxdata); i_finish_close_close_done(chan, muxdata); mux_deref_and_unlock(muxdata); } static void mux_channel_finish_close(struct mux_inst *chan) { if (!mux_channel_set_closed(chan, finish_close_close_done, chan)) finish_close(chan); } static void mux_send_new_channel_rsp(struct mux_data *muxdata, unsigned int remote_id, unsigned int max_read_size, unsigned int id, int err) { muxdata->xmit_data[0] = (MUX_NEW_CHANNEL_RSP << 4) | 0x3; muxdata->xmit_data[1] = 0; gensio_u16_to_buf(&muxdata->xmit_data[2], remote_id); gensio_u32_to_buf(&muxdata->xmit_data[4], max_read_size); gensio_u16_to_buf(&muxdata->xmit_data[8], id); gensio_u16_to_buf(&muxdata->xmit_data[10], err); muxdata->xmit_data_pos = 0; muxdata->xmit_data_len = 12; gensio_set_write_callback_enable(muxdata->child, true); } static void mux_send_init(struct mux_data *muxdata) { muxdata->xmit_data[0] = (MUX_INIT << 4) | 0x1; muxdata->xmit_data[1] = 0; muxdata->xmit_data[2] = 1; muxdata->xmit_data[3] = 0; muxdata->xmit_data_pos = 0; muxdata->xmit_data_len = 4; } /* * Must be called with an extra refcount held. */ static void chan_check_send_more(struct mux_inst *chan) { int err; if (chan->in_write_ready) /* Another caller is already handling, just let it retry. */ return; chan->in_write_ready = true; /* Need at least 4 bytes to write a message. */ while (chan->max_write_size - chan->write_data_len >= 4 && chan->write_ready_enabled && chan->state == MUX_INST_OPEN) { chan_ref(chan); mux_unlock(chan->mux); err = gensio_cb(chan->io, GENSIO_EVENT_WRITE_READY, 0, NULL, NULL, NULL); mux_lock(chan->mux); if (chan_deref(chan)) return; /* chan was freed. */ if (err) { chan->errcode = err; break; } } chan->in_write_ready = false; } static bool full_msg_ready(struct mux_inst *chan, gensiods *rlen) { gensiods len; if (chan->read_data_len == 0) return false; assert(chan->read_data_len >= 3); len = chan->read_data[chan_next_read_pos(chan, 1)] << 8; len |= chan->read_data[chan_next_read_pos(chan, 2)]; assert(len > 0); if (rlen) *rlen = len; return len + 3 <= chan->read_data_len; } /* * Must be called with an extra refcount held. */ static void chan_check_read(struct mux_inst *chan) { struct mux_data *muxdata = chan->mux; unsigned char flags; gensiods len = 0, olen, rcount, orcount, pos, to_ack; const char *flstr[3]; unsigned int i; bool fullmsg; int err; while (((fullmsg = full_msg_ready(chan, &len)) || chan->errcode) && chan->read_enabled && !chan->in_read_report) { if (chan->errcode && !fullmsg) { /* error is true and a full message is not present. */ chan->in_read_report = true; chan->read_enabled = false; mux_unlock(muxdata); err = gensio_cb(chan->io, GENSIO_EVENT_READ, chan->errcode, NULL, NULL, NULL); mux_lock(muxdata); chan->in_read_report = false; if (err) break; continue; } flags = chan->read_data[chan->read_data_pos]; pos = chan_next_read_pos(chan, 3); to_ack = 0; olen = 0; chan->in_read_report = true; i = 0; if (flags & MUX_FLAG_OUT_OF_BOUND) { if (!chan->do_oob) { rcount = len; orcount = rcount; goto skip_oob_data; } flstr[i++] = "oob"; } flstr[i] = NULL; if (pos + len > chan->max_read_size) { /* Buffer wraps, deliver in two parts. */ rcount = chan->max_read_size - pos; orcount = rcount; mux_unlock(muxdata); err = gensio_cb(chan->io, GENSIO_EVENT_READ, 0, chan->read_data + pos, &rcount, flstr); mux_lock(muxdata); if (err) { chan->errcode = err; goto after_read_done; } if (rcount > orcount) rcount = orcount; skip_oob_data: len -= rcount; to_ack += rcount; olen += rcount; if (rcount < orcount || !chan->read_enabled) /* User didn't consume all data. */ goto after_read_done; pos = 0; } rcount = len; orcount = rcount; mux_unlock(muxdata); if (flags & MUX_FLAG_END_OF_MESSAGE) flstr[i++] = "eom"; flstr[i] = NULL; err = gensio_cb(chan->io, GENSIO_EVENT_READ, 0, chan->read_data + pos, &rcount, flstr); mux_lock(muxdata); if (err) { chan->errcode = err; goto after_read_done; } if (rcount > orcount) rcount = orcount; len -= rcount; to_ack += rcount; olen += rcount; after_read_done: chan->in_read_report = false; if (len > 0) { /* Partial read, create a new 3-byte header over the data left. */ chan->read_data_pos = chan_next_read_pos(chan, olen); chan->read_data_len -= olen; chan->read_data[chan->read_data_pos] = flags; chan->read_data[chan_next_read_pos(chan, 1)] = len >> 8; chan->read_data[chan_next_read_pos(chan, 2)] = len & 0xff; } else { chan->read_data_pos = chan_next_read_pos(chan, olen + 3); chan->read_data_len -= olen + 3; to_ack += 3; } chan->received_unacked += to_ack; } /* * Schedule an ack send if we need it. The send_close thing may * look strange, but we delay finishing the close until all read * data is delivered, so if all the data is processed and a close * is pending, we send it. */ if (chan->received_unacked || (chan->send_close && chan->read_data_len == 0)) muxc_add_to_wrlist(chan); } static void chan_deferred_op(struct gensio_runner *runner, void *cbdata) { struct mux_inst *chan = cbdata; struct mux_data *muxdata = chan->mux; mux_lock_and_ref(muxdata); chan->deferred_op_pending = false; chan_check_send_more(chan); chan_check_read(chan); /* * If there is a not full message pending, there is no data to send, * we are not currently in a read/write callback, and we are ready to * finish the close. */ if (!chan->wr_ready && !chan->in_write_ready && !chan->deferred_op_pending && !chan->in_read_report && chan->state == MUX_INST_IN_CLOSE_FINAL) mux_channel_finish_close(chan); chan_deref(chan); mux_deref_and_unlock(muxdata); } static void chan_sched_deferred_op(struct mux_inst *chan) { if (!chan->deferred_op_pending) { chan_ref(chan); chan->deferred_op_pending = true; chan->o->run(chan->deferred_op_runner); } } static void muxc_add_to_wrlist(struct mux_inst *chan) { struct mux_data *muxdata = chan->mux; if (!chan->wr_ready && !muxdata->err_shutdown) { assert(!chan->in_wrlist); gensio_list_add_tail(&muxdata->wrchans, &chan->wrlink); chan->wr_ready = true; chan->in_wrlist = true; if (muxdata->state != MUX_CLOSED) gensio_set_write_callback_enable(muxdata->child, true); } } static int muxc_write(struct mux_inst *chan, gensiods *count, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { struct mux_data *muxdata = chan->mux; gensiods rcount, i, tot_len = 0; unsigned char hdr[3]; gensiods len; bool truncated = false; for (i = 0; i < sglen; i++) tot_len += sg[i].buflen; if (tot_len == 0) { *count = 0; return 0; } tot_len += 3; /* Add the header. */ mux_lock(muxdata); if (chan->state != MUX_INST_OPEN) { mux_unlock(muxdata); return GE_NOTREADY; } if (chan->errcode) { int err = chan->errcode; mux_unlock(muxdata); return err; } if (chan->in_newchannel) { /* * The user sent from the new channel event. This is a fairly * complicated scenario, the user may expect a data exchange, * so we can't wait for the return from the new channel event * here. In this case, we go ahead and finish the channel * response and set in_newchannel to 0 to tell the new channel * event handling what happened. */ chan->in_newchannel = 0; mux_send_new_channel_rsp(muxdata, chan->remote_id, chan->max_read_size, chan->id, 0); if (chan->service_len) { /* Ack the service data. */ chan->received_unacked = chan->service_len; muxc_add_to_wrlist(chan); } } /* * Just return on buffer full. We need 3 bytes for the header and at * least a byte of data. */ if (chan->max_write_size - chan->write_data_len < 4) { out_unlock_nosend: mux_unlock(muxdata); if (count) *count = 0; return 0; } if (tot_len > chan->max_write_size - chan->write_data_len) { /* Can only send as much as we have buffer for. */ tot_len = chan->max_write_size - chan->write_data_len; if (tot_len <= 3) goto out_unlock_nosend; truncated = true; } if (tot_len > chan->send_window_size / 2) { /* Only allow sends to 1/2 the window size. */ tot_len = chan->send_window_size / 2; if (tot_len <= 3) goto out_unlock_nosend; truncated = true; } /* FIXME - consolidate writes if possible. */ /* Construct the header and put it in first. */ hdr[0] = 0; /* flags */ if (!truncated && gensio_str_in_auxdata(auxdata, "eom")) hdr[0] |= MUX_FLAG_END_OF_MESSAGE; if (gensio_str_in_auxdata(auxdata, "oob")) hdr[0] |= MUX_FLAG_OUT_OF_BOUND; gensio_u16_to_buf(hdr + 1, tot_len - 3); chan_addwrbuf(chan, hdr, 3); tot_len -= 3; rcount = 0; for (i = 0; i < sglen && tot_len; i++) { len = sg[i].buflen; if (len > tot_len) len = tot_len; chan_addwrbuf(chan, sg[i].buf, len); rcount += len; tot_len -= len; } muxc_add_to_wrlist(chan); mux_unlock(muxdata); if (count) *count = rcount; return 0; } static void muxc_set_read_callback_enable(struct mux_inst *chan, bool enabled) { mux_lock(chan->mux); if (chan->read_enabled != enabled) { chan->read_enabled = enabled; if (enabled) chan_sched_deferred_op(chan); } mux_unlock(chan->mux); } static void muxc_set_write_callback_enable(struct mux_inst *chan, bool enabled) { mux_lock(chan->mux); if (chan->write_ready_enabled != enabled) { chan->write_ready_enabled = enabled; if (enabled) chan_sched_deferred_op(chan); } mux_unlock(chan->mux); } static void chan_send_close(struct mux_inst *chan) { assert(chan->sglen == 0); chan->hdr[0] = (MUX_CLOSE_CHANNEL << 4) | 0x2; chan->hdr[1] = 0; gensio_u16_to_buf(&chan->hdr[2], chan->remote_id); if (chan->errcode == GE_REMCLOSE) gensio_u16_to_buf(&chan->hdr[4], 0); else gensio_u16_to_buf(&chan->hdr[4], chan->errcode); gensio_u16_to_buf(&chan->hdr[6], 0); chan->sg[0].buf = chan->hdr; chan->sg[0].buflen = 8; chan->sglen = 1; chan->cur_msg_len = 0; /* Data isn't in chan->write_data. */ muxc_add_to_wrlist(chan); } static int muxc_close_nolock(struct mux_inst *chan, gensio_done close_done, void *close_data) { switch (chan->state) { case MUX_INST_IN_OPEN: /* Handle it once the open response is received. */ muxc_set_state(chan, MUX_INST_IN_OPEN_CLOSE); break; case MUX_INST_IN_REM_CLOSE: muxc_set_state(chan, MUX_INST_IN_CLOSE_FINAL); chan_sched_deferred_op(chan); break; case MUX_INST_OPEN: muxc_set_state(chan, MUX_INST_IN_CLOSE); if (chan->in_newchannel) { chan->in_newchannel = 2; muxc_set_state(chan, MUX_INST_IN_CLOSE_FINAL); chan_sched_deferred_op(chan); } else { chan->send_close = true; muxc_add_to_wrlist(chan); } break; default: return GE_NOTREADY; } chan_ref(chan); chan->close_done = close_done; chan->close_data = close_data; return 0; } static int muxc_close(struct mux_inst *chan, gensio_done close_done, void *close_data) { struct mux_data *muxdata = chan->mux; int err = GE_NOTREADY; mux_lock(muxdata); if (!chan->close_called) { chan->close_called = true; err = muxc_close_nolock(chan, close_done, close_data); } mux_unlock(muxdata); return err; } static void muxc_free(struct mux_inst *chan) { struct mux_data *muxdata = chan->mux; mux_lock_and_ref(muxdata); if (chan->in_newchannel) { chan->in_newchannel = 2; goto out_deref; } switch (chan->state) { case MUX_INST_IN_REM_CLOSE: case MUX_INST_IN_CLOSE: case MUX_INST_IN_CLOSE_FINAL: case MUX_INST_IN_OPEN_CLOSE: chan->close_done = NULL; /* deref will cause it to be freed when the close is finished. */ break; case MUX_INST_CLOSED: /* deref will cause it to be freed here. */ break; case MUX_INST_OPEN: case MUX_INST_IN_OPEN: muxc_close_nolock(chan, NULL, NULL); assert(chan->refcount > 1); break; case MUX_INST_PENDING_OPEN: /* Shouldn't be possible. */ abort(); } out_deref: chan_deref(chan); mux_deref_and_unlock(muxdata); } static int muxc_disable(struct mux_inst *chan) { struct mux_data *muxdata = chan->mux; mux_set_state(muxdata, MUX_CLOSED); gensio_disable(muxdata->child); return 0; } static unsigned int next_chan_id(struct mux_data *muxdata, unsigned int num) { if (num >= muxdata->max_channels - 1) return 0; else return num + 1; } static int mux_new_channel(struct mux_data *muxdata, gensio_event cb, void *user_data, bool is_client, struct mux_inst **new_mux) { struct mux_inst *chan; unsigned int id; struct gensio_os_funcs *o = muxdata->o; int err = GE_NOMEM; chan = o->zalloc(o, sizeof(*chan)); if (!chan) return GE_NOMEM; chan->o = o; chan->deferred_op_runner = o->alloc_runner(o, chan_deferred_op, chan); if (!chan->deferred_op_runner) goto out_free; chan->io = gensio_data_alloc(o, cb, user_data, muxc_gensio_handler, muxdata->child, "mux-instance", chan); if (!chan->io) goto out_free; gensio_set_is_packet(chan->io, true); gensio_set_is_reliable(chan->io, true); gensio_set_is_mux(chan->io, true); if (gensio_is_authenticated(muxdata->child)) gensio_set_is_authenticated(chan->io, true); if (gensio_is_encrypted(muxdata->child)) gensio_set_is_encrypted(chan->io, true); chan->mux = muxdata; chan->refcount = 1; chan->is_client = is_client; chan->max_read_size = muxdata->max_read_size; chan->max_write_size = muxdata->max_write_size; chan->read_data = o->zalloc(o, chan->max_read_size); if (!chan->read_data) goto out_free; chan->write_data = o->zalloc(o, chan->max_write_size); if (!chan->write_data) goto out_free; /* * We maintain the list in number order and rotate through the * numbers. So we start after the last number used and rotate * through the entries until we find an empty spot. */ if (gensio_list_empty(&muxdata->chans)) { gensio_list_add_tail(&muxdata->chans, &chan->link); /* Note that we do not claim a ref here, there is already one. */ } else { struct gensio_link *l, *p = &muxdata->chans.link, *f; struct mux_inst *tchan = NULL; /* First find the place at or before where the last number starts. */ id = muxdata->last_id; gensio_list_for_each(&muxdata->chans, l) { tchan = gensio_container_of(l, struct mux_inst, link); if (tchan->id > id) break; p = l; } id = next_chan_id(muxdata, id); l = gensio_list_next_wrap(&muxdata->chans, p); f = l; do { tchan = gensio_container_of(l, struct mux_inst, link); if (id != tchan->id) goto found; id = next_chan_id(muxdata, id); p = l; l = gensio_list_next_wrap(&muxdata->chans, p); } while (f != l); tchan = gensio_container_of(l, struct mux_inst, link); if (id != tchan->id) goto found; err = GE_INUSE; out_free: /* Didn't find a free number. */ chan_free(chan); return err; found: chan->id = id; muxdata->last_id = id; gensio_list_add_next(&muxdata->chans, p, &chan->link); mux_ref(muxdata); } *new_mux = chan; return 0; } static int muxc_alloc_channel_data(struct mux_data *muxdata, gensio_event cb, void *user_data, struct gensio_mux_config *data, struct gensio **new_io) { struct mux_inst *chan = NULL; int err = 0; err = mux_new_channel(muxdata, cb, user_data, data->is_client, &chan); if (err) goto out_err; if (data->service) { if (data->service_len > chan->max_write_size - 10) { err = GE_TOOBIG; goto out_err; } chan->service = gensio_strdup(muxdata->o, data->service); if (!chan->service) { err = GE_NOMEM; goto out_err; } chan->service_len = data->service_len; } muxc_set_state(chan, MUX_INST_CLOSED); if (new_io) *new_io = chan->io; return 0; out_err: if (chan) chan_deref(chan); return err; } static int gensio_mux_config(struct gensio_pparm_info *p, struct gensio_os_funcs *o, const char * const args[], struct gensio_mux_config *data) { unsigned int i; int rv = GE_NOMEM; const char *str; data->o = o; for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(p, args[i], "readbuf", &data->max_read_size) > 0) continue; if (gensio_pparm_ds(p, args[i], "writebuf", &data->max_write_size) > 0) continue; if (gensio_pparm_boolv(p, args[i], "mode", "client", "server", &data->is_client) > 0) continue; if (gensio_pparm_uint(p, args[i], "max_channels", &data->max_channels) > 0) { if (data->max_channels > 65536 || data->max_channels < 1) { rv = GE_INVAL; goto out_err; } continue; } if (gensio_pparm_value(p, args[i], "service", &str) > 0) { data->service = gensio_strdup(o, str); if (!data->service) goto out_err; data->service_len = strlen(data->service); continue; } rv = GE_INVAL; goto out_err; } return 0; out_err: return rv; } static void gensio_mux_config_cleanup(struct gensio_mux_config *data) { struct gensio_os_funcs *o; if (!data) return; o = data->o; if (data->service) o->free(o, data->service); } /* If the mode is specified in the default, override is_client. */ static int get_default_mode(struct gensio_os_funcs *o, bool *is_client) { int rv; char *str; rv = gensio_get_default(o, "mux", "mode", false, GENSIO_DEFAULT_STR, &str, NULL); if (rv) { gensio_log(o, GENSIO_LOG_ERR, "Failed getting mux mode, ignoring: %s", gensio_err_to_str(rv)); return rv; } if (str) { if (strcasecmp(str, "client") == 0) *is_client = true; else if (strcasecmp(str, "server") == 0) *is_client = false; else { gensio_log(o, GENSIO_LOG_ERR, "Unknown default mux mode (%s), ignoring", str); } o->free(o, str); } return 0; } static int muxc_alloc_channel(struct mux_data *muxdata, struct gensio_func_alloc_channel_data *ocdata) { int err; struct gensio_mux_config data; GENSIO_DECLARE_PPGENSIO(p, muxdata->o, ocdata->cb, "mux", ocdata->user_data); mux_lock(muxdata); if (muxdata->state != MUX_OPEN) { err = GE_NOTREADY; goto out_unlock; } memset(&data, 0, sizeof(data)); data.max_read_size = muxdata->max_read_size; data.max_write_size = muxdata->max_write_size; data.max_channels = muxdata->max_channels; data.is_client = true; err = get_default_mode(muxdata->o, &data.is_client); if (err) return err; err = gensio_mux_config(&p, muxdata->o, ocdata->args, &data); if (err) return err; err = muxc_alloc_channel_data(muxdata, ocdata->cb, ocdata->user_data, &data, &ocdata->new_io); gensio_mux_config_cleanup(&data); out_unlock: mux_unlock(muxdata); return err; } static void mux_call_open_done(struct mux_data *muxdata, struct mux_inst *chan, int err) { gensio_done_err open_done = chan->open_done; void *open_data = chan->open_data; chan->open_done = NULL; if (open_done) { mux_unlock(muxdata); open_done(chan->io, err, open_data); mux_lock(muxdata); } chan_deref(chan); } static void mux_child_open_done(struct gensio *child, int err, void *open_data) { struct mux_data *muxdata = open_data; struct mux_inst *chan; mux_lock_and_ref(muxdata); chan = mux_chan0(muxdata); if (err) { mux_shutdown_channels(muxdata, err); muxdata->nr_not_closed = 0; } else if (chan->state != MUX_INST_IN_OPEN) { /* A close was requested, handle it. */ muxc_set_state(chan, MUX_INST_CLOSED); mux_call_open_done(muxdata, chan, 0); mux_channel_finish_close(chan); } else { mux_set_state(muxdata, MUX_UNINITIALIZED); muxc_set_state(chan, MUX_INST_IN_OPEN); gensio_set_write_callback_enable(muxdata->child, true); gensio_set_read_callback_enable(muxdata->child, true); } mux_deref_and_unlock(muxdata); } static void muxc_reinit(struct mux_inst *chan) { muxc_set_state(chan, MUX_INST_CLOSED); chan->send_close = false; chan->close_sent = false; chan->read_enabled = false; chan->read_data_pos = 0; chan->read_data_len = 0; chan->in_read_report = false; chan->received_unacked = 0; chan->write_data_pos = 0; chan->write_data_len = 0; chan->write_ready_enabled = false; chan->in_write_ready = false; chan->sent_unacked = 0; chan->deferred_op_pending = false; chan->cur_msg_len = 0; chan->close_done = NULL; chan->wr_ready = false; chan->close_called = false; } static int muxc_open(struct mux_inst *chan, gensio_done_err open_done, void *open_data, bool do_child) { struct mux_data *muxdata = chan->mux; int err = GE_NOTREADY; mux_lock(muxdata); if (muxdata->state == MUX_CLOSED) { muxdata->sending_chan = NULL; muxdata->in_hdr = true; muxdata->hdr_pos = 0; muxdata->hdr_size = 0; muxdata->exit_err = 0; muxdata->err_shutdown = 0; muxdata->do_normal_close = false; muxc_reinit(chan); if (muxdata->is_client) { if (!chan->in_open_chan) { gensio_list_add_tail(&chan->mux->openchans, &chan->wrlink); chan->in_open_chan = true; } chan->mux->opencount = 1; chan->send_new_channel = true; } mux_send_init(muxdata); chan->open_done = open_done; chan->open_data = open_data; muxc_set_state(chan, MUX_INST_IN_OPEN); if (do_child) { err = gensio_open(muxdata->child, mux_child_open_done, muxdata); if (!err) { muxdata->nr_not_closed = 1; mux_set_state(muxdata, MUX_WAITING_CHILD_OPEN); } else { muxc_set_state(chan, MUX_INST_CLOSED); muxdata->opencount--; if (muxdata->is_client && chan->in_open_chan) { gensio_list_rm(&muxdata->openchans, &chan->wrlink); chan->in_open_chan = false; } } } else { muxdata->nr_not_closed = 1; mux_set_state(muxdata, MUX_UNINITIALIZED); gensio_set_write_callback_enable(muxdata->child, true); gensio_set_read_callback_enable(muxdata->child, true); err = 0; } } else { if (!do_child) { err = GE_INVAL; goto out_unlock; } if (chan->state != MUX_INST_CLOSED) goto out_unlock; muxc_reinit(chan); /* Only one open at a time is allowed, queue them otherwise. */ if (muxdata->opencount == 0 && muxdata->state == MUX_OPEN) { muxc_add_to_wrlist(chan); } else { gensio_list_add_tail(&muxdata->openchans, &chan->wrlink); chan->in_open_chan = true; } muxdata->opencount++; muxdata->nr_not_closed++; chan->open_done = open_done; chan->open_data = open_data; chan->send_new_channel = true; muxc_set_state(chan, MUX_INST_IN_OPEN); err = 0; } if (!err) chan_ref(chan); /* Claim the ref we hold while open. */ out_unlock: mux_unlock(muxdata); return err; } static int muxc_control(struct mux_inst *chan, bool get, int op, char *data, gensiods *datalen) { struct mux_data *muxdata = chan->mux; int err = 0; mux_lock(muxdata); switch (op) { case GENSIO_CONTROL_SERVICE: if (get) { gensiods to_copy; if (!chan->service) { err = GE_DATAMISSING; goto out; } to_copy = chan->service_len; if (to_copy > *datalen) to_copy = *datalen; memcpy(data, chan->service, to_copy); if (*datalen > to_copy) data[to_copy] = '\0'; *datalen = chan->service_len; } else { char *new_service = chan->o->zalloc(chan->o, *datalen); if (!new_service) { err = GE_NOMEM; goto out; } memcpy(new_service, data, *datalen); if (chan->service) chan->o->free(chan->o, chan->service); chan->service = new_service; chan->service_len = *datalen; } break; case GENSIO_CONTROL_ENABLE_OOB: if (get) *datalen = snprintf(data, *datalen, "%u", chan->do_oob); else chan->do_oob = !!strtoul(data, NULL, 0); break; default: err = GE_NOTSUP; break; } out: mux_unlock(muxdata); return err; } static int muxc_gensio_handler(struct gensio *io, int func, gensiods *count, const void *cbuf, gensiods buflen, void *buf, const char *const *auxdata) { struct mux_inst *chan = gensio_get_gensio_data(io); switch (func) { case GENSIO_FUNC_WRITE_SG: return muxc_write(chan, count, cbuf, buflen, auxdata); case GENSIO_FUNC_CLOSE: return muxc_close(chan, (void *) cbuf, buf); case GENSIO_FUNC_FREE: muxc_free(chan); return 0; case GENSIO_FUNC_SET_READ_CALLBACK: muxc_set_read_callback_enable(chan, buflen); return 0; case GENSIO_FUNC_SET_WRITE_CALLBACK: muxc_set_write_callback_enable(chan, buflen); return 0; case GENSIO_FUNC_DISABLE: return muxc_disable(chan); case GENSIO_FUNC_ALLOC_CHANNEL: return muxc_alloc_channel(chan->mux, buf); case GENSIO_FUNC_OPEN: return muxc_open(chan, (void *) cbuf, buf, true); case GENSIO_FUNC_OPEN_NOCHILD: return muxc_open(chan, (void *) cbuf, buf, false); case GENSIO_FUNC_CONTROL: return muxc_control(chan, *((bool *) cbuf), buflen, buf, count); default: return GE_NOTSUP; } } static void mux_shutdown_channels(struct mux_data *muxdata, int err) { struct gensio_link *l, *l2; struct mux_inst *chan; muxdata->err_shutdown = true; mux_set_state(muxdata, MUX_CLOSED); if (muxdata->acc_open_done && (muxdata->exit_state == MUX_WAITING_OPEN || muxdata->exit_state == MUX_UNINITIALIZED)) { gensio_done_err acc_open_done = muxdata->acc_open_done; void *acc_open_data = muxdata->acc_open_data; chan = mux_chan0(muxdata); muxc_set_state(chan, MUX_INST_CLOSED); muxdata->acc_open_done = NULL; mux_unlock(muxdata); acc_open_done(chan->io, err, acc_open_data); mux_lock(muxdata); } gensio_list_for_each_safe(&muxdata->chans, l, l2) { chan = gensio_container_of(l, struct mux_inst, link); if (chan->in_wrlist) { gensio_list_rm(&muxdata->wrchans, &chan->wrlink); chan->in_wrlist = false; } chan->wr_ready = false; if (chan->in_open_chan) { gensio_list_rm(&muxdata->openchans, &chan->wrlink); chan->in_open_chan = false; } switch (chan->state) { case MUX_INST_IN_CLOSE_FINAL: chan_sched_deferred_op(chan); break; case MUX_INST_CLOSED: case MUX_INST_IN_REM_CLOSE: break; case MUX_INST_PENDING_OPEN: muxc_set_state(chan, MUX_INST_CLOSED); mux_call_open_done(muxdata, chan, err); break; case MUX_INST_IN_OPEN: muxc_set_state(chan, MUX_INST_CLOSED); mux_call_open_done(muxdata, chan, err); break; case MUX_INST_IN_OPEN_CLOSE: muxc_set_state(chan, MUX_INST_CLOSED); chan_ref(chan); /* Don't let the open call free us. */ mux_call_open_done(muxdata, chan, err); finish_close(chan); chan_deref(chan); break; case MUX_INST_IN_CLOSE: /* Just close it. */ muxc_set_state(chan, MUX_INST_CLOSED); finish_close(chan); break; case MUX_INST_OPEN: /* Report the error through the read interface. */ chan->errcode = err; muxc_set_state(chan, MUX_INST_IN_REM_CLOSE); chan_sched_deferred_op(chan); break; } } if (gensio_list_empty(&muxdata->chans)) mux_set_state(muxdata, MUX_CLOSED); } static void chan_setup_send_new_channel(struct mux_inst *chan) { assert(chan->sglen == 0); chan->hdr[0] = (MUX_NEW_CHANNEL << 4) | 0x2; chan->hdr[1] = 0; gensio_u16_to_buf(&chan->hdr[2], chan->id); gensio_u32_to_buf(&chan->hdr[4], chan->max_read_size); gensio_u16_to_buf(&chan->hdr[8], chan->service_len); chan->sg[0].buf = chan->hdr; chan->sg[0].buflen = 10; chan->sglen = 1; if (chan->service_len) { chan->sg[1].buf = chan->service; chan->sg[1].buflen = chan->service_len; chan->sglen++; chan->sent_unacked = chan->service_len; } chan->cur_msg_len = 0; /* Data isn't in chan->write_data. */ } static bool chan_setup_send_data(struct mux_inst *chan) { unsigned char flags = 0; gensiods pos; gensiods window_left = chan->send_window_size - chan->sent_unacked; assert(chan->sglen == 0); chan->hdr[0] = (MUX_DATA << 4) | 0x2; chan->hdr[1] = 0; gensio_u16_to_buf(chan->hdr + 2, chan->remote_id); gensio_u32_to_buf(chan->hdr + 4, chan->received_unacked); chan->sg[0].buf = chan->hdr; chan->sg[0].buflen = 8; if (chan->write_data_len == 0) { check_send_ack: if (chan->received_unacked == 0) return false; chan->received_unacked = 0; /* Just sending an ack. */ gensio_u16_to_buf(chan->hdr + 8, 0); chan->sg[0].buflen = 10; chan->sglen = 1; return true; } assert(chan->write_data_len > 3); pos = chan_next_write_pos(chan, 1); chan->cur_msg_len = chan->write_data[pos] << 8; pos = chan_next_write_pos(chan, 2); chan->cur_msg_len |= chan->write_data[pos]; assert(chan->cur_msg_len > 0); chan->cur_msg_len += 2; /* Make sure to add 1 for the flags */ if (chan->cur_msg_len + 1 > window_left) { chan->cur_msg_len = 0; goto check_send_ack; } chan->received_unacked = 0; flags = chan->write_data[chan->write_data_pos]; chan_incr_write_pos(chan, 1); chan->hdr[1] = flags; chan->sent_unacked++; /* Flags is stored as delivered data on remote end. */ if (chan->write_data_pos + chan->cur_msg_len > chan->max_write_size) { /* Buffer wraps, need three parts for scatter/gatter. */ chan->sglen = 3; chan->sg[1].buf = chan->write_data + chan->write_data_pos; chan->sg[1].buflen = chan->max_write_size - chan->write_data_pos; chan->sg[2].buf = chan->write_data; chan->sg[2].buflen = chan->cur_msg_len - chan->sg[1].buflen; } else { chan->sglen = 2; chan->sg[1].buf = chan->write_data + chan->write_data_pos; chan->sg[1].buflen = chan->cur_msg_len; } chan->sent_unacked += chan->cur_msg_len; return true; } static void mux_on_err_close(struct gensio *child, void *close_data) { struct mux_data *muxdata = close_data; mux_lock_and_ref(muxdata); if (muxdata->do_normal_close) i_finish_close_close_done(muxdata->do_normal_close_chan, muxdata); else mux_shutdown_channels(muxdata, muxdata->exit_err); mux_deref_and_unlock(muxdata); /* Lose the open ref. */ } static int mux_child_write_ready(struct mux_data *muxdata) { int err = 0; struct mux_inst *chan; gensiods rcount; mux_lock_and_ref(muxdata); if (muxdata->state == MUX_IN_CLOSE || muxdata->state == MUX_CLOSED) { gensio_set_read_callback_enable(muxdata->child, false); gensio_set_write_callback_enable(muxdata->child, false); mux_deref_and_unlock(muxdata); return 0; } /* Finish any pending channel data. */ if (muxdata->sending_chan) { chan = muxdata->sending_chan; next_channel: assert(chan->sglen > 0 && chan->sgpos < chan->sglen); err = gensio_write_sg(muxdata->child, &rcount, chan->sg + chan->sgpos, chan->sglen - chan->sgpos, NULL); if (err) goto out_write_err; while (rcount > 0 && chan->sgpos < chan->sglen) { if (chan->sg[chan->sgpos].buflen <= rcount) { rcount -= chan->sg[chan->sgpos].buflen; chan->sgpos++; assert(chan->sgpos <= 3); } else { chan->sg[chan->sgpos].buflen -= rcount; chan->sg[chan->sgpos].buf = ((char *) chan->sg[chan->sgpos].buf) + rcount; rcount = 0; } } if (chan->sgpos >= chan->sglen) { /* Finished sending one message. */ chan->write_data_pos = chan_next_write_pos(chan, chan->cur_msg_len); chan->write_data_len -= chan->cur_msg_len; chan->cur_msg_len = 0; chan->sgpos = 0; chan->sglen = 0; muxdata->sending_chan = NULL; if (chan->write_data_len > 0 || chan->send_new_channel || chan->send_close) { /* More messages to send, add it to the tail for fairness. */ gensio_list_add_tail(&muxdata->wrchans, &chan->wrlink); chan->in_wrlist = true; } else { chan->wr_ready = false; } /* * Maybe the user can write. Also, if a close is pending, * handle it there, too. */ chan_sched_deferred_op(chan); } else { /* Couldn't send all the data. */ goto out; } } /* Handle data not associated with an existing channel. */ if (muxdata->xmit_data_len) { struct gensio_sg sg[1]; sg[0].buf = muxdata->xmit_data + muxdata->xmit_data_pos; sg[0].buflen = muxdata->xmit_data_len; err = gensio_write_sg(muxdata->child, &rcount, sg, 1, NULL); if (err) goto out_write_err; if (rcount >= muxdata->xmit_data_len) { muxdata->xmit_data_len = 0; muxdata->xmit_data_pos = 0; } else { /* Partial write, can't write anything else. */ muxdata->xmit_data_len -= rcount; muxdata->xmit_data_pos += rcount; goto out; } } /* Now look for a new channel to send. */ check_next_channel: if (!gensio_list_empty(&muxdata->wrchans)) { assert(muxdata->sending_chan == NULL); chan = gensio_container_of(gensio_list_first(&muxdata->wrchans), struct mux_inst, wrlink); gensio_list_rm(&muxdata->wrchans, &chan->wrlink); chan->in_wrlist = false; if (chan->send_new_channel) { chan_setup_send_new_channel(chan); chan->send_new_channel = false; muxdata->sending_chan = chan; } else if ((chan->write_data_len || chan->received_unacked) && !chan->close_sent) { /* * Send a data packet, either for data delivery or an ack. * Once we send a close, we cannot send any more data, * thus the check in the if statement above. */ if (!chan_setup_send_data(chan)) { chan->wr_ready = false; goto check_next_channel; } muxdata->sending_chan = chan; } else if (chan->send_close && (chan->read_data_len == 0 || chan->state == MUX_INST_IN_CLOSE || chan->state == MUX_INST_IN_CLOSE_FINAL)) { /* * Do the close last so all data is sent. The state * checks above are there because we want to delay the * send close if we are in MUX_INST_IN_REM_CLOSE to * deliver all the data the remote end sent before * reporting the close, but if our end requested the * close, send it after all local data has been sent. */ chan_send_close(chan); chan->send_close = false; chan->close_sent = true; muxdata->sending_chan = chan; } else { chan->wr_ready = false; goto check_next_channel; } goto next_channel; } out: gensio_set_write_callback_enable(muxdata->child, muxdata->sending_chan || !gensio_list_empty(&muxdata->wrchans)); mux_deref_and_unlock(muxdata); return 0; out_write_err: gensio_set_read_callback_enable(muxdata->child, false); gensio_set_write_callback_enable(muxdata->child, false); muxdata->exit_err = err; muxdata->exit_state = muxdata->state; mux_set_state(muxdata, MUX_IN_CLOSE); err = gensio_close(muxdata->child, mux_on_err_close, muxdata); if (err) mux_shutdown_channels(muxdata, err); mux_deref_and_unlock(muxdata); return 0; } static struct mux_inst * mux_get_channel(struct mux_data *muxdata) { struct gensio_link *l; unsigned int id = gensio_buf_to_u16(muxdata->hdr + 2); gensio_list_for_each(&muxdata->chans, l) { struct mux_inst *chan = gensio_container_of(l, struct mux_inst, link); if (chan->id == id) return chan; } return NULL; } static bool mux_find_remote_id(struct mux_data *muxdata, unsigned int id) { struct gensio_link *l; gensio_list_for_each(&muxdata->chans, l) { struct mux_inst *chan = gensio_container_of(l, struct mux_inst, link); if (chan->remote_id == id && chan->state != MUX_INST_PENDING_OPEN && chan->state != MUX_INST_IN_OPEN && chan->state != MUX_INST_IN_OPEN_CLOSE && chan->state != MUX_INST_IN_CLOSE_FINAL) return true; } return false; } static int mux_child_read(struct mux_data *muxdata, int ierr, unsigned char *buf, gensiods *ibuflen, const char *const *nauxdata) { gensiods processed = 0, used, acked, buflen; int err = 0; struct mux_inst *chan; const char *auxdata[2] = { NULL, NULL }; const char *proto_err_str = "?"; mux_lock_and_ref(muxdata); if (muxdata->state == MUX_IN_CLOSE || muxdata->state == MUX_CLOSED) { gensio_set_read_callback_enable(muxdata->child, false); gensio_set_write_callback_enable(muxdata->child, false); mux_deref_and_unlock(muxdata); return 0; } if (ierr) goto out_err; if (gensio_str_in_auxdata(nauxdata, "oob")) { /* We can't handle OOB data here. */ mux_deref_and_unlock(muxdata); return 0; } buflen = *ibuflen; while (buflen > 0) { if (muxdata->in_hdr) { if (muxdata->hdr_pos == 0) { /* * The first byte of the header contains what we need * to process the rest of the header. */ muxdata->hdr[muxdata->hdr_pos++] = *buf; muxdata->hdr_size = (*buf & 0xf) * 4; if (muxdata->hdr_size > MUX_MAX_HDR_SIZE) { proto_err_str = "Invalid header size"; goto protocol_err; } muxdata->msgid = *buf >> 4; if (muxdata->msgid <= 0 || muxdata->msgid > MUX_MAX_MSG_NUM) { proto_err_str = "msgid out of range"; goto protocol_err; } if (mux_msg_hdr_sizes[muxdata->msgid] > muxdata->hdr_size) { proto_err_str = "Invalid header size"; goto protocol_err; } used = 1; goto more_data; } if (buflen + muxdata->hdr_pos < muxdata->hdr_size) { /* The header is not completely received, partial copy. */ memcpy(muxdata->hdr + muxdata->hdr_pos, buf, buflen); muxdata->hdr_pos += buflen; processed += buflen; goto out_unlock; } /* We have the whole header now. */ used = muxdata->hdr_size - muxdata->hdr_pos; memcpy(muxdata->hdr + muxdata->hdr_pos, buf, used); muxdata->hdr_pos = 0; if (muxdata->msgid == MUX_INIT) { if (muxdata->state != MUX_UNINITIALIZED) { proto_err_str = "Init when already initialized"; goto protocol_err; } if (gensio_list_empty(&muxdata->openchans)) { mux_set_state(muxdata, MUX_WAITING_OPEN); goto more_data; } else { chan = NULL; mux_set_state(muxdata, MUX_IN_OPEN); goto next_channel_req_send; } } if (muxdata->state == MUX_UNINITIALIZED) { proto_err_str = "Not initialized"; goto protocol_err; } switch (muxdata->msgid) { case MUX_NEW_CHANNEL: { unsigned int remote_id = gensio_buf_to_u16(muxdata->hdr + 2); bool was_chan0 = false; if (muxdata->state == MUX_WAITING_OPEN) { chan = mux_chan0(muxdata); was_chan0 = true; } else { if (mux_find_remote_id(muxdata, remote_id)) { proto_err_str = "New remote channel for existing one"; goto protocol_err; } if (mux_new_channel(muxdata, NULL, NULL, false, &chan)) chan = NULL; else muxdata->nr_not_closed++; } muxdata->curr_chan = chan; if (chan) { muxc_set_state(chan, MUX_INST_PENDING_OPEN); chan->send_window_size = gensio_buf_to_u32(muxdata->hdr + 4); if (chan->send_window_size <= MUX_MIN_SEND_WINDOW_SIZE) { proto_err_str = "Invalid send window size"; if (was_chan0) goto protocol_err; else goto protocol_err_close_chan; } chan->remote_id = remote_id; muxdata->data_pos = 0; muxdata->in_hdr = false; /* Receive the service data */ } break; } case MUX_NEW_CHANNEL_RSP: chan = mux_get_channel(muxdata); if (!chan) { proto_err_str = "No channel for channel response"; goto protocol_err; } if (chan->state != MUX_INST_IN_OPEN && chan->state != MUX_INST_IN_OPEN_CLOSE) { proto_err_str = "Invalid channel state on open response"; goto protocol_err; } if (muxdata->state == MUX_IN_OPEN) { mux_set_state(muxdata, MUX_OPEN); } else if (muxdata->state != MUX_OPEN && muxdata->state != MUX_IN_CLOSE) { proto_err_str = "New channel response in bad state"; goto protocol_err; } chan->remote_id = gensio_buf_to_u16(muxdata->hdr + 8); chan->send_window_size = gensio_buf_to_u32(muxdata->hdr + 4); if (chan->send_window_size <= MUX_MIN_SEND_WINDOW_SIZE) { proto_err_str = "Invalid send window size"; goto protocol_err; } chan->errcode = gensio_buf_to_u16(muxdata->hdr + 10); muxdata->sending_chan = NULL; assert(muxdata->opencount > 0); muxdata->opencount--; if (chan->errcode) { enum mux_inst_state old_state = chan->state; muxc_set_state(chan, MUX_INST_CLOSED); mux_call_open_done(muxdata, chan, chan->errcode); if (old_state == MUX_INST_IN_OPEN_CLOSE) i_finish_close_close_done(chan, muxdata); chan = NULL; } else if (chan->state == MUX_INST_IN_OPEN_CLOSE) { muxc_set_state(chan, MUX_INST_IN_CLOSE); mux_call_open_done(muxdata, chan, GE_LOCALCLOSED); chan->send_close = true; muxc_add_to_wrlist(chan); chan = NULL; } else { muxc_set_state(chan, MUX_INST_OPEN); } next_channel_req_send: /* Start the next channel open, if necessary. */ if (!gensio_list_empty(&muxdata->openchans)) { struct mux_inst *next_chan = gensio_container_of( gensio_list_first(&muxdata->openchans), struct mux_inst, wrlink); gensio_list_rm(&muxdata->openchans, &next_chan->wrlink); next_chan->in_open_chan = false; muxc_add_to_wrlist(next_chan); } else { assert(muxdata->opencount == 0); } if (chan) { chan_ref(chan); mux_call_open_done(muxdata, chan, chan->errcode); if (chan_deref(chan)) goto more_data; /* Deliver a read error if read is enabled. */ if (chan->read_enabled) chan_sched_deferred_op(chan); } break; case MUX_CLOSE_CHANNEL: chan = mux_get_channel(muxdata); if (!chan || chan->state == MUX_INST_CLOSED || chan->state == MUX_INST_IN_OPEN || chan->state == MUX_INST_IN_OPEN_CLOSE || chan->state == MUX_INST_IN_CLOSE_FINAL || chan->state == MUX_INST_IN_REM_CLOSE) { proto_err_str = "Invalid channel state on close"; goto protocol_err; } chan->errcode = gensio_buf_to_u16(muxdata->hdr + 4); if (chan->state == MUX_INST_IN_CLOSE) { muxc_set_state(chan, MUX_INST_IN_CLOSE_FINAL); /* Do the close as a deferred op. */ chan_sched_deferred_op(chan); } else { muxc_set_state(chan, MUX_INST_IN_REM_CLOSE); if (chan->errcode == 0) chan->errcode = GE_REMCLOSE; chan->send_close = true; muxc_add_to_wrlist(chan); chan_sched_deferred_op(chan); } /* If we receive a close, don't send any more data. */ chan->write_data_len = 0; break; case MUX_DATA: chan = mux_get_channel(muxdata); if (!chan) { proto_err_str = "No channel on data"; goto protocol_err; } if (chan->state == MUX_INST_CLOSED || chan->state == MUX_INST_IN_OPEN || chan->state == MUX_INST_IN_OPEN_CLOSE || chan->state == MUX_INST_IN_CLOSE_FINAL || chan->state == MUX_INST_IN_REM_CLOSE) { proto_err_str = "Invalid channel state on data"; goto protocol_err; } acked = gensio_buf_to_u32(muxdata->hdr + 4); if (acked > chan->sent_unacked) { proto_err_str = "acked > chan->sent_unacked"; goto protocol_err; } chan->sent_unacked -= acked; if (acked > 0 && chan->write_data_len) muxc_add_to_wrlist(chan); muxdata->curr_chan = chan; muxdata->data_pos = 0; muxdata->in_hdr = false; /* Receive the data */ break; default: abort(); } more_data: processed += used; buf += used; buflen -= used; } else { /* * We are receiving data from the remote end, either service * or payload. The first two bytes is always the data length. */ if (muxdata->data_pos == 0) { muxdata->data_size = *buf << 8; muxdata->data_pos++; used = 1; goto more_data; } chan = muxdata->curr_chan; if (muxdata->data_pos == 1) { muxdata->data_size |= *buf; muxdata->data_pos++; used = 1; switch (muxdata->msgid) { case MUX_NEW_CHANNEL: if (!chan) /* Channel allocation failed, just abort. */ break; chan->service_len = muxdata->data_size; if (muxdata->data_size == 0) goto new_chan_no_service; chan->service = muxdata->o->zalloc(muxdata->o, muxdata->data_size + 1); if (!chan->service) { muxdata->curr_chan = NULL; chan_deref(chan); /* NULL curr_chan will cause an error to be sent. */ } break; case MUX_DATA: assert(chan); if (muxdata->data_size == 0) goto handle_read_no_data; if (chan_rdbufleft(chan) < muxdata->data_size + 3) { proto_err_str = "Too much data from remote end"; goto protocol_err; } /* Add the message flags first. */ chan_addrdbyte(chan, muxdata->hdr[1]); chan_addrdbyte(chan, muxdata->data_size >> 8); chan_addrdbyte(chan, muxdata->data_size & 0xff); break; default: abort(); } goto more_data; } /* Receiving message data. */ switch (muxdata->msgid) { case MUX_NEW_CHANNEL: if (buflen + muxdata->data_pos - 2 < muxdata->data_size) { /* Not enough data for service yet. */ if (chan) memcpy(chan->service + muxdata->data_pos - 2, buf, buflen); muxdata->data_pos += buflen; processed += buflen; goto out_unlock; } used = muxdata->data_size + 2 - muxdata->data_pos; if (chan) { memcpy(chan->service + muxdata->data_pos - 2, buf, used); } else { err = GE_INUSE; if (muxdata->xmit_data_len) { /* Only one new channel allowed at a time. */ proto_err_str = "New channel while in progress"; goto protocol_err; } mux_send_new_channel_rsp(muxdata, gensio_buf_to_u16(muxdata->hdr + 2), 0, 0, err); goto finish_new_chan; } new_chan_no_service: muxc_set_state(chan, MUX_INST_OPEN); if (muxdata->state == MUX_WAITING_OPEN) { /* * This is the first channel, deliver to the * gensio_acc_gensio code as an open. */ mux_set_state(muxdata, MUX_OPEN); mux_send_new_channel_rsp(muxdata, chan->remote_id, chan->max_read_size, chan->id, 0); if (muxdata->acc_open_done) { mux_unlock(muxdata); muxdata->acc_open_done(chan->io, 0, muxdata->acc_open_data); mux_lock(muxdata); } else { mux_call_open_done(muxdata, chan, 0); } } else { if (muxdata->xmit_data_len) { proto_err_str = "New channel while in progress"; goto protocol_err_close_chan; } if (chan->service) auxdata[0] = chan->service; else auxdata[0] = ""; chan->in_newchannel = 1; chan_ref(chan); err = mux_firstchan_event(muxdata, GENSIO_EVENT_NEW_CHANNEL, 0, (void *) chan->io, 0, auxdata); if (chan->in_newchannel == 0) { /* * The user did a write, so the new channel * response and service data ack are already * done. If an error is returned, we close * the channel. */ if (err && chan->state == MUX_INST_OPEN) { chan->errcode = err; muxc_set_state(chan, MUX_INST_IN_CLOSE); chan->send_close = true; muxc_add_to_wrlist(chan); } goto new_chan_done; } if (!err && chan->in_newchannel == 2) err = GE_REMCLOSE; chan->in_newchannel = 0; mux_send_new_channel_rsp(muxdata, chan->remote_id, chan->max_read_size, chan->id, err); if (err) { if (chan->state == MUX_INST_OPEN) /* * We might have gone to in_close, let the * close call happen in that case. */ muxc_set_state(chan, MUX_INST_CLOSED); } else if (chan->service_len) { /* Ack the service data. */ chan->received_unacked = chan->service_len; muxc_add_to_wrlist(chan); } new_chan_done: chan_deref(chan); } finish_new_chan: muxdata->in_hdr = true; goto more_data; case MUX_DATA: assert(chan); if (buflen + muxdata->data_pos < muxdata->data_size + 2) { /* Not all data received yet. */ chan_addrdbuf(chan, buf, buflen); muxdata->data_pos += buflen; processed += buflen; goto out_unlock; } used = muxdata->data_size + 2 - muxdata->data_pos; chan_addrdbuf(chan, buf, used); handle_read_no_data: chan_ref(chan); chan_check_send_more(chan); if (muxdata->data_size) chan_check_read(chan); chan_deref(chan); muxdata->in_hdr = true; goto more_data; default: abort(); } } } out_unlock: mux_deref_and_unlock(muxdata); *ibuflen = processed; return 0; protocol_err_close_chan: /* * A protocol error was reported before the channel was reported * to the user. Just delete the channel, otherwise it will not * get cleaned up on the close and the close of the mux will never * happen. */ chan_deref(muxdata->curr_chan); muxdata->curr_chan = NULL; protocol_err: ierr = GE_PROTOERR; out_err: gensio_set_read_callback_enable(muxdata->child, false); gensio_set_write_callback_enable(muxdata->child, false); muxdata->exit_state = muxdata->state; muxdata->exit_err = ierr; mux_set_state(muxdata, MUX_IN_CLOSE); err = gensio_close(muxdata->child, mux_on_err_close, muxdata); if (err) mux_shutdown_channels(muxdata, ierr); mux_deref_and_unlock(muxdata); if (err == GE_PROTOERR) gmux_log_err(muxdata, "Protocol error: %s\n", proto_err_str); return 0; } static int mux_child_cb(struct gensio *io, void *user_data, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) { struct mux_data *muxdata = user_data; int rv; switch (event) { case GENSIO_EVENT_READ: return mux_child_read(muxdata, err, buf, buflen, auxdata); case GENSIO_EVENT_WRITE_READY: return mux_child_write_ready(muxdata); case GENSIO_EVENT_NEW_CHANNEL: return GE_NOTSUP; default: mux_lock_and_ref(muxdata); rv = mux_firstchan_event(muxdata, event, err, buf, buflen, auxdata); mux_deref_and_unlock(muxdata); return rv; } } static int mux_gensio_alloc_data(struct gensio *child, struct gensio_mux_config *data, gensio_event cb, void *user_data, struct mux_data **rmuxdata) { struct gensio_os_funcs *o = data->o; struct mux_data *muxdata; int rv; if (data->max_write_size < MUX_MIN_SEND_WINDOW_SIZE || data->max_read_size < MUX_MIN_SEND_WINDOW_SIZE) return GE_INVAL; muxdata = o->zalloc(o, sizeof(*muxdata)); if (!muxdata) return GE_NOMEM; mux_set_state(muxdata, MUX_IN_ALLOC); muxdata->o = o; muxdata->refcount = 1; muxdata->is_client = data->is_client; muxdata->child = child; muxdata->in_hdr = true; muxdata->max_write_size = data->max_write_size; muxdata->max_read_size = data->max_read_size; muxdata->max_channels = data->max_channels; gensio_list_init(&muxdata->chans); gensio_list_init(&muxdata->openchans); gensio_list_init(&muxdata->wrchans); muxdata->lock = o->alloc_lock(o); if (!muxdata->lock) goto out_nomem; gensio_set_callback(child, mux_child_cb, muxdata); /* Set up to send the init message. */ mux_send_init(muxdata); /* Allocate channel 0. */ rv = muxc_alloc_channel_data(muxdata, cb, user_data, data, NULL); if (rv) goto out_nomem; mux_set_state(muxdata, MUX_CLOSED); muxdata->nr_not_closed = 1; *rmuxdata = muxdata; return 0; out_nomem: if (!gensio_list_empty(&muxdata->chans)) chan_deref(gensio_container_of( gensio_list_first(&muxdata->chans), struct mux_inst, link)); if (muxdata->lock) o->free_lock(muxdata->lock); o->free(o, muxdata); return GE_NOMEM; } static int mux_gensio_alloc(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **net) { int err; struct gensio *io; struct gensio_mux_config data; struct mux_data *muxdata; int ival; GENSIO_DECLARE_PPGENSIO(p, o, cb, "mux", user_data); if (!gensio_is_reliable(child)) /* Cowardly refusing to run MUX over an unreliable connection. */ return GE_NOTSUP; memset(&data, 0, sizeof(data)); data.max_read_size = GENSIO_DEFAULT_BUF_SIZE * 16; data.max_write_size = GENSIO_DEFAULT_BUF_SIZE * 2; data.max_channels = 1000; err = gensio_get_default(o, "mux", "max-channels", false, GENSIO_DEFAULT_INT, NULL, &ival); if (err) return err; data.max_channels = ival; data.is_client = true; err = get_default_mode(o, &data.is_client); if (err) return err; err = gensio_mux_config(&p, o, args, &data); if (err) return err; err = mux_gensio_alloc_data(child, &data, cb, user_data, &muxdata); gensio_mux_config_cleanup(&data); if (err) return err; io = mux_chan0(muxdata)->io; gensio_set_is_packet(io, true); gensio_set_is_reliable(io, true); gensio_set_is_mux(io, true); if (gensio_is_encrypted(child)) gensio_set_is_encrypted(io, true); *net = io; return 0; } static int str_to_mux_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct gensio *io2; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio(str, o, cb, user_data, &io2); if (err) return err; err = mux_gensio_alloc(io2, args, o, cb, user_data, new_gensio); if (err) gensio_free(io2); return err; } struct muxna_data { struct gensio_accepter *acc; struct gensio_mux_config data; struct gensio_os_funcs *o; }; static void muxna_free(struct muxna_data *nadata) { gensio_mux_config_cleanup(&nadata->data); nadata->o->free(nadata->o, nadata); } static int muxna_alloc_gensio(struct muxna_data *nadata, const char * const *iargs, struct gensio *child, struct gensio **rio) { return mux_gensio_alloc(child, iargs, nadata->o, NULL, NULL, rio); } static int muxna_new_child(struct muxna_data *nadata, void **finish_data, struct gensio_new_child_io *ncio) { struct mux_data *muxdata; struct mux_inst *chan; int err; err = mux_gensio_alloc_data(ncio->child, &nadata->data, NULL, NULL, &muxdata); if (!err) { mux_lock(muxdata); chan = mux_chan0(muxdata); ncio->new_io = chan->io; mux_set_state(muxdata, MUX_UNINITIALIZED); muxdata->acc_open_done = ncio->open_done; muxdata->acc_open_data = ncio->open_data; mux_unlock(muxdata); *finish_data = muxdata; } return err; } static int muxna_finish_parent(struct mux_data *muxdata) { gensio_set_write_callback_enable(muxdata->child, true); gensio_set_read_callback_enable(muxdata->child, true); return 0; } static int gensio_gensio_acc_mux_cb(void *acc_data, int op, void *data1, void *data2, void *data3, const void *data4) { switch (op) { case GENSIO_GENSIO_ACC_ALLOC_GENSIO: return muxna_alloc_gensio(acc_data, data4, data1, data2); case GENSIO_GENSIO_ACC_NEW_CHILD_IO: return muxna_new_child(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FREE: muxna_free(acc_data); return 0; case GENSIO_GENSIO_ACC_FINISH_PARENT: return muxna_finish_parent(data1); default: return GE_NOTSUP; } } static int mux_gensio_accepter_alloc(struct gensio_accepter *child, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { struct muxna_data *nadata; int err, ival; GENSIO_DECLARE_PPACCEPTER(p, o, cb, "mux", user_data); if (!gensio_acc_is_reliable(child)) /* Cowardly refusing to run MUX over an unreliable connection. */ return GE_NOTSUP; nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) return GE_NOMEM; nadata->data.max_read_size = GENSIO_DEFAULT_BUF_SIZE; nadata->data.max_write_size = GENSIO_DEFAULT_BUF_SIZE; nadata->data.max_channels = 1000; err = gensio_get_default(o, "mux", "max-channels", false, GENSIO_DEFAULT_INT, NULL, &ival); if (err) { o->free(o, nadata); return err; } nadata->data.max_channels = ival; nadata->data.is_client = false; err = get_default_mode(o, &nadata->data.is_client); if (err) { o->free(o, nadata); return err; } err = gensio_mux_config(&p, o, args, &nadata->data); if (err) { o->free(o, nadata); return err; } nadata->o = o; err = gensio_gensio_accepter_alloc(child, o, "mux", cb, user_data, gensio_gensio_acc_mux_cb, nadata, &nadata->acc); if (err) goto out_err; gensio_acc_set_is_packet(nadata->acc, true); gensio_acc_set_is_reliable(nadata->acc, true); gensio_acc_set_is_mux(nadata->acc, true); *accepter = nadata->acc; return 0; out_err: muxna_free(nadata); return err; } static int str_to_mux_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { int err; struct gensio_accepter *acc2 = NULL; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio_accepter(str, o, cb, user_data, &acc2); if (!err) { err = mux_gensio_accepter_alloc(acc2, args, o, cb, user_data, acc); if (err) gensio_acc_free(acc2); } return err; } int gensio_init_mux(struct gensio_os_funcs *o) { int rv; rv = register_filter_gensio(o, "mux", str_to_mux_gensio, mux_gensio_alloc); if (rv) return rv; rv = register_filter_gensio_accepter(o, "mux", str_to_mux_gensio_accepter, mux_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/gensio_net.c0000664000175000017500000012237615011177264011544 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* This code handles TCP and Unix network I/O. */ #include "config.h" #ifdef __linux__ #define _GNU_SOURCE /* For struct ucred. */ #define HAVE_NATIVE_UCRED #endif #include #include #include #include #if HAVE_UNIX #include #include #include #include #include #include #include #include #include #endif #include #include #include #include #include #include #include #include "gensio_net.h" #ifdef _WIN32 #include #include #endif #ifdef HAVE_NATIVE_UCRED static int netna_get_ucred(struct gensio_os_funcs *o, int fd, struct ucred *cred) { socklen_t len = sizeof(*cred); if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, cred, &len) == -1) return gensio_os_err_to_err(o, errno); return 0; } #elif HAVE_UCRED struct ucred { pid_t pid; uid_t uid; gid_t gid; }; #endif /* * The below is based on the code in glib2, gio/gcredentials. If you * want to implement this for something else, like other BSDs or * solaris, you can see that code for what to do. */ #if defined(__APPLE__) || defined(__FreeBSD__) #include static int netna_get_ucred(struct gensio_os_funcs *o, int fd, struct ucred *cred) { struct xucred c; socklen_t len = sizeof(c); pid_t pid = 0; if (getsockopt(fd, SOL_LOCAL, LOCAL_PEERCRED, &c, &len) == -1) return gensio_os_err_to_err(o, errno); #ifdef LOCAL_PEERPID len = sizeof(pid); if (getsockopt(fd, SOL_LOCAL, LOCAL_PEERPID, &pid, &len) == -1) return gensio_os_err_to_err(o, errno); #endif cred->pid = pid; cred->uid = c.cr_uid; cred->gid = c.cr_gid; return 0; } #endif struct net_data { struct gensio_os_funcs *o; struct gensio_ll *ll; struct gensio_addr *ai; /* Iterater points to the remote. */ struct gensio_addr *lai; /* Local address, NULL if not set. */ bool nodelay; int protocol; const char *typestr; int last_err; bool do_oob; int oob_char; }; static int net_check_open(void *handler_data, struct gensio_iod *iod, gensio_time *timeout) { struct net_data *tdata = handler_data; tdata->last_err = tdata->o->sock_control(iod, GENSIO_SOCKCTL_CHECK_OPEN, NULL, NULL); return tdata->last_err; } static int net_try_open(struct net_data *tdata, struct gensio_iod **iod, gensio_time *timeout) { struct gensio_iod *new_iod = NULL; int err = GE_INUSE; unsigned int setup = 0; if (tdata->protocol == GENSIO_NET_PROTOCOL_TCP) { setup = (GENSIO_SET_OPENSOCK_REUSEADDR | GENSIO_OPENSOCK_REUSEADDR | GENSIO_SET_OPENSOCK_NODELAY); setup |= GENSIO_SET_OPENSOCK_KEEPALIVE | GENSIO_OPENSOCK_KEEPALIVE; if (tdata->nodelay) setup |= GENSIO_OPENSOCK_NODELAY; } retry: err = tdata->o->socket_open(tdata->o, tdata->ai, tdata->protocol, &new_iod); if (err) goto out; err = tdata->o->socket_set_setup(new_iod, setup, tdata->lai); if (err) goto out; err = tdata->o->connect(new_iod, tdata->ai); if (err == GE_INPROGRESS) { *iod = new_iod; goto out_return; } /* * The GE_NOMEM check is strange here, but it really has more to * do with testing. connect() is not going to return GE_NOMEM * unless it's an error trigger failure, and we really want to * fail in that case or we will get a "error triggered but no * failure" in the test. */ if (err && err != GE_NOMEM) { if (gensio_addr_next(tdata->ai)) { tdata->o->close(&new_iod); goto retry; } } out: if (err) { if (new_iod) tdata->o->close(&new_iod); } else { *iod = new_iod; } out_return: return err; } static int net_retry_open(void *handler_data, struct gensio_iod **iod, gensio_time *timeout) { struct net_data *tdata = handler_data; if (!gensio_addr_next(tdata->ai)) return tdata->last_err; return net_try_open(tdata, iod, timeout); } static int net_sub_open(void *handler_data, struct gensio_iod **iod, gensio_time *timeout) { struct net_data *tdata = handler_data; gensio_addr_rewind(tdata->ai); return net_try_open(tdata, iod, timeout); } static void net_free(void *handler_data) { struct net_data *tdata = handler_data; if (tdata->ai) gensio_addr_free(tdata->ai); if (tdata->lai) gensio_addr_free(tdata->lai); tdata->o->free(tdata->o, tdata); } static int net_control(void *handler_data, struct gensio_iod *iod, bool get, unsigned int option, char *data, gensiods *datalen) { struct net_data *tdata = handler_data; int rv, val; unsigned int i, setup; gensiods pos, size; struct gensio_addr *addr; switch (option) { case GENSIO_CONTROL_NODELAY: if (tdata->protocol != GENSIO_NET_PROTOCOL_TCP) return GE_NOTSUP; if (get) { if (iod) { setup = GENSIO_SET_OPENSOCK_NODELAY; rv = tdata->o->socket_get_setup(iod, &setup); if (rv) return rv; val = !!(setup & GENSIO_OPENSOCK_NODELAY); } else { val = tdata->nodelay; } *datalen = snprintf(data, *datalen, "%d", val); } else { val = strtoul(data, NULL, 0); if (iod) { setup = GENSIO_SET_OPENSOCK_NODELAY; if (val) setup |= GENSIO_OPENSOCK_NODELAY; rv = tdata->o->socket_set_setup(iod, val, NULL); if (rv) return rv; } tdata->nodelay = val; } return 0; case GENSIO_CONTROL_LADDR: if (!get) return GE_NOTSUP; if (strtoul(data, NULL, 0) > 0) return GE_NOTFOUND; rv = tdata->o->sock_control(iod, GENSIO_SOCKCTL_GET_SOCKNAME, &addr, NULL); if (rv) return rv; pos = 0; rv = gensio_addr_to_str(addr, data, &pos, *datalen); gensio_addr_free(addr); if (rv) return rv; *datalen = pos; return 0; case GENSIO_CONTROL_RADDR: if (!get) return GE_NOTSUP; if (strtoul(data, NULL, 0) > 0) return GE_NOTFOUND; pos = 0; rv = gensio_addr_to_str(tdata->ai, data, &pos, *datalen); if (rv) return rv; *datalen = pos; return 0; case GENSIO_CONTROL_RADDR_BIN: if (!get) return GE_NOTSUP; gensio_addr_getaddr(tdata->ai, data, datalen); return 0; case GENSIO_CONTROL_LPORT: if (!get) return GE_NOTSUP; size = sizeof(unsigned int); rv = tdata->o->sock_control(iod, GENSIO_SOCKCTL_GET_PORT, &i, &size); if (rv) return rv; *datalen = snprintf(data, *datalen, "%d", i); return 0; case GENSIO_CONTROL_ENABLE_OOB: if (get) *datalen = snprintf(data, *datalen, "%u", tdata->do_oob); else tdata->do_oob = !!strtoul(data, NULL, 0); return 0; case GENSIO_CONTROL_DRAIN_COUNT: if (!get) return GE_NOTSUP; rv = tdata->o->bufcount(iod, GENSIO_OUT_BUF, &size); if (rv) return rv; *datalen = snprintf(data, *datalen, "%lu", (unsigned long) size); return 0; default: return GE_NOTSUP; } } static int net_except_read(struct gensio_iod *iod, void *data, gensiods count, gensiods *rcount, const char ***auxdata, void *cb_data) { struct net_data *tdata = cb_data; static const char *argv[3] = { "oob", "oobtcp", NULL }; if (tdata->oob_char >= 0) { if (tdata->do_oob) { *auxdata = argv; if (count == 0) { *rcount = 0; return 0; } *((unsigned char *) data) = tdata->oob_char; tdata->oob_char = -1; *rcount = 1; return 0; } tdata->oob_char = -1; } return tdata->o->recv(iod, data, count, rcount, 0); } static int net_except_ready(void *handler_data, struct gensio_iod *iod) { struct net_data *tdata = handler_data; unsigned char urgdata; gensiods rcount = 0; int rv; if (tdata->protocol != GENSIO_NET_PROTOCOL_TCP) return GE_NOTSUP; rv = tdata->o->recv(iod, &urgdata, 1, &rcount, GENSIO_MSG_OOB); if (rv || rcount == 0) return GE_NOTSUP; tdata->oob_char = urgdata; gensio_fd_ll_handle_incoming(tdata->ll, net_except_read, NULL, tdata); return 0; } static int net_write(void *handler_data, struct gensio_iod *iod, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { struct net_data *tdata = handler_data; int flags = 0; if (auxdata) { int i; for (i = 0; auxdata[i]; i++) { if (strcasecmp(auxdata[i], "oob") == 0) flags |= GENSIO_MSG_OOB; else if (strcasecmp(auxdata[i], "oobtcp") == 0) flags |= GENSIO_MSG_OOB; else return GE_INVAL; } } return tdata->o->send(iod, sg, sglen, rcount, flags); } static int net_check_close(void *handler_data, struct gensio_iod *iod, enum gensio_ll_close_state state, gensio_time *timeout) { struct net_data *tdata = handler_data; int err; if (state == GENSIO_LL_CLOSE_STATE_START) return 0; err = tdata->o->graceful_close(&iod); if (err == GE_INPROGRESS && timeout) { timeout->secs = 0; timeout->nsecs = 1000000; } return err; } static const struct gensio_fd_ll_ops net_fd_ll_ops = { .sub_open = net_sub_open, .check_open = net_check_open, .retry_open = net_retry_open, .free = net_free, .control = net_control, .except_ready = net_except_ready, .write = net_write, .check_close = net_check_close }; static int net_gensio_alloc(const struct gensio_addr *iai, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, int protocol, const char *typestr, struct gensio_base_parms **rparms, struct gensio **new_gensio) { struct net_data *tdata = NULL; struct gensio_addr *laddr = NULL, *laddr2, *addr = NULL; struct gensio *io; gensiods max_read_size = GENSIO_DEFAULT_BUF_SIZE; bool nodelay = false; unsigned int i; int ival, err; bool istcp = protocol == GENSIO_NET_PROTOCOL_TCP; struct gensio_base_parms *parms; GENSIO_DECLARE_PPGENSIO(p, o, cb, typestr, user_data); if (rparms) { parms = *rparms; } else { err = gensio_base_parms_alloc(o, false, typestr, &parms); if (err) goto out_err; } err = gensio_get_default(o, typestr, "nodelay", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (err) goto out_err; nodelay = ival; err = gensio_get_defaultaddr(o, typestr, "laddr", false, GENSIO_NET_PROTOCOL_TCP, true, false, &laddr); if (err && err != GE_NOTSUP) { gensio_log(o, GENSIO_LOG_ERR, "Invalid default %d laddr: %s", typestr, gensio_err_to_str(err)); goto out_err; } err = gensio_get_default(o, typestr, "nodelay", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (err) goto out_err; nodelay = ival; for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(&p, args[i], "readbuf", &max_read_size) > 0) continue; if (istcp && gensio_pparm_addrs(&p, args[i], "laddr", GENSIO_NET_PROTOCOL_TCP, true, false, &laddr2) > 0) { if (laddr) gensio_addr_free(laddr); laddr = laddr2; continue; } if (istcp && gensio_pparm_bool(&p, args[i], "nodelay", &nodelay) > 0) continue; if (laddr) gensio_addr_free(laddr); if (gensio_base_parm(parms, &p, args[i]) > 0) continue; gensio_pparm_unknown_parm(&p, args[i]); err = GE_INVAL; goto out_err; } tdata = o->zalloc(o, sizeof(*tdata)); if (!tdata) goto out_nomem; tdata->protocol = protocol; tdata->typestr = typestr; tdata->oob_char = -1; addr = gensio_addr_dup(iai); if (!addr) goto out_nomem; tdata->o = o; tdata->nodelay = nodelay; tdata->ll = fd_gensio_ll_alloc(o, NULL, &net_fd_ll_ops, tdata, max_read_size, false, false); if (!tdata->ll) goto out_nomem; io = base_gensio_alloc(o, tdata->ll, NULL, NULL, typestr, cb, user_data); if (!io) goto out_nomem; err = gensio_base_parms_set(io, &parms); if (err) goto out_err2; if (rparms) *rparms = NULL; /* Assign these last so gensio_ll_free() won't free it on err. */ tdata->ai = addr; tdata->lai = laddr; gensio_set_is_reliable(io, true); if (protocol == GENSIO_NET_PROTOCOL_UNIX_SEQPACKET) gensio_set_is_packet(io, true); *new_gensio = io; return 0; out_nomem: err = GE_NOMEM; out_err2: if (laddr) gensio_addr_free(laddr); if (addr) gensio_addr_free(addr); if (tdata) { if (tdata->ll) gensio_ll_free(tdata->ll); else /* gensio_ll_free() frees it otherwise. */ o->free(o, tdata); } out_err: if (rparms) gensio_base_parms_free(rparms); else if (parms) gensio_base_parms_free(&parms); return err; } static int str_to_net_gensio(const char *str, const char * const args[], int protocol, const char *typestr, struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { struct gensio_addr *addr; int err; err = gensio_os_scan_netaddr(o, str, false, protocol, &addr); if (err) { GENSIO_DECLARE_PPGENSIO(p, o, cb, typestr, user_data); gensio_pparm_log(&p, "Invalid network address: %s", str); return err; } err = net_gensio_alloc(addr, args, o, cb, user_data, protocol, typestr, NULL, new_gensio); gensio_addr_free(addr); return err; } static int tcp_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { const struct gensio_addr *iai = gdata; return net_gensio_alloc(iai, args, o, cb, user_data, GENSIO_NET_PROTOCOL_TCP, "tcp", NULL, new_gensio); } static int str_to_tcp_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { return str_to_net_gensio(str, args, GENSIO_NET_PROTOCOL_TCP, "tcp", o, cb, user_data, new_gensio); } static int unix_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { #if HAVE_UNIX const struct gensio_addr *iai = gdata; return net_gensio_alloc(iai, args, o, cb, user_data, GENSIO_NET_PROTOCOL_UNIX, "unix", NULL, new_gensio); #else return GE_NOTSUP; #endif } static int unixseq_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { #if HAVE_UNIX && defined(SOCK_SEQPACKET) const struct gensio_addr *iai = gdata; return net_gensio_alloc(iai, args, o, cb, user_data, GENSIO_NET_PROTOCOL_UNIX_SEQPACKET, "unixseq", NULL, new_gensio); #else return GE_NOTSUP; #endif } static int str_to_unix_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { return str_to_net_gensio(str, args, GENSIO_NET_PROTOCOL_UNIX, "unix", o, cb, user_data, new_gensio); } static int str_to_unixseq_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { #if HAVE_UNIX && defined(SOCK_SEQPACKET) return str_to_net_gensio(str, args, GENSIO_NET_PROTOCOL_UNIX_SEQPACKET, "unixseq", o, cb, user_data, new_gensio); #else return GE_NOTSUP; #endif } struct netna_data { struct gensio_accepter *acc; struct gensio_os_funcs *o; struct gensio_lock *lock; struct gensio_runner *cb_en_done_runner; gensiods max_read_size; bool nodelay; gensio_acc_done shutdown_done; gensio_acc_done cb_en_done; struct gensio_addr *ai; /* The address list for the portname. */ struct gensio_opensocks *acceptfds; /* The file descriptor used to accept connections on the NET port. */ #if HAVE_UNIX mode_t mode; bool mode_set; char *owner; char *group; #if HAVE_UCRED const char **permusers; /* Permitted user list. */ const char **permgrps; /* Permitted group list. */ #endif #endif #ifdef HAVE_TCPD_H enum gensio_tcpd_options tcpd; char *tcpd_progname; #endif unsigned int nr_acceptfds; unsigned int nr_accept_close_waiting; unsigned int opensock_flags; int protocol; const char *typestr; }; static const struct gensio_fd_ll_ops net_server_fd_ll_ops = { .free = net_free, .control = net_control, .except_ready = net_except_ready, .write = net_write }; static void netna_fd_cleared(struct gensio_iod *iod, void *cbdata) { struct netna_data *nadata = cbdata; unsigned int num_left, i; for (i = 0; i < nadata->nr_acceptfds; i++) { if (iod == nadata->acceptfds[i].iod) break; } assert(i < nadata->nr_acceptfds); nadata->o->close(&nadata->acceptfds[i].iod); nadata->o->lock(nadata->lock); assert(nadata->nr_accept_close_waiting > 0); num_left = --nadata->nr_accept_close_waiting; if (num_left == 0) { nadata->o->free(nadata->o, nadata->acceptfds); nadata->acceptfds = NULL; } nadata->o->unlock(nadata->lock); if (num_left == 0) nadata->shutdown_done(nadata->acc, NULL); } static void netna_set_fd_enables(struct netna_data *nadata, bool enable) { unsigned int i; for (i = 0; i < nadata->nr_acceptfds; i++) nadata->o->set_read_handler(nadata->acceptfds[i].iod, enable); } static void netna_finish_server_open(struct gensio *net, int err, void *cb_data) { struct netna_data *nadata = cb_data; base_gensio_server_open_done(nadata->acc, net, err); } #if HAVE_UCRED static bool netna_permitted(struct ucred *cred, struct netna_data *nadata) { unsigned int i; char buf[16384]; int err; /* * Either permusers or permgroups must be set here, so we don't * have to check for both being NULL. */ for (i = 0; nadata->permusers && nadata->permusers[i]; i++) { struct passwd pwdbuf, *pwd; err = getpwnam_r(nadata->permusers[i], &pwdbuf, buf, sizeof(buf), &pwd); if (err || !pwd) continue; if (cred->uid == pwd->pw_uid) return true; } for (i = 0; nadata->permgrps && nadata->permgrps[i]; i++) { struct group grpbuf, *grp; err = getgrnam_r(nadata->permgrps[i], &grpbuf, buf, sizeof(buf), &grp); if (err || !grp) continue; if (cred->gid == grp->gr_gid) return true; } return false; } #endif static void netna_readhandler(struct gensio_iod *iod, void *cbdata) { struct netna_data *nadata = cbdata; struct gensio_iod *new_iod = NULL; struct gensio_addr *raddr; struct net_data *tdata = NULL; struct gensio *io = NULL; unsigned int setup = 0; int err; if (nadata->protocol == GENSIO_NET_PROTOCOL_TCP) { setup = (GENSIO_SET_OPENSOCK_REUSEADDR | GENSIO_OPENSOCK_REUSEADDR | GENSIO_SET_OPENSOCK_KEEPALIVE | GENSIO_SET_OPENSOCK_NODELAY); } err = nadata->o->accept(iod, &raddr, &new_iod); if (err) { if (err != GE_NODATA) /* FIXME - maybe shut down the socket I/O? */ gensio_acc_log(nadata->acc, GENSIO_LOG_ERR, "Error accepting net gensio: %s", gensio_err_to_str(err)); return; } err = base_gensio_accepter_new_child_start(nadata->acc); if (err) { gensio_addr_free(raddr); nadata->o->close(&new_iod); return; } #ifdef HAVE_TCPD_H if (nadata->protocol == GENSIO_NET_PROTOCOL_TCP && nadata->tcpd != GENSIO_TCPD_OFF) { const char *msg = gensio_os_check_tcpd_ok(new_iod, nadata->tcpd_progname); if (msg) { if (nadata->tcpd == GENSIO_TCPD_PRINT) { struct gensio_sg sg[1] = { { msg, strlen(msg) } }; nadata->o->send(new_iod, sg, 1, NULL, 0); } gensio_acc_log(nadata->acc, GENSIO_LOG_INFO, "Error accepting net gensio: tcpd check failed"); err = GE_INVAL; goto out_err; } } #endif #if HAVE_UCRED if (nadata->protocol != GENSIO_NET_PROTOCOL_TCP && (nadata->permusers || nadata->permgrps)) { int fd = nadata->o->iod_get_fd(new_iod); struct ucred cred; err = netna_get_ucred(nadata->o, fd, &cred); if (err) { gensio_acc_log(nadata->acc, GENSIO_LOG_INFO, "Error getting peer credentials: %s", gensio_err_to_str(err)); goto out_err; } if (!netna_permitted(&cred, nadata)) { gensio_acc_log(nadata->acc, GENSIO_LOG_INFO, "Error accepting unix gensio: user not permitted"); err = GE_PERM; goto out_err; } } #endif tdata = nadata->o->zalloc(nadata->o, sizeof(*tdata)); if (!tdata) { gensio_acc_log(nadata->acc, GENSIO_LOG_INFO, "Error accepting net gensio: out of memory"); err = GE_NOMEM; goto out_err; } tdata->o = nadata->o; tdata->oob_char = -1; tdata->ai = raddr; tdata->protocol = nadata->protocol; tdata->nodelay = nadata->nodelay; raddr = NULL; if (tdata->protocol == GENSIO_NET_PROTOCOL_TCP) setup |= GENSIO_OPENSOCK_KEEPALIVE; if (tdata->nodelay) setup |= GENSIO_OPENSOCK_NODELAY; err = tdata->o->socket_set_setup(new_iod, setup, NULL); if (err) { gensio_acc_log(nadata->acc, GENSIO_LOG_ERR, "Error setting up net port: %s", gensio_err_to_str(err)); goto out_err; } tdata->ll = fd_gensio_ll_alloc(nadata->o, new_iod, &net_server_fd_ll_ops, tdata, nadata->max_read_size, false, false); if (!tdata->ll) { gensio_acc_log(nadata->acc, GENSIO_LOG_ERR, "Out of memory allocating net ll"); err = GE_NOMEM; goto out_err; } io = base_gensio_server_alloc(nadata->o, tdata->ll, NULL, NULL, nadata->typestr, netna_finish_server_open, nadata); if (!io) { gensio_acc_log(nadata->acc, GENSIO_LOG_ERR, "Out of memory allocating net base"); err = GE_NOMEM; goto out_err; } gensio_set_is_reliable(io, true); if (tdata->protocol == GENSIO_NET_PROTOCOL_UNIX_SEQPACKET) gensio_set_is_packet(io, true); err = gensio_acc_base_parms_apply(nadata->acc, io); if (err) goto out_err; err = base_gensio_server_start(io); if (err) goto out_err; base_gensio_accepter_new_child_end(nadata->acc, io, 0); return; out_err: base_gensio_accepter_new_child_end(nadata->acc, NULL, err); if (io) { gensio_free(io); return; } if (tdata) { if (tdata->ll) { gensio_ll_free(tdata->ll); return; } /* gensio_ll_free() frees it otherwise. */ net_free(tdata); } if (raddr) gensio_addr_free(raddr); if (new_iod) nadata->o->close(&new_iod); } #if HAVE_UNIX || defined(_WIN32) /* * This section is duplicated in gensio_dgram.c. If you fix something * here, fix it there, too. */ #define SIZEOF_SOCKADDR_UN_HEADER \ (sizeof(struct sockaddr_un) - \ sizeof(((struct sockaddr_un *) 0)->sun_path)) #define MAX_UNIX_ADDR_PATH (sizeof(((struct sockaddr_un *) 0)->sun_path) + 1) static void get_unix_addr_path(struct gensio_addr *addr, char *path) { struct sockaddr_storage taddr; struct sockaddr_un *sun = (struct sockaddr_un *) &taddr; gensiods len = sizeof(taddr); /* Remove the socket if it already exists. */ gensio_addr_getaddr(addr, sun, &len); len -= SIZEOF_SOCKADDR_UN_HEADER; /* * Make sure the path is nil terminated. See discussions * in the unix(7) man page on Linux for details. */ memcpy(path, sun->sun_path, len); path[len] = '\0'; } #endif static void netna_rm_unix_socket(struct gensio_addr *addr) { #if HAVE_UNIX || defined(_WIN32) char path[MAX_UNIX_ADDR_PATH]; /* Remove the socket if it already exists. */ get_unix_addr_path(addr, path); #endif #if HAVE_UNIX unlink(path); #endif #ifdef _WIN32 DeleteFile(path); #endif } /* Duplicated in gensio_dgram.c */ static int netna_b4_listen(struct gensio_iod *iod, void *data) { struct netna_data *nadata = data; #if HAVE_UNIX /* uid_t can be unsigned, do a cast to avoid warnings. */ #define GENSIO_UID_INVALID_VAL ((uid_t) -1) char pwbuf[16384]; uid_t ownerid = GENSIO_UID_INVALID_VAL; uid_t groupid = GENSIO_UID_INVALID_VAL; int err; char unpath[MAX_UNIX_ADDR_PATH]; #endif if (nadata->protocol == GENSIO_NET_PROTOCOL_TCP) return 0; #if HAVE_UNIX get_unix_addr_path(nadata->ai, unpath); /* Set up perms for Unix domain sockets. */ if (nadata->mode_set) { err = chmod(unpath, nadata->mode); if (err) goto out_errno; } if (nadata->owner) { struct passwd pwdbuf, *pwd; err = getpwnam_r(nadata->owner, &pwdbuf, pwbuf, sizeof(pwbuf), &pwd); if (err) goto out_errno; if (!pwd) { err = ENOENT; goto out_err; } ownerid = pwd->pw_uid; } if (nadata->group) { struct group grpbuf, *grp; err = getgrnam_r(nadata->group, &grpbuf, pwbuf, sizeof(pwbuf), &grp); if (err) goto out_errno; if (!grp) { err = ENOENT; goto out_err; } groupid = grp->gr_gid; } if (ownerid != GENSIO_UID_INVALID_VAL || groupid != GENSIO_UID_INVALID_VAL) { err = chown(unpath, ownerid, groupid); if (err) goto out_errno; } return 0; out_errno: err = errno; out_err: return gensio_os_err_to_err(nadata->o, err); #else return 0; #endif } static int netna_startup(struct gensio_accepter *accepter, struct netna_data *nadata) { int rv; rv = gensio_os_open_listen_sockets(nadata->o, nadata->ai, netna_readhandler, NULL, netna_fd_cleared, netna_b4_listen, nadata, nadata->opensock_flags, &nadata->acceptfds, &nadata->nr_acceptfds); if (!rv) netna_set_fd_enables(nadata, true); return rv; } static int netna_shutdown(struct gensio_accepter *accepter, struct netna_data *nadata, gensio_acc_done shutdown_done) { unsigned int i; nadata->shutdown_done = shutdown_done; nadata->nr_accept_close_waiting = nadata->nr_acceptfds; for (i = 0; i < nadata->nr_acceptfds; i++) nadata->o->clear_fd_handlers(nadata->acceptfds[i].iod); if (nadata->protocol != GENSIO_NET_PROTOCOL_TCP) /* Remove the socket. */ netna_rm_unix_socket(nadata->ai); return 0; } static void netna_cb_en_done(struct gensio_runner *runner, void *cb_data) { struct netna_data *nadata = cb_data; gensio_acc_done done = nadata->cb_en_done; nadata->cb_en_done = NULL; done(nadata->acc, NULL); } static int netna_set_accept_callback_enable(struct gensio_accepter *accepter, struct netna_data *nadata, bool enabled, gensio_acc_done done) { unsigned int i; if (nadata->cb_en_done) return GE_INUSE; nadata->cb_en_done = done; for (i = 0; i < nadata->nr_acceptfds; i++) nadata->o->set_read_handler(nadata->acceptfds[i].iod, enabled); if (done) nadata->o->run(nadata->cb_en_done_runner); return 0; } static void netna_free(struct gensio_accepter *accepter, struct netna_data *nadata) { if (nadata->lock) nadata->o->free_lock(nadata->lock); if (nadata->cb_en_done_runner) nadata->o->free_runner(nadata->cb_en_done_runner); if (nadata->ai) gensio_addr_free(nadata->ai); #if HAVE_UNIX if (nadata->owner) nadata->o->free(nadata->o, nadata->owner); if (nadata->group) nadata->o->free(nadata->o, nadata->group); #if HAVE_UCRED if (nadata->permusers) gensio_argv_free(nadata->o, nadata->permusers); if (nadata->permgrps) gensio_argv_free(nadata->o, nadata->permgrps); #endif #endif #ifdef HAVE_TCPD_H if (nadata->tcpd_progname) nadata->o->free(nadata->o, nadata->tcpd_progname); #endif nadata->o->free(nadata->o, nadata); } static int netna_str_to_gensio(struct gensio_accepter *accepter, struct netna_data *nadata, const char *addr, gensio_event cb, void *user_data, struct gensio **new_io) { int err; const char *args[5] = { NULL, NULL, NULL, NULL, NULL }; char buf[100]; unsigned int i; gensiods max_read_size = nadata->max_read_size; const char **iargs = NULL; struct gensio_addr *ai = NULL; const char *laddr = NULL, *dummy; bool is_port_set; int protocol = 0; bool nodelay = false; struct gensio_base_parms *parms; GENSIO_DECLARE_PPGENSIO(p, nadata->o, cb, nadata->typestr, user_data); parms = gensio_acc_base_parms_dup(nadata->acc); if (!parms) return GE_NOERR; err = gensio_scan_network_port(nadata->o, addr, false, &ai, &protocol, &is_port_set, NULL, &iargs); if (err) { gensio_pparm_log(&p, "Invalid network address: %s", addr); goto out_err; } err = GE_INVAL; if (nadata->protocol != protocol) goto out_err; if (protocol == GENSIO_NET_PROTOCOL_TCP && !is_port_set) goto out_err; for (i = 0; iargs && iargs[i]; i++) { if (gensio_pparm_ds(&p, iargs[i], "readbuf", &max_read_size) > 0) continue; if (nadata->protocol == GENSIO_NET_PROTOCOL_TCP && gensio_pparm_value(&p, iargs[i], "laddr", &dummy) > 0) { laddr = iargs[i]; continue; } if (nadata->protocol == GENSIO_NET_PROTOCOL_TCP && gensio_pparm_bool(&p, args[i], "nodelay", &nodelay) > 0) continue; if (gensio_base_parm(parms, &p, args[i]) > 0) continue; gensio_pparm_unknown_parm(&p, args[i]); goto out_err; } i = 0; if (max_read_size != GENSIO_DEFAULT_BUF_SIZE) { snprintf(buf, sizeof(buf), "readbuf=%lu", (unsigned long) nadata->max_read_size); args[i++] = buf; } if (laddr) args[i++] = laddr; if (nodelay) args[i++] = "nodelay"; err = net_gensio_alloc(ai, args, nadata->o, cb, user_data, nadata->protocol, nadata->typestr, &parms, new_io); out_err: if (iargs) gensio_argv_free(nadata->o, iargs); if (ai) gensio_addr_free(ai); if (parms) gensio_base_parms_free(&parms); return err; } static int netna_control_laddr(struct netna_data *nadata, bool get, char *data, gensiods *datalen) { unsigned int i; gensiods pos = 0; struct gensio_addr *addr; int rv; if (!get) return GE_NOTSUP; if (nadata->nr_acceptfds == 0) return GE_NOTREADY; i = strtoul(data, NULL, 0); if (i >= nadata->nr_acceptfds) return GE_NOTFOUND; rv = nadata->o->sock_control(nadata->acceptfds[i].iod, GENSIO_SOCKCTL_GET_SOCKNAME, &addr, NULL); if (rv) return rv; rv = gensio_addr_to_str(addr, data, &pos, *datalen); gensio_addr_free(addr); if (rv) return rv; *datalen = pos; return 0; } static int netna_control_lport(struct netna_data *nadata, bool get, char *data, gensiods *datalen) { unsigned int i; if (!get) return GE_NOTSUP; if (nadata->protocol != GENSIO_NET_PROTOCOL_TCP) return GE_NOTSUP; if (nadata->nr_acceptfds == 0) return GE_NOTREADY; i = strtoul(data, NULL, 0); if (i >= nadata->nr_acceptfds) return GE_NOTFOUND; *datalen = snprintf(data, *datalen, "%d", nadata->acceptfds[i].port); return 0; } static int netna_control(struct gensio_accepter *accepter, struct netna_data *nadata, bool get, unsigned int option, char *data, gensiods *datalen) { switch (option) { case GENSIO_ACC_CONTROL_LADDR: return netna_control_laddr(nadata, get, data, datalen); case GENSIO_ACC_CONTROL_LPORT: return netna_control_lport(nadata, get, data, datalen); #ifdef HAVE_TCPD_H case GENSIO_ACC_CONTROL_TCPDNAME: if (get) { if (!nadata->tcpd_progname) return GE_NODATA; *datalen = snprintf(data, *datalen, "%s", nadata->tcpd_progname); } else { char *newval = strdup(data); if (!newval) return GE_NOMEM; if (nadata->tcpd_progname) nadata->o->free(nadata->o, nadata->tcpd_progname); nadata->tcpd_progname = newval; } return 0; #endif default: return GE_NOTSUP; } } static void netna_disable(struct gensio_accepter *accepter, struct netna_data *nadata) { unsigned int i; for (i = 0; i < nadata->nr_acceptfds; i++) nadata->o->clear_fd_handlers_norpt(nadata->acceptfds[i].iod); for (i = 0; i < nadata->nr_acceptfds; i++) nadata->o->close(&nadata->acceptfds[i].iod); } static int netna_base_acc_op(struct gensio_accepter *acc, int op, void *acc_op_data, void *done, int val1, void *data, void *data2, void *ret) { switch(op) { case GENSIO_BASE_ACC_STARTUP: return netna_startup(acc, acc_op_data); case GENSIO_BASE_ACC_SHUTDOWN: return netna_shutdown(acc, acc_op_data, done); case GENSIO_BASE_ACC_SET_CB_ENABLE: return netna_set_accept_callback_enable(acc, acc_op_data, val1, done); case GENSIO_BASE_ACC_FREE: netna_free(acc, acc_op_data); return 0; case GENSIO_BASE_ACC_CONTROL: return netna_control(acc, acc_op_data, val1, *((unsigned int *) done), data, ret); case GENSIO_BASE_ACC_STR_TO_GENSIO: return netna_str_to_gensio(acc, acc_op_data, (const char *) data, (gensio_event) done, data2, ret); case GENSIO_BASE_ACC_DISABLE: netna_disable(acc, acc_op_data); return 0; default: return GE_NOTSUP; } } #ifdef HAVE_TCPD_H static struct gensio_enum_val tcpd_enums[] = { { "on", GENSIO_TCPD_ON }, { "print", GENSIO_TCPD_PRINT }, { "off", GENSIO_TCPD_OFF }, { NULL } }; #endif static int net_gensio_accepter_alloc(const struct gensio_addr *iai, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, int protocol, const char *typestr, struct gensio_accepter **accepter) { struct netna_data *nadata; gensiods max_read_size = GENSIO_DEFAULT_BUF_SIZE; bool nodelay = false; bool reuseaddr = protocol == GENSIO_NET_PROTOCOL_TCP; #if HAVE_UNIX unsigned int umode = 6, gmode = 6, omode = 6, mode; bool mode_set = false; const char *owner = NULL, *group = NULL; #if HAVE_UCRED const char **permusers = NULL; const char **permgrps = NULL; #endif #endif #ifdef HAVE_TCPD_H const char *tcpdname = NULL; enum gensio_tcpd_options tcpd = GENSIO_TCPD_ON; #endif bool istcp = protocol == GENSIO_NET_PROTOCOL_TCP; unsigned int i; int err, ival; struct gensio_accepter *newacc; struct gensio_base_parms *parms = NULL; GENSIO_DECLARE_PPACCEPTER(p, o, cb, typestr, user_data); err = gensio_base_parms_alloc(o, true, typestr, &parms); if (err) goto out_err2; if (protocol == GENSIO_NET_PROTOCOL_TCP) { err = gensio_get_default(o, typestr, "reuseaddr", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (err) goto out_err2; } else { err = gensio_get_default(o, typestr, "delsock", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (err) goto out_err2; } reuseaddr = ival; #ifdef HAVE_TCPD_H err = gensio_get_default(o, typestr, "tcpd", false, GENSIO_DEFAULT_INT, NULL, &ival); if (err) goto out_err2; tcpd = ival; #endif for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(&p, args[i], "readbuf", &max_read_size) > 0) continue; if (istcp && gensio_pparm_bool(&p, args[i], "nodelay", &nodelay) > 0) continue; if (!istcp && gensio_pparm_bool(&p, args[i], "delsock", &reuseaddr) > 0) continue; if (istcp && gensio_pparm_bool(&p, args[i], "reuseaddr", &reuseaddr) > 0) continue; #ifdef HAVE_TCPD_H if (istcp && gensio_pparm_value(&p, args[i], "tcpdname", &tcpdname)) continue; if (istcp && gensio_pparm_enum(&p, args[i], "tcpd", tcpd_enums, &ival) > 0) { tcpd = ival; continue; } #endif #if HAVE_UNIX if (!istcp && gensio_pparm_mode(&p, args[i], "umode", &umode) > 0) { mode_set = true; continue; } if (!istcp && gensio_pparm_mode(&p, args[i], "gmode", &gmode) > 0) { mode_set = true; continue; } if (!istcp && gensio_pparm_mode(&p, args[i], "omode", &omode) > 0) { mode_set = true; continue; } if (!istcp && gensio_pparm_perm(&p, args[i], "perm", &mode) > 0) { mode_set = true; umode = mode >> 6 & 7; gmode = mode >> 3 & 7; omode = mode & 7; continue; } if (!istcp && gensio_pparm_value(&p, args[i], "owner", &owner)) continue; if (!istcp && gensio_pparm_value(&p, args[i], "group", &group)) continue; #if HAVE_UCRED if (!istcp && gensio_pparm_argv(&p, args[i], "permusers", ";", NULL, &permusers)) continue; if (!istcp && gensio_pparm_argv(&p, args[i], "permgrps", ";", NULL, &permgrps)) continue; #endif #endif if (gensio_base_parm(parms, &p, args[i]) > 0) continue; gensio_pparm_unknown_parm(&p, args[i]); err = GE_INVAL; goto out_err2; } nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) { err = GE_NOMEM; goto out_err2; } nadata->o = o; err = GE_NOMEM; if (reuseaddr) nadata->opensock_flags |= GENSIO_OPENSOCK_REUSEADDR; #if HAVE_UNIX #if HAVE_UCRED nadata->permusers = permusers; permusers = NULL; nadata->permgrps = permgrps; permgrps = NULL; #endif nadata->mode_set = mode_set; nadata->mode = umode << 6 | gmode << 3 | omode; if (owner) { nadata->owner = gensio_strdup(o, owner); if (!nadata->owner) goto out_err; } if (group) { nadata->group = gensio_strdup(o, group); if (!nadata->group) goto out_err; } #endif #ifdef HAVE_TCPD_H nadata->tcpd = tcpd; if (tcpdname) nadata->tcpd_progname = strdup(tcpdname); #endif nadata->ai = gensio_addr_dup(iai); if (!nadata->ai) goto out_err; nadata->lock = o->alloc_lock(o); if (!nadata->lock) goto out_err; nadata->cb_en_done_runner = o->alloc_runner(o, netna_cb_en_done, nadata); if (!nadata->cb_en_done_runner) goto out_err; nadata->protocol = protocol; nadata->typestr = typestr; err = base_gensio_accepter_alloc(NULL, netna_base_acc_op, nadata, o, typestr, cb, user_data, &newacc); if (err) goto out_err; err = gensio_acc_base_parms_set(newacc, &parms); if (err) { gensio_acc_free(newacc); goto out_err2; } *accepter = newacc; nadata->acc = *accepter; gensio_acc_set_is_reliable(nadata->acc, true); if (protocol == GENSIO_NET_PROTOCOL_UNIX_SEQPACKET) gensio_acc_set_is_packet(nadata->acc, true); nadata->max_read_size = max_read_size; nadata->nodelay = nodelay; return 0; out_err: netna_free(NULL, nadata); out_err2: #if HAVE_UCRED if (permusers) gensio_argv_free(o, permusers); if (permgrps) gensio_argv_free(o, permgrps); #endif if (parms) gensio_base_parms_free(&parms); return err; } static int str_to_net_gensio_accepter(const char *str, const char * const args[], int protocol, const char *typestr, struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { int err; struct gensio_addr *ai; err = gensio_os_scan_netaddr(o, str, true, protocol, &ai); if (err) { GENSIO_DECLARE_PPACCEPTER(p, o, cb, typestr, user_data); gensio_pparm_log(&p, "Invalid network address: %s", str); return err; } err = net_gensio_accepter_alloc(ai, args, o, cb, user_data, protocol, typestr, acc); gensio_addr_free(ai); return err; } static int tcp_gensio_accepter_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { const struct gensio_addr *iai = gdata; return net_gensio_accepter_alloc(iai, args, o, cb, user_data, GENSIO_NET_PROTOCOL_TCP, "tcp", accepter); } static int str_to_tcp_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { return str_to_net_gensio_accepter(str, args, GENSIO_NET_PROTOCOL_TCP, "tcp", o, cb, user_data, acc); } static int unix_gensio_accepter_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { const struct gensio_addr *iai = gdata; return net_gensio_accepter_alloc(iai, args, o, cb, user_data, GENSIO_NET_PROTOCOL_UNIX, "unix", accepter); } static int unixseq_gensio_accepter_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { #if HAVE_UNIX && defined(SOCK_SEQPACKET) const struct gensio_addr *iai = gdata; return net_gensio_accepter_alloc(iai, args, o, cb, user_data, GENSIO_NET_PROTOCOL_UNIX_SEQPACKET, "unixseq", accepter); #else return GE_NOTSUP; #endif } static int str_to_unix_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { return str_to_net_gensio_accepter(str, args, GENSIO_NET_PROTOCOL_UNIX, "unix", o, cb, user_data, acc); } static int str_to_unixseq_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { #if HAVE_UNIX && defined(SOCK_SEQPACKET) return str_to_net_gensio_accepter(str, args, GENSIO_NET_PROTOCOL_UNIX_SEQPACKET, "unixseq", o, cb, user_data, acc); #else return GE_NOTSUP; #endif } int gensio_init_net(struct gensio_os_funcs *o) { int rv; rv = register_gensio(o, "tcp", str_to_tcp_gensio, tcp_gensio_alloc); if (rv) return rv; rv = register_gensio_accepter(o, "tcp", str_to_tcp_gensio_accepter, tcp_gensio_accepter_alloc); if (rv) return rv; rv = register_gensio(o, "unix", str_to_unix_gensio, unix_gensio_alloc); if (rv) return rv; rv = register_gensio_accepter(o, "unix", str_to_unix_gensio_accepter, unix_gensio_accepter_alloc); if (rv) return rv; rv = register_gensio(o, "unixseq", str_to_unixseq_gensio, unixseq_gensio_alloc); if (rv) return rv; rv = register_gensio_accepter(o, "unixseq", str_to_unixseq_gensio_accepter, unixseq_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/net_stdsock.c0000664000175000017500000016176414752425772011751 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2019 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #define _GNU_SOURCE /* Get in6_pktinfo. */ #include "config.h" #define _DEFAULT_SOURCE /* Get getgrouplist(), setgroups() */ #include #include #include #include #ifdef _WIN32 #include #include #include typedef int taddrlen; typedef int sockret; #define sock_errno WSAGetLastError() #define SOCK_EINTR WSAEINTR #define SOCK_EWOULDBLOCK WSAEWOULDBLOCK #define SOCK_EAGAIN WSAEWOULDBLOCK #define SOCK_EADDRINUSE WSAEADDRINUSE #define SOCK_EPIPE WSAECONNRESET #define SOCK_EINVAL WSAEINVAL #else #include #include #include #include #include #include #include #include typedef socklen_t taddrlen; typedef ssize_t sockret; #define sock_errno errno #define SOCK_EINTR EINTR #define SOCK_EWOULDBLOCK EWOULDBLOCK #define SOCK_EAGAIN EWOULDBLOCK #define SOCK_EADDRINUSE EADDRINUSE #define SOCK_EPIPE EPIPE #define SOCK_EINVAL EINVAL #endif #if HAVE_UNIX #include #endif #include #include #include #include #include #include "errtrig.h" #include #include /* MacOS doesn't have IPV6_ADD_MEMBERSHIP, but has an equivalent. */ #ifndef IPV6_ADD_MEMBERSHIP #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP #endif /* For older systems that don't have this. */ #ifndef AI_V4MAPPED #define AI_V4MAPPED 0 #endif #define SIZEOF_SOCKADDR_UN_HEADER \ (sizeof(struct sockaddr_un) - \ sizeof(((struct sockaddr_un *) 0)->sun_path)) struct gensio_stdsock_info { int protocol; int family; /* * Has the connect completed? Windows shutdown will not return an * FD_CLOSE after a shutdown if the socket has not finished * opening, so if open is not complete, use this to just close the * socket. */ bool connected; #ifdef HAVE_RECVMSG /* Is the extrainfo flag set? */ bool extrainfo; #endif }; struct gensio_listen_scan_info { unsigned int curr; unsigned int start; unsigned int reqport; }; /* * Setup a receiving socket given the socket() parameters. If do_listen * is true, call listen on the socket. This sets nonblocking, reuse, * does a bind, etc. Works on the current address in addr. * * The new file descriptor is returned in rfd, and the chosen port is * returned in port. If the address has a port set to 0, this * function choose random port from the IANA dynamic range. * * The rsi parameter is used for handling port 0 for multiple sockets. * Pass in a zero-ed structure here. If the code encounters a zero * port, it will set some information int the rsi structure and for * every other zero port in future calls it will choose the same port. * If it chooses a port that is already in use on one of the later * addresses with a zero port, you can clear the reqport member, close * everything, and start over. The function will continue scanning * from the next port. If it returns GE_ADDRINUSE and the curr and * start value are the same, then no port was found that could be * opened on all addresses. Errors besides GE_ADDRINUSE should be * treated as immediate errors, something else went wrong. */ static int gensio_setup_listen_socket(struct gensio_os_funcs *o, int family, int socktype, int protocol, int flags, struct sockaddr *addr, socklen_t addrlen, int (*call_b4_listen)(struct gensio_iod *, void *), void *data, unsigned int opensock_flags, struct gensio_iod **iod, unsigned int *port, struct gensio_listen_scan_info *rsi); bool sockaddr_equal(const struct sockaddr *a1, socklen_t l1, const struct sockaddr *a2, socklen_t l2, bool compare_ports); /* Does sa have an equivalent address in the list before this address? */ static bool sockaddr_in_list_b4(struct addrinfo *sa, struct addrinfo *l) { for (; l; l = l->ai_next) { if (sa == l) break; if (sockaddr_equal(sa->ai_addr, sa->ai_addrlen, l->ai_addr, l->ai_addrlen, true)) return true; } return false; } #define ERRHANDLE() \ do { \ int err = 0; \ if (rv < 0) { \ if (sock_errno == SOCK_EINTR) \ goto retry; \ if (sock_errno == SOCK_EWOULDBLOCK || sock_errno == SOCK_EAGAIN) \ rv = 0; /* Handle like a zero-byte write. */ \ else { \ err = sock_errno; \ assert(err); \ } \ } else if (rv == 0) { \ err = SOCK_EPIPE; \ } \ if (!err && rcount) \ *rcount = rv; \ rv = gensio_os_err_to_err(o, err); \ } while(0) static int close_socket(struct gensio_os_funcs *o, int fd) { int err; /* Don't do errtrig on close, it can fail and not cause any issues. */ assert(fd != -1); #ifdef _WIN32 /* * We must call shutdown before closing the socket. If we do not, it * leaves the socket open on the remote if there is another connection * to the same system. The socket will only close when all connections * to that system close. Windows is broken in so many ways. */ shutdown(fd, SD_BOTH); err = closesocket(fd); #else err = close(fd); #endif #if defined(ENABLE_INTERNAL_TRACE) && !defined(_WIN32) /* * Close should never fail (well, except for windows), but don't crash * in production builds. */ assert(err == 0); #endif if (err == -1) return gensio_os_err_to_err(o, sock_errno); return 0; } #if HAVE_LIBSCTP #include static void sctp_shutdown_fds(struct gensio_os_funcs *o, struct gensio_opensocks *fds, unsigned int nrfds) { unsigned int i; if (!fds) return; for (i = 0; i < nrfds; i++) { o->clear_fd_handlers_norpt(fds[i].iod); o->close(&fds[i].iod); } o->free(o, fds); } static int gensio_os_sctp_open_sockets(struct gensio_os_funcs *o, struct gensio_addr *addr, int (*call_b4_listen)(struct gensio_iod *iod, void *data), void *data, unsigned int opensock_flags, struct gensio_opensocks **rfds, unsigned int *rnr_fds) { struct addrinfo *ai, *rp; unsigned int i; int family = AF_INET6; int rv = 0; struct gensio_listen_scan_info scaninfo; struct gensio_opensocks *fds = NULL, *tfds; unsigned int nr_fds = 0; memset(&scaninfo, 0, sizeof(scaninfo)); ai = gensio_addr_addrinfo_get(addr); retry: for (rp = ai; rp; rp = rp->ai_next) { unsigned int port; if (family != rp->ai_family) continue; /* * getaddrinfo() will return the same address twice in the * list if ::1 and 127.0.0.1 are both set for localhost in * /etc/hosts. So the second open attempt will fail if we * don't ignore this. In general, it's probably better to * ignore duplicates in this function, anyway. */ if (sockaddr_in_list_b4(rp, ai)) continue; rv = gensio_sockaddr_get_port(rp->ai_addr, &port); if (rv) goto out_err; for (i = 0; i < nr_fds; i++) { if (port == fds[i].port && (fds[i].family == family)) { if (sctp_bindx(o->iod_get_fd(fds[i].iod), rp->ai_addr, 1, SCTP_BINDX_ADD_ADDR)) { rv = gensio_os_err_to_err(o, sock_errno); goto out_err; } break; } } if (i < nr_fds) continue; /* Port matched, already did bind. */ /* Increment the fds array and open a new socket. */ tfds = o->zalloc(o, sizeof(*tfds) * (i + 1)); if (!tfds) { rv = GE_NOMEM; goto out_err; } if (fds) memcpy(tfds, fds, sizeof(*tfds) * i); rv = gensio_setup_listen_socket(o, rp->ai_family, SOCK_STREAM, IPPROTO_SCTP, rp->ai_flags, rp->ai_addr, rp->ai_addrlen, call_b4_listen, data, opensock_flags, &tfds[i].iod, &tfds[i].port, &scaninfo); if (rv) { o->free(o, tfds); goto out_err; } tfds[i].family = rp->ai_family; tfds[i].flags = rp->ai_flags; if (fds) o->free(o, fds); fds = tfds; nr_fds++; } if (family == AF_INET6) { family = AF_INET; goto retry; } if (nr_fds == 0) { rv = GE_INVAL; goto out; } *rfds = fds; *rnr_fds = nr_fds; out: return rv; out_err: sctp_shutdown_fds(o, fds, nr_fds); #if !HAVE_WORKING_PORT0 fds = NULL; nr_fds = 0; if (rv == GE_ADDRINUSE && scaninfo.start != 0 && scaninfo.curr != scaninfo.start) { /* We need to keep scanning. */ scaninfo.reqport = 0; family = AF_INET6; goto retry; } #endif goto out; } static int gensio_stdsock_sctp_recvmsg(struct gensio_iod *iod, void *msg, gensiods len, gensiods *rcount, struct sctp_sndrcvinfo *sinfo, int *flags) { struct gensio_os_funcs *o = iod->f; int rv; if (do_errtrig()) return GE_NOMEM; retry: rv = sctp_recvmsg(o->iod_get_fd(iod), msg, len, NULL, NULL, sinfo, flags); ERRHANDLE(); return rv; } static int l_sctp_send(struct gensio_os_funcs *o, int fd, const void *msg, size_t len, gensiods *rcount, const struct sctp_sndrcvinfo *sinfo, uint32_t flags) { int rv; retry: rv = sctp_send(fd, msg, len, sinfo, flags); ERRHANDLE(); return rv; } #if HAVE_SCTP_SENDV #define gensio_stdsock_sctp_send l_gensio_stdsock_sctp_send #endif static int gensio_stdsock_sctp_send(struct gensio_iod *iod, const struct gensio_sg *sg, gensiods sglen, gensiods *rcount, const struct sctp_sndrcvinfo *sinfo, uint32_t flags) { struct gensio_os_funcs *o = iod->f; int err = 0; gensiods i, count = 0, total_write = 0; if (do_errtrig()) return GE_NOMEM; /* Without sctp_sendv, this is really hard to do. */ for (i = 0; i < sglen; i++) { err = l_sctp_send(o, o->iod_get_fd(iod), sg[i].buf, sg[i].buflen, &count, sinfo, flags); if (err || count == 0) break; total_write += count; } if (rcount) *rcount = total_write; return err; } #if HAVE_SCTP_SENDV #undef gensio_stdsock_sctp_send static bool sctp_sendv_broken; static int gensio_stdsock_sctp_send(struct gensio_iod *iod, const struct gensio_sg *sg, gensiods sglen, gensiods *rcount, const struct sctp_sndrcvinfo *sinfo, uint32_t flags) { struct gensio_os_funcs *o = iod->f; int rv = 0; struct sctp_sndinfo *sndinfo = NULL, sdata; if (do_errtrig()) return GE_NOMEM; if (sctp_sendv_broken) { broken: return l_gensio_stdsock_sctp_send(iod, sg, sglen, rcount, sinfo, flags); } if (sinfo) { sdata.snd_sid = sinfo->sinfo_stream; sdata.snd_flags = sinfo->sinfo_flags; sdata.snd_ppid = sinfo->sinfo_ppid; sdata.snd_context = sinfo->sinfo_context; sdata.snd_assoc_id = sinfo->sinfo_assoc_id; sndinfo = &sdata; } retry: rv = sctp_sendv(o->iod_get_fd(iod), (struct iovec *) sg, sglen, NULL, 0, sndinfo, sizeof(*sndinfo), SCTP_SENDV_SNDINFO, flags); if (rv == -1 && sock_errno == SOCK_EINVAL) { /* No sendv support, fall back. */ sctp_sendv_broken = true; goto broken; } ERRHANDLE(); return rv; } #endif static int gensio_addr_to_sockarray(struct gensio_os_funcs *o, struct gensio_addr *addrs, struct sockaddr **rsaddrs, unsigned int *rslen, bool *ripv6_only) { struct addrinfo *ai; char *saddrs, *s; unsigned int slen = 0, i, memlen = 0; int ipv6_only = 1; for (ai = gensio_addr_addrinfo_get(addrs); ai; ai = ai->ai_next) { unsigned int len; if (ai->ai_addr->sa_family == AF_INET6) { len = sizeof(struct sockaddr_in6); } else if (ai->ai_addr->sa_family == AF_INET) { len = sizeof(struct sockaddr_in); ipv6_only = 0; } else { return GE_INVAL; } memlen += len; slen++; } if (memlen == 0) return GE_NOTFOUND; saddrs = o->zalloc(o, memlen); if (!saddrs) return GE_NOMEM; s = saddrs; for (ai = gensio_addr_addrinfo_get(addrs), i = 0; i < slen; ai = ai->ai_next) { unsigned int len; if (ai->ai_addr->sa_family == AF_INET6) len = sizeof(struct sockaddr_in6); else if (ai->ai_addr->sa_family == AF_INET) len = sizeof(struct sockaddr_in); else assert(0); memcpy(s, ai->ai_addr, len); s += len; i++; } *rsaddrs = (struct sockaddr *) saddrs; *rslen = slen; *ripv6_only = ipv6_only; return 0; } static int gensio_stdsock_sctp_connectx(struct gensio_iod *iod, struct gensio_addr *addrs) { struct gensio_os_funcs *o = iod->f; struct sockaddr *saddrs; unsigned int naddrs; int err; bool ipv6_only; if (do_errtrig()) return GE_NOMEM; err = gensio_addr_to_sockarray(o, addrs, &saddrs, &naddrs, &ipv6_only); if (err) return err; if (ipv6_only) { int val = 1; err = setsockopt(o->iod_get_fd(iod), IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)); if (err) goto out_err; val = !val; err = setsockopt(o->iod_get_fd(iod), SOL_SCTP, SCTP_I_WANT_MAPPED_V4_ADDR, &val, sizeof(val)); if (err) goto out_err; } err = sctp_connectx(o->iod_get_fd(iod), saddrs, naddrs, NULL); if (err == -1) err = gensio_os_err_to_err(o, sock_errno); else err = 0; out_err: o->free(o, saddrs); return err; } static int sctp_getraddr(struct gensio_os_funcs *o, int fd, struct sockaddr **addr, gensiods *addrlen) { int rv; rv = sctp_getpaddrs(fd, 0, addr); if (rv < 0) { return gensio_os_err_to_err(o, sock_errno); } if (rv == 0) { return GE_NOTFOUND; } *addrlen = rv; return 0; } static int gensio_os_sctp_getraddr(struct gensio_iod *iod, void *addr, gensiods *addrlen) { struct gensio_os_funcs *o = iod->f; struct sockaddr *saddr; gensiods len = 0, clen = *addrlen; int rv = sctp_getraddr(o, o->iod_get_fd(iod), &saddr, &len); if (rv) return rv; if (len > clen) len = clen; memcpy(addr, saddr, clen); *addrlen = len; sctp_freepaddrs(saddr); return 0; } static int sctp_addr_to_addr(struct gensio_os_funcs *o, struct sockaddr *saddr, gensiods len, struct gensio_addr **raddr) { struct sockaddr *s; gensiods i, size; struct addrinfo *ai = NULL, *aip = NULL; struct gensio_addr *addr; char *d; int rv; addr = gensio_addr_addrinfo_make(o, 0, false); if (!addr) return GE_NOMEM; rv = GE_NOMEM; d = (char *) saddr; for (i = 0; i < len; i++) { s = (struct sockaddr *) d; ai = o->zalloc(o, sizeof(*ai)); if (!ai) goto out; if (!aip) { gensio_addr_addrinfo_set(addr, ai); } else { aip->ai_next = ai; } aip = ai; switch (s->sa_family) { case AF_INET6: size = sizeof(struct sockaddr_in6); break; case AF_INET: size = sizeof(struct sockaddr_in); break; default: rv = GE_INVAL; goto out; } ai->ai_addr = o->zalloc(o, size); if (!ai->ai_addr) goto out; memcpy(ai->ai_addr, d, size); ai->ai_family = s->sa_family; d += size; } rv = 0; *raddr = addr; out: if (rv && addr) gensio_addr_free(addr); return rv; } static int gensio_os_sctp_getpaddrs(struct gensio_iod *iod, struct gensio_addr **raddr) { struct gensio_os_funcs *o = iod->f; struct sockaddr *saddr; gensiods len = 0; int rv = sctp_getraddr(o, o->iod_get_fd(iod), &saddr, &len); if (rv) return rv; rv = sctp_addr_to_addr(o, saddr, len, raddr); sctp_freepaddrs(saddr); return rv; } static int gensio_os_sctp_getladdrs(struct gensio_iod *iod, struct gensio_addr **raddr) { struct gensio_os_funcs *o = iod->f; int rv; struct sockaddr *saddr; rv = sctp_getladdrs(o->iod_get_fd(iod), 0, &saddr); if (rv < 0) { return gensio_os_err_to_err(o, sock_errno); } if (rv == 0) { return GE_NOTFOUND; } rv = sctp_addr_to_addr(o, saddr, rv, raddr); sctp_freeladdrs(saddr); return rv; } static int gensio_stdsock_sctp_socket_setup(struct gensio_iod *iod, bool events, struct sctp_initmsg *initmsg, struct sctp_sack_info *sackinfo) { int err = 0, fd = iod->f->iod_get_fd(iod); if (initmsg) { err = setsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, initmsg, sizeof(*initmsg)); if (err) return err; } if (sackinfo) { err = setsockopt(fd, IPPROTO_SCTP, SCTP_DELAYED_SACK, sackinfo, sizeof(*sackinfo)); if (err) return err; } if (events) { struct sctp_event_subscribe event_sub; memset(&event_sub, 0, sizeof(event_sub)); event_sub.sctp_data_io_event = 1; err = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event_sub, sizeof(event_sub)); } return err; } static int gensio_stdsock_sctp_get_socket_status(struct gensio_iod *iod, struct sctp_status *status) { int err, fd = iod->f->iod_get_fd(iod); taddrlen stat_size = sizeof(*status); err = getsockopt(fd, IPPROTO_SCTP, SCTP_STATUS, status, &stat_size); if (err) /* * If the remote end closes, this fails with EINVAL. Just * assume the remote end closed on error. */ return GE_REMCLOSE; return 0; } #endif static int check_ipv6_only(int family, int protocol, int flags, int fd) { int val; #ifdef AF_INET6 if (family != AF_INET6) return 0; #endif if (flags & AI_V4MAPPED) val = 0; else val = 1; if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *) &val, sizeof(val)) == -1) return -1; #if HAVE_LIBSCTP if (protocol == IPPROTO_SCTP) { val = !val; if (setsockopt(fd, SOL_SCTP, SCTP_I_WANT_MAPPED_V4_ADDR, (void *) &val, sizeof(val)) == -1) return -1; } #endif return 0; } static int gensio_stdsock_recv(struct gensio_iod *iod, void *buf, gensiods buflen, gensiods *rcount, int gflags) { struct gensio_os_funcs *o = iod->f; sockret rv; int flags = (gflags & GENSIO_MSG_OOB) ? MSG_OOB : 0; if (do_errtrig()) return GE_NOMEM; retry: rv = recv(o->iod_get_fd(iod), buf, buflen, flags); ERRHANDLE(); return rv; } #ifndef HAVE_SENDMSG static unsigned char * gensio_sg_to_buf(const struct gensio_sg *sg, gensiods sglen, gensiods *rlen) { gensiods len = 0, pos = 0, i; unsigned char *buf; for (i = 0; i < sglen; i++) len += sg[i].buflen; buf = malloc(len); if (!buf) return NULL; for (i = 0; i < sglen; i++) { memcpy(buf + pos, sg[i].buf, sg[i].buflen); pos += sg[i].buflen; } *rlen = len; return buf; } #endif static int gensio_stdsock_send(struct gensio_iod *iod, const struct gensio_sg *sg, gensiods sglen, gensiods *rcount, int gflags) { struct gensio_os_funcs *o = iod->f; sockret rv; int flags = (gflags & GENSIO_MSG_OOB) ? MSG_OOB : 0; if (do_errtrig()) return GE_NOMEM; { #ifdef HAVE_SENDMSG struct msghdr hdr; memset(&hdr, 0, sizeof(hdr)); hdr.msg_iov = (struct iovec *) sg; hdr.msg_iovlen = sglen; retry: rv = sendmsg(o->iod_get_fd(iod), &hdr, flags); ERRHANDLE(); #else gensiods len; void *buf; buf = gensio_sg_to_buf(sg, sglen, &len); if (!buf) return GE_NOMEM; retry: rv = send(o->iod_get_fd(iod), buf, len, flags); ERRHANDLE(); free(buf); #endif } return rv; } static int gensio_stdsock_sendto(struct gensio_iod *iod, const struct gensio_sg *sg, gensiods sglen, gensiods *rcount, int gflags, const struct gensio_addr *raddr) { struct gensio_os_funcs *o = iod->f; sockret rv; int flags = (gflags & GENSIO_MSG_OOB) ? MSG_OOB : 0; if (do_errtrig()) return GE_NOMEM; { #ifdef HAVE_SENDMSG struct msghdr hdr; struct addrinfo *ai; ai = gensio_addr_addrinfo_get_curr(raddr); memset(&hdr, 0, sizeof(hdr)); hdr.msg_name = (void *) ai->ai_addr; hdr.msg_namelen = ai->ai_addrlen; hdr.msg_iov = (struct iovec *) sg; hdr.msg_iovlen = sglen; retry: rv = sendmsg(o->iod_get_fd(iod), &hdr, flags); ERRHANDLE(); #else gensiods len; void *buf; struct addrinfo *ai; ai = gensio_addr_addrinfo_get_curr(raddr); buf = gensio_sg_to_buf(sg, sglen, &len); if (!buf) return GE_NOMEM; retry: rv = sendto(o->iod_get_fd(iod), buf, len, flags, (void *) ai->ai_addr, ai->ai_addrlen); ERRHANDLE(); free(buf); #endif } return rv; } static struct gensio_addr * gensio_addr_addrinfo_alloc_recvfrom(struct gensio_os_funcs *o) { /* * Addresses used for recvfrom cannot be duplicated with refcounts * because the storage is reused. So allocate them without a * refcount to mark them to always do a full replication. */ return gensio_addr_addrinfo_make(o, sizeof(struct sockaddr_storage), true); } static int gensio_stdsock_recvfrom(struct gensio_iod *iod, void *buf, gensiods buflen, gensiods *rcount, int flags, struct gensio_addr *addr) { struct gensio_os_funcs *o = iod->f; sockret rv; int err = 0; taddrlen len; struct addrinfo *ai; #ifdef HAVE_RECVMSG struct gensio_stdsock_info *gsi; struct msghdr hdr; struct iovec iov; unsigned char ctrlinfo[128]; #endif if (do_errtrig()) return GE_NOMEM; gensio_addr_rewind(addr); ai = gensio_addr_addrinfo_get_curr(addr); retry: len = sizeof(struct sockaddr_storage); #ifdef HAVE_RECVMSG err = o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, true, (intptr_t) &gsi); if (err) return err; memset(&hdr, 0, sizeof(hdr)); hdr.msg_name = ai->ai_addr; hdr.msg_namelen = len; iov.iov_base = buf; iov.iov_len = buflen; hdr.msg_iov = &iov; hdr.msg_iovlen = 1; hdr.msg_control = ctrlinfo; hdr.msg_controllen = sizeof(ctrlinfo); rv = recvmsg(o->iod_get_fd(iod), &hdr, flags); len = hdr.msg_namelen; #else rv = recvfrom(o->iod_get_fd(iod), buf, buflen, flags, ai->ai_addr, &len); #endif if (rv >= 0) { if (len == 0) { /* * This happens when receiving an AF_UNIX datagram socket * where the other end isn't bound. Just create a socket * with the family set and no path. */ ai->ai_addrlen = sizeof(ai->ai_addr->sa_family); ai->ai_addr->sa_family = AF_UNIX; } else { ai->ai_addrlen = len; } ai->ai_family = ai->ai_addr->sa_family; } else { if (sock_errno == SOCK_EINTR) goto retry; if (sock_errno == SOCK_EWOULDBLOCK || sock_errno == SOCK_EAGAIN) rv = 0; /* Handle like a zero-byte write. */ else err = sock_errno; } #ifdef HAVE_RECVMSG if (!err && gsi->extrainfo) { struct cmsghdr *cmsg; #ifdef IP_PKTINFO for (cmsg = CMSG_FIRSTHDR(&hdr); cmsg; cmsg = CMSG_NXTHDR(&hdr, cmsg)) { if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { struct in_pktinfo *pi; pi = (struct in_pktinfo *) CMSG_DATA(cmsg); if (gensio_addr_next(addr)) { struct sockaddr *inaddr; ai = gensio_addr_addrinfo_get_curr(addr); ai->ai_family = GENSIO_AF_IFINDEX; inaddr = (struct sockaddr *) ai->ai_addr; inaddr->sa_family = GENSIO_AF_IFINDEX; *((unsigned int *) inaddr->sa_data) = pi->ipi_ifindex; } if (gensio_addr_next(addr)) { struct sockaddr_in *inaddr; ai = gensio_addr_addrinfo_get_curr(addr); ai->ai_family = AF_INET; inaddr = (struct sockaddr_in *) ai->ai_addr; inaddr->sin_family = AF_INET; inaddr->sin_port = 0; inaddr->sin_addr = pi->ipi_addr; } } } #elif defined(IP_RECVIF) && defined(IP_RECVDSTADDR) for (cmsg = CMSG_FIRSTHDR(&hdr); cmsg; cmsg = CMSG_NXTHDR(&hdr, cmsg)) { if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVIF) { uint16_t *iptr; struct sockaddr *inaddr; /* * There's no docs on this that I could find, but the * value seems to be in the second 16-bit value in the * data. Not sure if it will work on big endian, or * if this is even right. */ iptr = (uint16_t *) CMSG_DATA(cmsg); if (gensio_addr_next(addr)) { ai = gensio_addr_addrinfo_get_curr(addr); ai->ai_family = GENSIO_AF_IFINDEX; inaddr = (struct sockaddr *) ai->ai_addr; inaddr->sa_family = GENSIO_AF_IFINDEX; *((unsigned int *) inaddr->sa_data) = iptr[1]; } } } for (cmsg = CMSG_FIRSTHDR(&hdr); cmsg; cmsg = CMSG_NXTHDR(&hdr, cmsg)) { if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR) { struct sockaddr_in *inaddr; if (gensio_addr_next(addr)) { struct in_addr *iptr; iptr = (struct in_addr *) CMSG_DATA(cmsg); ai = gensio_addr_addrinfo_get_curr(addr); ai->ai_family = AF_INET; inaddr = (struct sockaddr_in *) ai->ai_addr; inaddr->sin_family = AF_INET; inaddr->sin_port = 0; inaddr->sin_addr = *iptr; } } } #endif #ifdef IPV6_RECVPKTINFO for (cmsg = CMSG_FIRSTHDR(&hdr); cmsg; cmsg = CMSG_NXTHDR(&hdr, cmsg)) { if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) { struct in6_pktinfo *pi; pi = (struct in6_pktinfo *) CMSG_DATA(cmsg); if (gensio_addr_next(addr)) { struct sockaddr *inaddr; ai = gensio_addr_addrinfo_get_curr(addr); ai->ai_family = GENSIO_AF_IFINDEX; inaddr = (struct sockaddr *) ai->ai_addr; inaddr->sa_family = GENSIO_AF_IFINDEX; *((unsigned int *) inaddr->sa_data) = pi->ipi6_ifindex; } if (gensio_addr_next(addr)) { struct sockaddr_in6 *inaddr; ai = gensio_addr_addrinfo_get_curr(addr); ai->ai_family = AF_INET6; inaddr = (struct sockaddr_in6 *) ai->ai_addr; memset(inaddr, 0, sizeof(*inaddr)); inaddr->sin6_family = AF_INET6; inaddr->sin6_addr = pi->ipi6_addr; } } } #endif } #endif gensio_addr_rewind(addr); if (!err && rcount) *rcount = rv; return gensio_os_err_to_err(o, err); } static int gensio_stdsock_accept(struct gensio_iod *iod, struct gensio_addr **raddr, struct gensio_iod **newiod) { struct gensio_os_funcs *o = iod->f; struct gensio_addr *addr = NULL; int rv, err; struct sockaddr *sa; struct sockaddr_storage sadata; taddrlen len; struct gensio_iod *riod = NULL; struct addrinfo *ai = NULL; struct gensio_stdsock_info *gsi = NULL, *ogsi = NULL; if (do_errtrig()) return GE_NOMEM; if (raddr) { addr = gensio_addr_addrinfo_make(o, sizeof(struct sockaddr_storage), false); if (!addr) return GE_NOMEM; ai = gensio_addr_addrinfo_get_curr(addr); sa = ai->ai_addr; len = ai->ai_addrlen; } else { sa = (struct sockaddr *) &sadata; len = sizeof(sadata); } rv = accept(o->iod_get_fd(iod), sa, &len); if (rv >= 0) { gsi = o->zalloc(o, sizeof(*gsi)); if (!gsi) { close_socket(o, rv); err = GE_NOMEM; goto out; } err = o->add_iod(o, GENSIO_IOD_SOCKET, rv, &riod); if (err) { close_socket(o, rv); goto out; } err = o->set_non_blocking(riod); if (err) goto out; o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, true, (intptr_t) &ogsi); *gsi = *ogsi; gsi->connected = true; o->iod_control(riod, GENSIO_IOD_CONTROL_SOCKINFO, false, (intptr_t) gsi); if (ai) { ai->ai_family = ai->ai_addr->sa_family; ai->ai_addrlen = len; *raddr = addr; } *newiod = riod; } else { rv = sock_errno; if (rv == SOCK_EAGAIN && rv == SOCK_EWOULDBLOCK) err = GE_NODATA; else err = gensio_os_err_to_err(o, rv); } out: if (err) { if (gsi) o->free(o, gsi); if (riod) o->close(&riod); if (addr) gensio_addr_free(addr); } return err; } static int gensio_stdsock_check_socket_open(struct gensio_iod *iod) { struct gensio_os_funcs *o = iod->f; struct gensio_stdsock_info *gsi; int err, optval; socklen_t len = sizeof(optval); if (do_errtrig()) return GE_NOMEM; err = o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, true, (intptr_t) &gsi); if (err) return err; err = getsockopt(o->iod_get_fd(iod), SOL_SOCKET, SO_ERROR, (void *) &optval, &len); if (err) err = gensio_os_err_to_err(o, sock_errno); else err = gensio_os_err_to_err(o, optval); if (!err) gsi->connected = true; return err; } static int gensio_stdsock_socket_open(struct gensio_os_funcs *o, const struct gensio_addr *addr, int protocol, struct gensio_iod **riod) { int sockproto, socktype, family; int newfd, err; struct addrinfo *ai; struct gensio_iod *iod; struct gensio_stdsock_info *gsi; if (do_errtrig()) return GE_NOMEM; ai = gensio_addr_addrinfo_get_curr(addr); family = ai->ai_family; switch (protocol) { case GENSIO_NET_PROTOCOL_TCP: case GENSIO_NET_PROTOCOL_UNIX: sockproto = 0; socktype = SOCK_STREAM; break; case GENSIO_NET_PROTOCOL_UNIX_DGRAM: sockproto = 0; socktype = SOCK_DGRAM; break; #ifdef SOCK_SEQPACKET case GENSIO_NET_PROTOCOL_UNIX_SEQPACKET: sockproto = 0; socktype = SOCK_SEQPACKET; break; #endif case GENSIO_NET_PROTOCOL_UDP: sockproto = 0; socktype = SOCK_DGRAM; break; #if HAVE_LIBSCTP case GENSIO_NET_PROTOCOL_SCTP: sockproto = IPPROTO_SCTP; socktype = SOCK_STREAM; #ifdef AF_INET6 /* * For SCTP, always use AF_INET6 if available. sctp_connectx() * can use ipv4 addresses, too, on an AF_INET6 socket. */ family = AF_INET6; #endif break; #endif default: return GE_INVAL; } newfd = socket(family, socktype, sockproto); if (newfd == -1) return gensio_os_err_to_err(o, sock_errno); err = o->add_iod(o, GENSIO_IOD_SOCKET, newfd, &iod); if (err) { close_socket(o, newfd); return err; } err = o->set_non_blocking(iod); if (err) { o->close(&iod); return err; } gsi = o->zalloc(o, sizeof(*gsi)); if (!gsi) { o->close(&iod); return GE_NOMEM; } gsi->protocol = protocol; gsi->family = family; o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, false, (intptr_t) gsi); *riod = iod; return 0; } static int gensio_stdsock_socket_set_setup(struct gensio_iod *iod, unsigned int opensock_flags, struct gensio_addr *bindaddr) { struct gensio_os_funcs *o = iod->f; struct gensio_stdsock_info *gsi = NULL; int err, val, fd; fd = o->iod_get_fd(iod); if (opensock_flags & GENSIO_SET_OPENSOCK_KEEPALIVE) { val = !!(opensock_flags & GENSIO_OPENSOCK_KEEPALIVE); if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&val, sizeof(val)) == -1) return gensio_os_err_to_err(o, sock_errno); } if (opensock_flags & GENSIO_SET_OPENSOCK_NODELAY) { err = o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, true, (intptr_t) &gsi); if (err) return err; val = !!(opensock_flags & GENSIO_OPENSOCK_NODELAY); if (gsi->protocol == GENSIO_NET_PROTOCOL_TCP) err = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void *) &val, sizeof(val)); #if HAVE_LIBSCTP else if (gsi->protocol == GENSIO_NET_PROTOCOL_SCTP) err = setsockopt(fd, IPPROTO_SCTP, SCTP_NODELAY, (void *) &val, sizeof(val)); #endif else err = 0; if (err) return gensio_os_err_to_err(o, sock_errno); } if (opensock_flags & GENSIO_SET_OPENSOCK_REUSEADDR) { val = !!(opensock_flags & GENSIO_OPENSOCK_REUSEADDR); if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&val, sizeof(val)) == -1) return gensio_os_err_to_err(o, sock_errno); } if (bindaddr) { struct addrinfo *ai; if (!gsi) { err = o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, true, (intptr_t) &gsi); if (err) return err; } switch (gsi->protocol) { #if HAVE_LIBSCTP case GENSIO_NET_PROTOCOL_SCTP: ai = gensio_addr_addrinfo_get(bindaddr); while (ai) { if (sctp_bindx(fd, ai->ai_addr, 1, SCTP_BINDX_ADD_ADDR) == -1) return gensio_os_err_to_err(o, sock_errno); ai = ai->ai_next; } break; #endif case GENSIO_NET_PROTOCOL_TCP: case GENSIO_NET_PROTOCOL_UDP: case GENSIO_NET_PROTOCOL_UNIX: case GENSIO_NET_PROTOCOL_UNIX_DGRAM: #ifdef SOCK_SEQPACKET case GENSIO_NET_PROTOCOL_UNIX_SEQPACKET: #endif ai = gensio_addr_addrinfo_get_curr(bindaddr); if (bind(fd, ai->ai_addr, ai->ai_addrlen) == -1) return gensio_os_err_to_err(o, sock_errno); break; default: return GE_INVAL; } } return 0; } static int gensio_stdsock_socket_get_setup(struct gensio_iod *iod, unsigned int *iopensock_flags) { struct gensio_os_funcs *o = iod->f; int err; int val; taddrlen len; unsigned int opensock_flags = 0; struct gensio_stdsock_info *gsi = NULL; if (*iopensock_flags & GENSIO_SET_OPENSOCK_KEEPALIVE) { len = sizeof(val); if (getsockopt(o->iod_get_fd(iod), SOL_SOCKET, SO_KEEPALIVE, (void *)&val, &len) == -1) return gensio_os_err_to_err(o, sock_errno); opensock_flags |= GENSIO_SET_OPENSOCK_KEEPALIVE; if (val) opensock_flags |= GENSIO_OPENSOCK_KEEPALIVE; } if (*iopensock_flags & GENSIO_SET_OPENSOCK_NODELAY) { if (!gsi) { err = o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, true, (intptr_t) &gsi); if (err) return err; } val = 0; len = sizeof(val); if (gsi->protocol == GENSIO_NET_PROTOCOL_TCP) err = getsockopt(o->iod_get_fd(iod), IPPROTO_TCP, TCP_NODELAY, (void *) &val, &len); #if HAVE_LIBSCTP else if (gsi->protocol == GENSIO_NET_PROTOCOL_SCTP) err = getsockopt(o->iod_get_fd(iod), IPPROTO_SCTP, SCTP_NODELAY, (void *) &val, &len); #endif else err = 0; if (err) return gensio_os_err_to_err(o, sock_errno); opensock_flags |= GENSIO_SET_OPENSOCK_NODELAY; if (val) opensock_flags |= GENSIO_OPENSOCK_NODELAY; } if (*iopensock_flags & GENSIO_SET_OPENSOCK_REUSEADDR) { len = sizeof(val); if (getsockopt(o->iod_get_fd(iod), SOL_SOCKET, SO_REUSEADDR, (void *)&val, &len) == -1) return gensio_os_err_to_err(o, sock_errno); opensock_flags |= GENSIO_SET_OPENSOCK_REUSEADDR; if (val) opensock_flags |= GENSIO_OPENSOCK_REUSEADDR; } *iopensock_flags = opensock_flags; return 0; } static int gensio_stdsock_connect(struct gensio_iod *iod, const struct gensio_addr *addr) { struct gensio_os_funcs *o = iod->f; struct addrinfo *ai; int err; if (do_errtrig()) return GE_NOMEM; ai = gensio_addr_addrinfo_get_curr(addr); err = check_ipv6_only(ai->ai_family, ai->ai_protocol, ai->ai_flags, o->iod_get_fd(iod)); if (err == 0) err = connect(o->iod_get_fd(iod), ai->ai_addr, ai->ai_addrlen); if (err == -1) return gensio_os_err_to_err(o, sock_errno); return 0; } static int gensio_stdsock_close_socket(struct gensio_iod *iod, bool retry, bool force) { struct gensio_os_funcs *o = iod->f; struct gensio_stdsock_info *gsi; int err; #ifdef _WIN32 bool closed; #endif err = o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, true, (intptr_t) &gsi); if (err) return err; #ifdef _WIN32 if (force || (gsi && !gsi->connected)) { err = close_socket(o, o->iod_get_fd(iod)); if (!gsi->connected) err = 0; /* Windows can return non-zero here, just force success. */ goto out; } if (!retry) { err = shutdown(o->iod_get_fd(iod), SD_SEND); if (err == 0) err = GE_INPROGRESS; else if (sock_errno == WSAENOTCONN || sock_errno == WSAECONNRESET || sock_errno == WSAECONNABORTED) /* Other end has already closed. */ err = close_socket(o, o->iod_get_fd(iod)); else err = gensio_os_err_to_err(o, sock_errno); goto out; } err = o->iod_control(iod, GENSIO_IOD_CONTROL_IS_CLOSED, true, (intptr_t) &closed); if (err) close_socket(o, o->iod_get_fd(iod)); else if (closed) err = close_socket(o, o->iod_get_fd(iod)); else err = GE_INPROGRESS; out: #else err = close_socket(o, o->iod_get_fd(iod)); #endif if (gsi && err != GE_INPROGRESS) o->free(o, gsi); return err; } static int gensio_stdsock_mcast_add(struct gensio_iod *iod, struct gensio_addr *mcast_addrs, int iface, bool curr_only) { struct gensio_os_funcs *o = iod->f; struct addrinfo *ai; int rv; if (do_errtrig()) return GE_NOMEM; if (curr_only) ai = gensio_addr_addrinfo_get_curr(mcast_addrs); else ai = gensio_addr_addrinfo_get(mcast_addrs); while (ai) { switch (ai->ai_addr->sa_family) { case AF_INET: { struct sockaddr_in *a = (struct sockaddr_in *) ai->ai_addr; #if defined(_WIN32) || defined(__MSYS__) struct ip_mreq m; #else struct ip_mreqn m; #endif memset(&m, 0, sizeof(m)); m.imr_multiaddr = a->sin_addr; #if !defined(_WIN32) && !defined(__MSYS__) m.imr_address.s_addr = INADDR_ANY; m.imr_ifindex = iface; #endif rv = setsockopt(o->iod_get_fd(iod), IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *) &m, sizeof(m)); if (rv == -1) return gensio_os_err_to_err(o, sock_errno); } break; #ifdef AF_INET6 case AF_INET6: { struct sockaddr_in6 *a = (struct sockaddr_in6 *) ai->ai_addr; struct ipv6_mreq m; m.ipv6mr_multiaddr = a->sin6_addr; m.ipv6mr_interface = iface; rv = setsockopt(o->iod_get_fd(iod), IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (void *) &m, sizeof(m)); if (rv == -1) return gensio_os_err_to_err(o, sock_errno); } break; #endif default: return GE_INVAL; } if (curr_only) break; ai = ai->ai_next; } return 0; } static int gensio_stdsock_mcast_del(struct gensio_iod *iod, struct gensio_addr *mcast_addrs, int iface, bool curr_only) { struct gensio_os_funcs *o = iod->f; struct addrinfo *ai; int rv; if (do_errtrig()) return GE_NOMEM; if (curr_only) ai = gensio_addr_addrinfo_get_curr(mcast_addrs); else ai = gensio_addr_addrinfo_get(mcast_addrs); while (ai) { switch (ai->ai_addr->sa_family) { case AF_INET: { struct sockaddr_in *a = (struct sockaddr_in *) ai->ai_addr; #if defined(_WIN32) || defined(__MSYS__) struct ip_mreq m; #else struct ip_mreqn m; #endif memset(&m, 0, sizeof(m)); m.imr_multiaddr = a->sin_addr; #if !defined(_WIN32) && !defined(__MSYS__) m.imr_address.s_addr = INADDR_ANY; m.imr_ifindex = iface; #endif rv = setsockopt(o->iod_get_fd(iod), IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *) &m, sizeof(m)); if (rv == -1) return gensio_os_err_to_err(o, sock_errno); } break; #ifdef AF_INET6 case AF_INET6: { struct sockaddr_in6 *a = (struct sockaddr_in6 *) ai->ai_addr; struct ipv6_mreq m; m.ipv6mr_multiaddr = a->sin6_addr; m.ipv6mr_interface = iface; rv = setsockopt(o->iod_get_fd(iod), IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (void *) &m, sizeof(m)); if (rv == -1) return gensio_os_err_to_err(o, sock_errno); } break; #endif default: return GE_INVAL; } if (curr_only) break; ai = ai->ai_next; } return 0; } static int gensio_stdsock_set_mcast_loop(struct gensio_iod *iod, bool ival) { struct gensio_os_funcs *o = iod->f; int rv, val = ival; struct gensio_stdsock_info *gsi; if (do_errtrig()) return GE_NOMEM; rv = o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, true, (intptr_t) &gsi); if (rv) return rv; switch (gsi->family) { case AF_INET: rv = setsockopt(o->iod_get_fd(iod), IPPROTO_IP, IP_MULTICAST_LOOP, (void *) &val, sizeof(val)); if (rv == -1) return gensio_os_err_to_err(o, sock_errno); break; #ifdef AF_INET6 case AF_INET6: rv = setsockopt(o->iod_get_fd(iod), IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (void *) &val, sizeof(val)); if (rv == -1) return gensio_os_err_to_err(o, sock_errno); break; #endif default: return GE_INVAL; } return 0; } static int gensio_stdsock_get_mcast_loop(struct gensio_iod *iod, bool *ival) { struct gensio_os_funcs *o = iod->f; int rv, val; socklen_t size; struct gensio_stdsock_info *gsi; if (do_errtrig()) return GE_NOMEM; rv = o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, true, (intptr_t) &gsi); if (rv) return rv; switch (gsi->family) { case AF_INET: size = sizeof(val); rv = getsockopt(o->iod_get_fd(iod), IPPROTO_IP, IP_MULTICAST_LOOP, (void *) &val, &size); if (rv == -1) return gensio_os_err_to_err(o, sock_errno); break; #ifdef AF_INET6 case AF_INET6: size = sizeof(val); rv = getsockopt(o->iod_get_fd(iod), IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (void *) &val, &size); if (rv == -1) return gensio_os_err_to_err(o, sock_errno); break; #endif default: return GE_INVAL; } *ival = !!val; return 0; } static int gensio_stdsock_getsockname(struct gensio_iod *iod, struct gensio_addr **raddr) { struct gensio_os_funcs *o = iod->f; struct gensio_addr *addr; struct addrinfo *ai; int err; taddrlen len; if (do_errtrig()) return GE_NOMEM; #if HAVE_LIBSCTP { struct gensio_stdsock_info *gsi; err = o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, true, (intptr_t) &gsi); if (err) return err; if (gsi->protocol == GENSIO_NET_PROTOCOL_SCTP) return gensio_os_sctp_getladdrs(iod, raddr); } #endif addr = gensio_addr_addrinfo_make(o, sizeof(struct sockaddr_storage), false); if (!addr) return GE_NOMEM; ai = gensio_addr_addrinfo_get_curr(addr); len = ai->ai_addrlen; err = getsockname(o->iod_get_fd(iod), ai->ai_addr, &len); if (err) { gensio_addr_free(addr); return gensio_os_err_to_err(o, sock_errno); } ai->ai_family = ai->ai_addr->sa_family; ai->ai_addrlen = len; *raddr = addr; return 0; } static int gensio_stdsock_getpeername(struct gensio_iod *iod, struct gensio_addr **raddr) { struct gensio_os_funcs *o = iod->f; struct gensio_addr *addr; struct addrinfo *ai; int err; taddrlen len; if (do_errtrig()) return GE_NOMEM; #if HAVE_LIBSCTP { struct gensio_stdsock_info *gsi; err = o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, true, (intptr_t) &gsi); if (err) return err; if (gsi->protocol == GENSIO_NET_PROTOCOL_SCTP) return gensio_os_sctp_getpaddrs(iod, raddr); } #endif addr = gensio_addr_addrinfo_make(o, sizeof(struct sockaddr_storage), false); if (!addr) return GE_NOMEM; ai = gensio_addr_addrinfo_get_curr(addr); len = ai->ai_addrlen; err = getpeername(o->iod_get_fd(iod), ai->ai_addr, &len); if (err) { gensio_addr_free(addr); return gensio_os_err_to_err(o, sock_errno); } ai->ai_family = ai->ai_addr->sa_family; ai->ai_addrlen = len; *raddr = addr; return 0; } static int gensio_stdsock_getpeerraw(struct gensio_iod *iod, void *addr, gensiods *addrlen) { struct gensio_os_funcs *o = iod->f; int err; taddrlen len; if (do_errtrig()) return GE_NOMEM; #if HAVE_LIBSCTP { struct gensio_stdsock_info *gsi; err = o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, true, (intptr_t) &gsi); if (err) return err; if (gsi->protocol == GENSIO_NET_PROTOCOL_SCTP) return gensio_os_sctp_getraddr(iod, addr, addrlen); } #endif len = *addrlen; err = getpeername(o->iod_get_fd(iod), addr, &len); if (err) return gensio_os_err_to_err(o, sock_errno); else *addrlen = len; return 0; } static int socket_get_port(struct gensio_os_funcs *o, int fd, unsigned int *port) { struct sockaddr_storage sa; socklen_t len = sizeof(sa); int rv; if (do_errtrig()) return GE_NOMEM; rv = getsockname(fd, (struct sockaddr *) &sa, &len); if (rv) return gensio_os_err_to_err(o, sock_errno); rv = gensio_sockaddr_get_port((struct sockaddr *) &sa, port); if (rv) return rv; return 0; } static int gensio_stdsock_get_port(struct gensio_iod *iod, unsigned int *port) { return socket_get_port(iod->f, iod->f->iod_get_fd(iod), port); } static int gensio_stdsock_set_mcast_ttl(struct gensio_iod *iod, unsigned int ttl) { struct gensio_os_funcs *o = iod->f; int rv, val = ttl; struct gensio_stdsock_info *gsi; if (do_errtrig()) return GE_NOMEM; rv = o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, true, (intptr_t) &gsi); if (rv) return rv; switch (gsi->family) { case AF_INET: rv = setsockopt(o->iod_get_fd(iod), IPPROTO_IP, IP_MULTICAST_TTL, (void *) &val, sizeof(val)); if (rv == -1) return gensio_os_err_to_err(o, sock_errno); break; #ifdef AF_INET6 case AF_INET6: rv = setsockopt(o->iod_get_fd(iod), IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (void *) &val, sizeof(val)); if (rv == -1) return gensio_os_err_to_err(o, sock_errno); break; #endif default: return GE_INVAL; } return 0; } static int gensio_stdsock_get_mcast_ttl(struct gensio_iod *iod, unsigned int *ttl) { struct gensio_os_funcs *o = iod->f; int rv, val; socklen_t size; struct gensio_stdsock_info *gsi; if (do_errtrig()) return GE_NOMEM; rv = o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, true, (intptr_t) &gsi); if (rv) return rv; switch (gsi->family) { case AF_INET: size = sizeof(val); rv = getsockopt(o->iod_get_fd(iod), IPPROTO_IP, IP_MULTICAST_TTL, (void *) &val, &size); if (rv == -1) return gensio_os_err_to_err(o, sock_errno); break; #ifdef AF_INET6 case AF_INET6: size = sizeof(val); rv = getsockopt(o->iod_get_fd(iod), IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (void *) &val, &size); if (rv == -1) return gensio_os_err_to_err(o, sock_errno); break; #endif default: return GE_INVAL; } *ttl = val; return 0; } static int gensio_stdsock_set_extrainfo(struct gensio_iod *iod, unsigned int val) { #ifndef HAVE_RECVMSG return GE_NOTSUP; #else struct gensio_os_funcs *o = iod->f; struct gensio_stdsock_info *gsi; int fd, err; err = o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, true, (intptr_t) &gsi); if (err) return err; if (gsi->protocol != GENSIO_NET_PROTOCOL_UDP) return GE_INVAL; fd = o->iod_get_fd(iod); if (gsi->family == AF_UNSPEC || gsi->family == AF_INET) { #ifdef IP_PKTINFO err = setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val)); if (err) return gensio_os_err_to_err(o, sock_errno); #elif defined(IP_RECVIF) && defined(IP_RECVDSTADDR) err = setsockopt(fd, IPPROTO_IP, IP_RECVIF, &val, sizeof(val)); if (err) return gensio_os_err_to_err(o, sock_errno); err = setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &val, sizeof(val)); if (err) return gensio_os_err_to_err(o, sock_errno); #else return GE_NOTSUP; #endif } #ifdef AF_INET6 if (gsi->family == AF_UNSPEC || gsi->family == AF_INET6) { #ifdef IPV6_RECVPKTINFO err = setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val, sizeof(val)); if (err) return gensio_os_err_to_err(o, sock_errno); #else return GE_NOTSUP; #endif } #endif gsi->extrainfo = val; return 0; #endif } static int gensio_stdsock_get_extrainfo(struct gensio_iod *iod, unsigned int *val) { #ifndef HAVE_RECVMSG return GE_NOTSUP; #else struct gensio_os_funcs *o = iod->f; struct gensio_stdsock_info *gsi; int err; err = o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, true, (intptr_t) &gsi); if (err) return err; *val = gsi->extrainfo; return 0; #endif } static int gensio_stdsock_control(struct gensio_iod *iod, int func, void *data, gensiods *datalen) { switch (func) { case GENSIO_SOCKCTL_SET_MCAST_LOOP: if (*datalen != sizeof(bool)) return GE_INVAL; return gensio_stdsock_set_mcast_loop(iod, *((bool *) data)); case GENSIO_SOCKCTL_GET_MCAST_LOOP: if (*datalen != sizeof(bool)) return GE_INVAL; return gensio_stdsock_get_mcast_loop(iod, ((bool *) data)); case GENSIO_SOCKCTL_GET_SOCKNAME: return gensio_stdsock_getsockname(iod, data); case GENSIO_SOCKCTL_GET_PEERNAME: return gensio_stdsock_getpeername(iod, data); case GENSIO_SOCKCTL_GET_PEERRAW: return gensio_stdsock_getpeerraw(iod, data, datalen); case GENSIO_SOCKCTL_GET_PORT: if (*datalen != sizeof(unsigned int)) return GE_INVAL; return gensio_stdsock_get_port(iod, ((unsigned int *) data)); case GENSIO_SOCKCTL_CHECK_OPEN: return gensio_stdsock_check_socket_open(iod); case GENSIO_SOCKCTL_SET_MCAST_TTL: if (*datalen != sizeof(unsigned int)) return GE_INVAL; return gensio_stdsock_set_mcast_ttl(iod, *((unsigned int *) data)); case GENSIO_SOCKCTL_GET_MCAST_TTL: if (*datalen != sizeof(unsigned int)) return GE_INVAL; return gensio_stdsock_get_mcast_ttl(iod, ((unsigned int *) data)); case GENSIO_SOCKCTL_SET_EXTRAINFO: if (*datalen != sizeof(unsigned int)) return GE_INVAL; return gensio_stdsock_set_extrainfo(iod, *((unsigned int *) data)); case GENSIO_SOCKCTL_GET_EXTRAINFO: if (*datalen != sizeof(unsigned int)) return GE_INVAL; return gensio_stdsock_get_extrainfo(iod, ((unsigned int *) data)); default: return GE_NOTSUP; } } /* * For assigning zero ports. */ #define IP_DYNRANGE_START 49152 #define IP_DYNRANGE_END 65535 static unsigned int gensio_dyn_scan_next(unsigned int port) { if (port == IP_DYNRANGE_END) return IP_DYNRANGE_START; else return port + 1; } static int gensio_stdsock_open_listen_sockets(struct gensio_os_funcs *o, struct gensio_addr *addr, int (*call_b4_listen)(struct gensio_iod *, void *), void *data, unsigned int opensock_flags, struct gensio_opensocks **rfds, unsigned int *nr_fds) { struct addrinfo *rp; int family; struct gensio_opensocks *fds; unsigned int curr_fd = 0, i; unsigned int max_fds = 0; struct addrinfo *ai; int rv = 0; struct gensio_listen_scan_info scaninfo; if (do_errtrig()) return GE_NOMEM; ai = gensio_addr_addrinfo_get(addr); #if HAVE_LIBSCTP if (ai->ai_protocol == IPPROTO_SCTP) return gensio_os_sctp_open_sockets(o, addr, call_b4_listen, data, opensock_flags, rfds, nr_fds); #endif for (rp = ai; rp != NULL; rp = rp->ai_next) max_fds++; if (max_fds == 0) return GE_INVAL; fds = o->zalloc(o, sizeof(*fds) * max_fds); if (!fds) return GE_NOMEM; memset(&scaninfo, 0, sizeof(scaninfo)); #if !HAVE_WORKING_PORT0 restart_family: #endif #ifdef AF_INET6 family = AF_INET6; /* Try IPV6 first, then IPV4. */ #else family = AF_INET; #endif restart: for (rp = ai; rp != NULL; rp = rp->ai_next) { if (family != rp->ai_family) continue; /* * getaddrinfo() will return the same address twice in the * list if ::1 and 127.0.0.1 are both set for localhost in * /etc/hosts. So the second open attempt will fail if we * don't ignore this. In general, it's probably better to * ignore duplicates in this function, anyway. */ if (sockaddr_in_list_b4(rp, ai)) continue; rv = gensio_setup_listen_socket(o, rp->ai_family, rp->ai_socktype, rp->ai_protocol, rp->ai_flags, rp->ai_addr, rp->ai_addrlen, call_b4_listen, data, opensock_flags, &fds[curr_fd].iod, &fds[curr_fd].port, &scaninfo); if (rv) goto out_close; fds[curr_fd].family = rp->ai_family; fds[curr_fd].flags = rp->ai_flags; curr_fd++; } #ifdef AF_INET6 if (family == AF_INET6) { family = AF_INET; goto restart; } #endif if (family == AF_INET) { family = AF_UNIX; goto restart; } if (curr_fd == 0) { o->free(o, fds); if (rv) return rv; assert(0); return GE_NOTFOUND; } *nr_fds = curr_fd; *rfds = fds; return 0; out_close: for (i = 0; i < curr_fd; i++) { o->clear_fd_handlers_norpt(fds[i].iod); o->close(&fds[i].iod); } #if !HAVE_WORKING_PORT0 if (rv == GE_ADDRINUSE && scaninfo.start != 0 && scaninfo.curr != scaninfo.start) { /* We need to keep scanning. */ curr_fd = 0; scaninfo.reqport = 0; goto restart_family; } #endif o->free(o, fds); return rv; } static bool family_is_inet(int family) { if (family == AF_INET) return true; #ifdef AF_INET6 if (family == AF_INET6) return true; #endif return false; } static int gensio_setup_listen_socket(struct gensio_os_funcs *o, int family, int socktype, int sockproto, int flags, struct sockaddr *addr, socklen_t addrlen, int (*call_b4_listen)(struct gensio_iod *, void *), void *data, unsigned int opensock_flags, struct gensio_iod **riod, unsigned int *rport, struct gensio_listen_scan_info *rsi) { int optval = 1; int fd, rv = 0; unsigned int port; struct sockaddr_storage sa; struct gensio_iod *iod = NULL; int protocol; struct gensio_stdsock_info *gsi = NULL; bool do_listen = true; if (family == AF_UNIX && socktype == SOCK_DGRAM) { protocol = GENSIO_NET_PROTOCOL_UNIX_DGRAM; do_listen = false; #ifdef SOCK_SEQPACKET } else if (family == AF_UNIX && socktype == SOCK_SEQPACKET) { protocol = GENSIO_NET_PROTOCOL_UNIX_SEQPACKET; #endif }else if (family == AF_UNIX) protocol = GENSIO_NET_PROTOCOL_UNIX; #ifdef IPPROTO_SCTP else if (sockproto == IPPROTO_SCTP) protocol = GENSIO_NET_PROTOCOL_SCTP; #endif else if (sockproto == 0 && socktype == SOCK_DGRAM) protocol = GENSIO_NET_PROTOCOL_UDP; else if (sockproto == 0 && socktype == SOCK_STREAM) protocol = GENSIO_NET_PROTOCOL_TCP; else if (sockproto == IPPROTO_TCP) protocol = GENSIO_NET_PROTOCOL_TCP; else if (sockproto == IPPROTO_UDP) { protocol = GENSIO_NET_PROTOCOL_UDP; do_listen = false; } else return GE_INVAL; rv = gensio_sockaddr_get_port(addr, &port); if (rv == -1) return GE_INVAL; if (addrlen < 0) return GE_INVAL; if ((unsigned int) addrlen > sizeof(sa)) return GE_TOOBIG; memcpy(&sa, addr, addrlen); addr = (struct sockaddr *) &sa; if (rsi && rsi->reqport != 0 && port == 0) { rv = gensio_sockaddr_set_port(addr, rsi->reqport); if (rv) return rv; port = rsi->reqport; } fd = socket(family, socktype, sockproto); if (fd == -1) return gensio_os_err_to_err(o, sock_errno); if (opensock_flags & GENSIO_OPENSOCK_REUSEADDR) { switch (family) { #if HAVE_UNIX || defined(_WIN32) case AF_UNIX: { /* We remove an existing socket with reuseaddr and AF_UNIX. */ struct sockaddr_un *unaddr = (struct sockaddr_un *) addr; char unpath[sizeof(unaddr->sun_path) + 1]; /* * Make sure the path is nil terminated. See discussions * in the unix(7) man page on Linux for details. */ assert(addrlen <= sizeof(*unaddr)); memcpy(unpath, unaddr->sun_path, addrlen-SIZEOF_SOCKADDR_UN_HEADER); unpath[addrlen - SIZEOF_SOCKADDR_UN_HEADER] = '\0'; #if HAVE_UNIX unlink(unpath); #else DeleteFile(unpath); #endif /* * Ignore errors, it may not exist, and we'll get errors * later on problems. */ break; } #endif default: if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval, sizeof(optval)) == -1) goto out_err; } } if (check_ipv6_only(family, sockproto, flags, fd) == -1) goto out_err; #if !HAVE_WORKING_PORT0 if (port == 0 && family_is_inet(family)) { struct gensio_listen_scan_info lsi; struct gensio_listen_scan_info *si = rsi; if (!si) { si = &lsi; memset(si, 0, sizeof(*si)); } if (si->start == 0) { /* Get a random port in the dynamic range. */ o->get_random(o, &si->start, sizeof(si->start)); si->start %= IP_DYNRANGE_END - IP_DYNRANGE_START + 1; si->start += IP_DYNRANGE_START; si->curr = si->start; } do { rv = gensio_sockaddr_set_port(addr, si->curr); if (rv) goto out; if (bind(fd, addr, addrlen) == 0) { goto got_it; } else { #ifdef _WIN32 /* * Apparently, if you try to grab some ports on * windows, you get a permission error if maybe some * other process that is privileged or just another * user is using it? Sometimes this happens, just let * it go. */ if (sock_errno == WSAEACCES) goto next_port; #endif if (sock_errno == SOCK_EADDRINUSE) goto next_port; goto out_err; } next_port: si->curr = gensio_dyn_scan_next(si->curr); } while (si->curr != si->start); /* Unable to find an open port, give up. */ rv = GE_ADDRINUSE; goto out; } #endif if (bind(fd, addr, addrlen) != 0) { if (rsi) rsi->curr = gensio_dyn_scan_next(rsi->curr); goto out_err; } #if !HAVE_WORKING_PORT0 got_it: #endif if (family_is_inet(family)) { rv = socket_get_port(o, fd, &port); if (rv) goto out; if (rsi && rsi->reqport == 0) rsi->reqport = port; *rport = port; } else { *rport = 0; } rv = o->add_iod(o, GENSIO_IOD_SOCKET, fd, &iod); if (rv) goto out; gsi = o->zalloc(o, sizeof(*gsi)); if (!gsi) { rv = GE_NOMEM; goto out; } gsi->protocol = protocol; gsi->family = family; o->iod_control(iod, GENSIO_IOD_CONTROL_SOCKINFO, false, (intptr_t) gsi); rv = o->set_non_blocking(iod); if (rv) goto out; if (call_b4_listen) { rv = call_b4_listen(iod, data); if (rv) goto out; } if (do_listen && listen(fd, 5) != 0) goto out_err; out: if (rv) { if (iod) o->release_iod(iod); if (gsi) o->free(o, gsi); close_socket(o, fd); } else { *riod = iod; } return rv; out_err: rv = gensio_os_err_to_err(o, sock_errno); goto out; } int gensio_stdsock_set_os_funcs(struct gensio_os_funcs *o) { #ifdef _WIN32 WSADATA wsa_data; if (WSAStartup(MAKEWORD(2, 2), &wsa_data)) return GE_NOMEM; #endif o->recv = gensio_stdsock_recv; o->send = gensio_stdsock_send; o->sendto = gensio_stdsock_sendto; o->addr_alloc_recvfrom = gensio_addr_addrinfo_alloc_recvfrom; o->recvfrom = gensio_stdsock_recvfrom; o->accept = gensio_stdsock_accept; o->socket_open = gensio_stdsock_socket_open; o->socket_set_setup = gensio_stdsock_socket_set_setup; o->socket_get_setup = gensio_stdsock_socket_get_setup; o->connect = gensio_stdsock_connect; o->close_socket = gensio_stdsock_close_socket; o->mcast_add = gensio_stdsock_mcast_add; o->mcast_del = gensio_stdsock_mcast_del; o->sock_control = gensio_stdsock_control; o->open_listen_sockets = gensio_stdsock_open_listen_sockets; #if HAVE_LIBSCTP o->sctp_connectx = gensio_stdsock_sctp_connectx; o->sctp_recvmsg = gensio_stdsock_sctp_recvmsg; o->sctp_send = gensio_stdsock_sctp_send; o->sctp_socket_setup = gensio_stdsock_sctp_socket_setup; o->sctp_get_socket_status = gensio_stdsock_sctp_get_socket_status; #endif return 0; } void gensio_stdsock_cleanup(struct gensio_os_funcs *o) { #ifdef _WIN32 WSACleanup(); #endif } gensio-3.0.0/lib/gensio_openipmi_oshandler.c0000664000175000017500000002664714775472612014654 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2025 Corey Minyard * * This is an OpenIPMI os handler that you can create from a * gensio_os_funcs. * * SPDX-License-Identifier: LGPL-2.1-only */ #include #include #include #include #include #include #include struct igensio_info { struct gensio_os_funcs *o; os_vlog_t log_handler; }; static void * gio_mem_alloc(int size) { return malloc(size); } static void gio_mem_free(void *data) { free(data); } struct os_hnd_fd_id_s { struct gensio_os_funcs *o; int fd; struct gensio_iod *iod; void *cb_data; os_data_ready_t data_ready; os_data_ready_t write_ready; os_data_ready_t except_ready; os_handler_t *handler; os_fd_data_freed_t freed; }; static void fd_read_handler(struct gensio_iod *iod, void *data) { os_hnd_fd_id_t *fd_data = (os_hnd_fd_id_t *) data; fd_data->data_ready(fd_data->fd, fd_data->cb_data, fd_data); } static void fd_write_handler(struct gensio_iod *iod, void *data) { os_hnd_fd_id_t *fd_data = (os_hnd_fd_id_t *) data; fd_data->write_ready(fd_data->fd, fd_data->cb_data, fd_data); } static void fd_except_handler(struct gensio_iod *iod, void *data) { os_hnd_fd_id_t *fd_data = (os_hnd_fd_id_t *) data; fd_data->except_ready(fd_data->fd, fd_data->cb_data, fd_data); } static void free_fd_data(struct gensio_iod *iod, void *data) { os_hnd_fd_id_t *fd_data = data; fd_data->o->release_iod(fd_data->iod); if (fd_data->freed) fd_data->freed(fd_data->fd, fd_data->cb_data); free(data); } static int gio_add_fd_to_wait_for(os_handler_t *handler, int fd, os_data_ready_t data_ready, void *cb_data, os_fd_data_freed_t freed, os_hnd_fd_id_t **id) { os_hnd_fd_id_t *fd_data; int rv; struct igensio_info *info = handler->internal_data; struct gensio_os_funcs *o = info->o; fd_data = malloc(sizeof(*fd_data)); if (!fd_data) return ENOMEM; fd_data->o = o; rv = o->add_iod(o, GENSIO_IOD_SOCKET, fd, &fd_data->iod); if (rv) { free(fd_data); return rv; } fd_data->fd = fd; fd_data->cb_data = cb_data; fd_data->data_ready = data_ready; fd_data->handler = handler; fd_data->freed = freed; rv = o->set_fd_handlers(fd_data->iod, fd_data, fd_read_handler, fd_write_handler, fd_except_handler, free_fd_data); if (rv) { o->release_iod(fd_data->iod); free(fd_data); return rv; } o->set_write_handler(fd_data->iod, false); o->set_except_handler(fd_data->iod, false); o->set_read_handler(fd_data->iod, true); *id = fd_data; return 0; } static int gio_remove_fd_to_wait_for(os_handler_t *handler, os_hnd_fd_id_t *id) { struct igensio_info *info = handler->internal_data; struct gensio_os_funcs *o = info->o; o->set_read_handler(id->iod, false); o->clear_fd_handlers(id->iod); return 0; } struct os_hnd_timer_id_s { void *cb_data; os_timed_out_t timed_out; struct gensio_timer *timer; bool running; os_handler_t *handler; struct gensio_lock *lock; }; static void timer_handler(struct gensio_timer *t, void *data) { os_hnd_timer_id_t *timer = (os_hnd_timer_id_t *) data; os_handler_t *handler = timer->handler; struct igensio_info *info = handler->internal_data; struct gensio_os_funcs *o = info->o; void *cb_data; os_timed_out_t timed_out; o->lock(timer->lock); timed_out = timer->timed_out; cb_data = timer->cb_data; timer->running = false; o->unlock(timer->lock); timed_out(cb_data, timer); } static int gio_alloc_timer(os_handler_t *handler, os_hnd_timer_id_t **rtimer) { os_hnd_timer_id_t *timer; struct igensio_info *info = handler->internal_data; struct gensio_os_funcs *o = info->o; timer = malloc(sizeof(*timer)); if (!timer) return ENOMEM; timer->lock = o->alloc_lock(o); if (!timer->lock) { free(timer); return ENOMEM; } timer->running = false; timer->timed_out = NULL; timer->handler = handler; timer->timer = o->alloc_timer(o, timer_handler, timer); if (!timer->timer) { o->free_lock(timer->lock); free(timer); return ENOMEM; } *rtimer = timer; return 0; } static int gio_free_timer(os_handler_t *handler, os_hnd_timer_id_t *timer) { struct igensio_info *info = handler->internal_data; struct gensio_os_funcs *o = info->o; o->free_timer(timer->timer); o->free_lock(timer->lock); free(timer); return 0; } static int gio_start_timer(os_handler_t *handler, os_hnd_timer_id_t *timer, struct timeval *timeout, os_timed_out_t timed_out, void *cb_data) { struct igensio_info *info = handler->internal_data; struct gensio_os_funcs *o = info->o; gensio_time gtime; int rv = 0; o->lock(timer->lock); if (timer->running) { rv = EAGAIN; goto out_unlock; } timer->running = true; timer->cb_data = cb_data; timer->timed_out = timed_out; gtime.secs = timeout->tv_sec; gtime.nsecs = timeout->tv_usec * 1000; rv = o->start_timer(timer->timer, >ime); if (rv) timer->running = false; out_unlock: o->unlock(timer->lock); return rv; } static int gio_stop_timer(os_handler_t *handler, os_hnd_timer_id_t *timer) { struct igensio_info *info = handler->internal_data; struct gensio_os_funcs *o = info->o; int rv = 0; o->lock(timer->lock); if (timer->running) { timer->running = 0; o->stop_timer(timer->timer); } else { rv = ETIMEDOUT; } o->unlock(timer->lock); return rv; } struct os_hnd_lock_s { struct gensio_lock *lock; }; static int gio_create_lock(os_handler_t *handler, os_hnd_lock_t **rlock) { struct igensio_info *info = handler->internal_data; struct gensio_os_funcs *o = info->o; os_hnd_lock_t *lock; lock = malloc(sizeof(*lock)); if (!lock) return ENOMEM; lock->lock = o->alloc_lock(o); if (!lock->lock) { free(lock); return ENOMEM; } *rlock = lock; return 0; } static int gio_destroy_lock(os_handler_t *handler, os_hnd_lock_t *lock) { struct igensio_info *info = handler->internal_data; struct gensio_os_funcs *o = info->o; o->free_lock(lock->lock); free(lock); return 0; } static int gio_lock(os_handler_t *handler, os_hnd_lock_t *lock) { struct igensio_info *info = handler->internal_data; struct gensio_os_funcs *o = info->o; o->lock(lock->lock); return 0; } static int gio_unlock(os_handler_t *handler, os_hnd_lock_t *lock) { struct igensio_info *info = handler->internal_data; struct gensio_os_funcs *o = info->o; o->unlock(lock->lock); return 0; } static int gio_get_random(os_handler_t *handler, void *data, unsigned int len) { struct igensio_info *info = handler->internal_data; return info->o->get_random(info->o, data, len); } static void gio_vlog(os_handler_t *handler, enum ipmi_log_type_e log_type, const char *format, va_list ap) { struct igensio_info *info = handler->internal_data; os_vlog_t log_handler = info->log_handler; enum gensio_log_levels level; switch(log_type) { case IPMI_LOG_INFO: default: level = GENSIO_LOG_INFO; break; case IPMI_LOG_WARNING: case IPMI_LOG_ERR_INFO: level = GENSIO_LOG_WARNING; break; case IPMI_LOG_SEVERE: level = GENSIO_LOG_ERR; break; case IPMI_LOG_FATAL: level = GENSIO_LOG_FATAL; break; case IPMI_LOG_DEBUG: case IPMI_LOG_DEBUG_START: case IPMI_LOG_DEBUG_CONT: case IPMI_LOG_DEBUG_END: level = GENSIO_LOG_DEBUG; break; } if (log_handler) { log_handler(handler, format, log_type, ap); } else if (info->o->vlog) { gensio_vlog(info->o, level, format, ap); } else if (gensio_get_log_mask() & (1 << level)) { vprintf(format, ap); putc('\n', stdout); } } static void gio_log(os_handler_t *handler, enum ipmi_log_type_e log_type, const char *format, ...) { va_list ap; va_start(ap, format); gio_vlog(handler, log_type, format, ap); va_end(ap); } static void gio_set_log_handler(os_handler_t *handler, os_vlog_t log_handler) { struct igensio_info *info = handler->internal_data; info->log_handler = log_handler; } static void gio_set_fd_handlers(os_handler_t *handler, os_hnd_fd_id_t *id, os_data_ready_t write_ready, os_data_ready_t except_ready) { id->write_ready = write_ready; id->except_ready = except_ready; } static int gio_set_fd_enables(os_handler_t *handler, os_hnd_fd_id_t *id, int read, int write, int except) { struct igensio_info *info = handler->internal_data; struct gensio_os_funcs *o = info->o; o->set_read_handler(id->iod, read); o->set_write_handler(id->iod, write); o->set_except_handler(id->iod, except); return 0; } static int gio_get_monotonic_time(os_handler_t *handler, struct timeval *tv) { struct igensio_info *info = handler->internal_data; struct gensio_os_funcs *o = info->o; gensio_time gtime; o->get_monotonic_time(o, >ime); tv->tv_sec = gtime.secs; tv->tv_usec = (gtime.nsecs + 500) / 1000; return 0; } static int gio_get_real_time(os_handler_t *handler, struct timeval *tv) { gettimeofday(tv, NULL); return 0; } static void gio_free_os_handler(os_handler_t *handler) { struct igensio_info *info = handler->internal_data; ipmi_free_os_handler(handler); free(info); } void ipmi_malloc_init(os_handler_t *oshandler); void ipmi_malloc_shutdown(void); os_handler_t * gensio_openipmi_oshandler_alloc(struct gensio_os_funcs *o) { struct igensio_info *info; os_handler_t *handler; os_handler_t dummyh; info = malloc(sizeof(*info)); if (!info) return NULL; info->o = o; info->log_handler = NULL; /* * This is a cheap hack, get enough of an os handler to allocate one * with ipmi_alloc_os_handler(), then shut it down and let the main * os handler take over. */ memset(&dummyh, 0, sizeof(dummyh)); dummyh.mem_alloc = gio_mem_alloc; dummyh.mem_free = gio_mem_free; ipmi_malloc_init(&dummyh); handler = ipmi_alloc_os_handler(); if (!handler) { free(info); return NULL; } ipmi_malloc_shutdown(); handler->mem_alloc = gio_mem_alloc; handler->mem_free = gio_mem_free; handler->add_fd_to_wait_for = gio_add_fd_to_wait_for; handler->remove_fd_to_wait_for = gio_remove_fd_to_wait_for; handler->alloc_timer = gio_alloc_timer; handler->free_timer = gio_free_timer; handler->start_timer = gio_start_timer; handler->stop_timer = gio_stop_timer; handler->create_lock = gio_create_lock; handler->destroy_lock = gio_destroy_lock; handler->lock = gio_lock; handler->unlock = gio_unlock; handler->get_random = gio_get_random; handler->log = gio_log; handler->vlog = gio_vlog; handler->set_log_handler = gio_set_log_handler; handler->set_fd_handlers = gio_set_fd_handlers; handler->set_fd_enables = gio_set_fd_enables; handler->get_monotonic_time = gio_get_monotonic_time; handler->get_real_time = gio_get_real_time; handler->free_os_handler = gio_free_os_handler; handler->internal_data = info; return handler; }; gensio-3.0.0/lib/gensio_keepopen.c0000664000175000017500000004024514664224267012567 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* * This code is for a gensio that will never report child errors and * attempts to keep the child open. */ #include #include #include #include "config.h" #include #include #include #include /* * KEEPN_CLOSED: * open: * open_done = userfunc * rv = start child open * if (rv) * // Use this to report the open immediately * ->KEEPN_OPEN_INIT_FAIL * start zero timer * else * ->KEEPN_IN_OPEN * * KEEPN_IN_OPEN: * close: * rv = start child close * if (rv) * ->KEEPN_CLOSE_STOP_TIMER * start zero-length timer * else * ->KEEPN_IN_CLOSE * opened: * report open * open_done = NULL * if (err) * start timer * ->KEEPN_CHILD_CLOSED * else * ->KEEPN_OPEN * report open * * KEEPN_OPEN_INIT_FAIL: //Failed on first open only * close: * ->KEEPN_CLOSE_STOP_TIMER // timeout will open/close it * timeout: * start timer * ->KEEPN_CHILD_CLOSED * * KEEPN_OPEN: * pass data through * close: * rv = start child close * if (rv) * ->KEEPN_CLOSED * else * ->KEEPN_IN_CLOSE * I/O error: * rv = start child close * if (rv) * start timer * ->KEEPN_CHILD_CLOSED * else * ->KEEPN_CHILD_ERR_CLOSE * * KEEPN_IN_CLOSE: * closed: * if open_done * report open * open_done = NULL * ->KEEPN_CLOSED * report close * * KEEPN_CHILD_ERR_CLOSE: * close: * ->KEEPN_IN_CLOSE * closed: * incr refcount * start timer * ->KEEPN_CHILD_CLOSED * * KEEPN_CHILD_CLOSED: * close: * ->KEEPN_CLOSE_STOP_TIMER * rv = stop_timer * if (rv == GE_TIMEDOUT) * -- * else if (rv == 0) * start zero-length timer * else * error * timeout: * rv = start chid open * if (rv) * start timer * else * ->KEEPN_CHILD_CLOSED_IN_OPEN * * KEEPN_CLOSE_STOP_TIMER: * timeout: * if open_done * report open * open_done = NULL * ->KEEPN_CLOSED * report close * * KEEPN_CHILD_CLOSED_IN_OPEN: * close: * rv = start child close * if (rv) * ->KEEPN_CLOSE_STOP_TIMER * start zero-length timer * else * ->KEEPN_IN_CLOSE * opened: * if (err) * start timer * ->KEEPN_CHILD_CLOSED * else * ->KEEPN_OPEN * */ enum keepn_state { KEEPN_CLOSED, KEEPN_IN_OPEN, KEEPN_OPEN_INIT_FAIL, KEEPN_OPEN, KEEPN_IN_CLOSE, KEEPN_CHILD_ERR_CLOSE, KEEPN_CHILD_CLOSED, KEEPN_CLOSE_STOP_TIMER, KEEPN_CHILD_CLOSED_IN_OPEN, }; struct keepn_data { struct gensio_os_funcs *o; struct gensio_lock *lock; struct gensio *child; unsigned int refcount; enum keepn_state state; int last_child_err; bool discard_badwrites; /* Keep these around to set them when the open completes. */ bool rx_enable; bool tx_enable; struct gensio *io; struct gensio_timer *retry_timer; struct gensio_time retry_time; bool read_enabled; bool xmit_enabled; gensio_done_err open_done; void *open_data; gensio_done close_done; void *close_data; }; static void keepn_finish_free(struct keepn_data *ndata) { struct gensio_os_funcs *o = ndata->o; if (ndata->io) gensio_data_free(ndata->io); if (ndata->child) gensio_free(ndata->child); if (ndata->retry_timer) o->free_timer(ndata->retry_timer); if (ndata->lock) o->free_lock(ndata->lock); o->free(o, ndata); } static void keepn_lock(struct keepn_data *ndata) { ndata->o->lock(ndata->lock); } static void keepn_unlock(struct keepn_data *ndata) { ndata->o->unlock(ndata->lock); } static void keepn_ref(struct keepn_data *ndata) { assert(ndata->refcount > 0); ndata->refcount++; } /* Cannot be called for the last deref. */ static void keepn_deref(struct keepn_data *ndata) { assert(ndata->refcount > 1); ndata->refcount--; } static void keepn_unlock_and_deref(struct keepn_data *ndata) { assert(ndata->refcount > 0); if (ndata->refcount == 1) { keepn_unlock(ndata); keepn_finish_free(ndata); } else { ndata->refcount--; keepn_unlock(ndata); } } static void keepn_start_zero_timer(struct keepn_data *ndata) { gensio_time timeout = { 0, 0 }; keepn_ref(ndata); if (ndata->o->start_timer(ndata->retry_timer, &timeout) != 0) assert(0); } static void keepn_start_timer(struct keepn_data *ndata) { keepn_ref(ndata); if (ndata->o->start_timer(ndata->retry_timer, &ndata->retry_time) != 0) assert(0); } static void keepn_cancel_timer(struct keepn_data *ndata) { int err = ndata->o->stop_timer(ndata->retry_timer); if (err == GE_TIMEDOUT) { /* * In the timer handler before the lock, just let the * timer handle handle it. */ } else if (!err) { keepn_start_zero_timer(ndata); keepn_deref(ndata); } else { assert(0); } } static void keepn_check_open_done(struct keepn_data *ndata) { if (ndata->open_done) { gensio_done_err open_done = ndata->open_done; void *open_data = ndata->open_data; /* * I don't think that anything can change the state at * this point, so no need for a marker that we are in open * done. */ ndata->open_done = NULL; keepn_unlock(ndata); open_done(ndata->io, 0, open_data); keepn_lock(ndata); } } static void keepn_check_close_done(struct keepn_data *ndata) { gensio_done close_done = ndata->close_done; void *close_data = ndata->close_data; ndata->close_done = NULL; keepn_unlock(ndata); if (close_done) close_done(ndata->io, close_data); keepn_lock(ndata); } static void keepn_open_done(struct gensio *io, int err, void *iopen_data) { struct keepn_data *ndata = iopen_data; keepn_lock(ndata); switch (ndata->state) { case KEEPN_IN_OPEN: if (err) { ndata->last_child_err = err; keepn_unlock(ndata); gensio_glog(ndata->io, GENSIO_LOG_INFO, "Error opening child gensio: %s", gensio_err_to_str(err)); keepn_lock(ndata); ndata->state = KEEPN_CHILD_CLOSED; keepn_start_timer(ndata); } else { /* * last_child_err is set if there was a previous error, we * use that to know if this was the first connection and * don't report on a first connection. */ if (ndata->last_child_err) { keepn_unlock(ndata); gensio_glog(ndata->io, GENSIO_LOG_INFO, "child gensio open restored"); keepn_lock(ndata); } gensio_set_write_callback_enable(ndata->child, ndata->tx_enable); gensio_set_read_callback_enable(ndata->child, ndata->rx_enable); ndata->state = KEEPN_OPEN; } if (ndata->open_done) { gensio_done_err open_done = ndata->open_done; void *open_data = ndata->open_data; /* * I don't think that anything can change the state at * this point, so no need for a marker that we are in open * done. */ ndata->open_done = NULL; keepn_unlock(ndata); open_done(ndata->io, 0, open_data); keepn_lock(ndata); } break; default: assert(0); } keepn_unlock(ndata); } static void keepn_close_done(struct gensio *io, void *open_data) { struct keepn_data *ndata = open_data; keepn_lock(ndata); switch (ndata->state) { case KEEPN_IN_CLOSE: keepn_check_open_done(ndata); ndata->state = KEEPN_CLOSED; keepn_check_close_done(ndata); break; case KEEPN_CHILD_ERR_CLOSE: ndata->state = KEEPN_CHILD_CLOSED; keepn_start_timer(ndata); break; default: assert(0); } keepn_unlock_and_deref(ndata); } static int keepn_handle_io_err(struct keepn_data *ndata, int err) { keepn_lock(ndata); if (ndata->state != KEEPN_OPEN) { keepn_unlock(ndata); return 0; } ndata->last_child_err = err; err = gensio_close(ndata->child, keepn_close_done, ndata); if (err) { keepn_start_timer(ndata); ndata->state = KEEPN_CHILD_CLOSED; } else { ndata->state = KEEPN_CHILD_ERR_CLOSE; keepn_ref(ndata); } keepn_unlock(ndata); gensio_glog(ndata->io, GENSIO_LOG_INFO, "I/O error from child gensio: %s", gensio_err_to_str(err)); return 0; } static int keepn_event(struct gensio *io, void *user_data, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) { struct keepn_data *ndata = user_data; if (err && event == GENSIO_EVENT_READ) { keepn_handle_io_err(ndata, err); return 0; } /* All other events just pass through. */ return gensio_cb(ndata->io, event, err, buf, buflen, auxdata); } static void keepn_retry_timeout(struct gensio_timer *t, void *cb_data) { struct keepn_data *ndata = cb_data; int err; keepn_lock(ndata); switch (ndata->state) { case KEEPN_OPEN_INIT_FAIL: keepn_check_open_done(ndata); ndata->state = KEEPN_CHILD_CLOSED; keepn_start_timer(ndata); keepn_unlock_and_deref(ndata); gensio_glog(ndata->io, GENSIO_LOG_INFO, "Error from gensio open: %s", gensio_err_to_str(ndata->last_child_err)); return; case KEEPN_CHILD_CLOSED: err = gensio_open(ndata->child, keepn_open_done, ndata); if (err) keepn_start_timer(ndata); else ndata->state = KEEPN_IN_OPEN; break; case KEEPN_CLOSE_STOP_TIMER: keepn_check_open_done(ndata); ndata->state = KEEPN_CLOSED; keepn_check_close_done(ndata); break; default: assert(0); } keepn_unlock_and_deref(ndata); } static int keepn_open(struct gensio *io, gensio_done_err open_done, void *open_data) { struct keepn_data *ndata = gensio_get_gensio_data(io); int err; keepn_lock(ndata); if (ndata->state != KEEPN_CLOSED) { err = GE_NOTREADY; goto out_unlock; } err = gensio_open(ndata->child, keepn_open_done, ndata); if (err) { ndata->last_child_err = err; ndata->state = KEEPN_OPEN_INIT_FAIL; keepn_start_zero_timer(ndata); err = 0; } else { ndata->last_child_err = 0; ndata->state = KEEPN_IN_OPEN; } ndata->open_done = open_done; ndata->open_data = open_data; out_unlock: keepn_unlock(ndata); return err; } static int keepn_close(struct gensio *io, gensio_done close_done, void *close_data) { struct keepn_data *ndata = gensio_get_gensio_data(io); int err = 0; keepn_lock(ndata); switch (ndata->state) { case KEEPN_OPEN: case KEEPN_IN_OPEN: err = gensio_close(ndata->child, keepn_close_done, ndata); if (err) { ndata->state = KEEPN_CLOSE_STOP_TIMER; keepn_start_zero_timer(ndata); } else { ndata->state = KEEPN_IN_CLOSE; keepn_ref(ndata); } break; case KEEPN_OPEN_INIT_FAIL: ndata->state = KEEPN_CLOSE_STOP_TIMER; break; case KEEPN_CHILD_ERR_CLOSE: ndata->state = KEEPN_IN_CLOSE; break; case KEEPN_CHILD_CLOSED: ndata->state = KEEPN_CLOSE_STOP_TIMER; keepn_cancel_timer(ndata); break; case KEEPN_CHILD_CLOSED_IN_OPEN: err = gensio_close(ndata->child, keepn_close_done, ndata); if (err) { ndata->state = KEEPN_CLOSE_STOP_TIMER; keepn_start_zero_timer(ndata); } else { ndata->state = KEEPN_IN_CLOSE; keepn_ref(ndata); } break; default: err = GE_NOTREADY; goto out_unlock; } ndata->close_done = close_done; ndata->close_data = close_data; out_unlock: keepn_unlock(ndata); return err; } static void keepn_free(struct gensio *io) { struct keepn_data *ndata = gensio_get_gensio_data(io); keepn_lock(ndata); switch(ndata->state) { case KEEPN_CLOSED: case KEEPN_IN_CLOSE: case KEEPN_CHILD_ERR_CLOSE: ndata->state = KEEPN_CLOSED; break; case KEEPN_OPEN_INIT_FAIL: ndata->state = KEEPN_CLOSE_STOP_TIMER; /* fallthrough */ case KEEPN_CLOSE_STOP_TIMER: ndata->open_done = NULL; /* Don't call the open callback on a free. */ break; case KEEPN_IN_OPEN: case KEEPN_OPEN: case KEEPN_CHILD_CLOSED_IN_OPEN: /* Close operation will grab a ref. */ keepn_close(ndata->io, NULL, NULL); ndata->state = KEEPN_CLOSED; break; case KEEPN_CHILD_CLOSED: ndata->state = KEEPN_CLOSE_STOP_TIMER; keepn_cancel_timer(ndata); break; } keepn_unlock_and_deref(ndata); } static int keepn_disable(struct gensio *io) { struct keepn_data *ndata = gensio_get_gensio_data(io); keepn_lock(ndata); ndata->state = KEEPN_CLOSED; keepn_unlock(ndata); return 0; } static int keepn_gensio_func(struct gensio *io, int func, gensiods *count, const void *cbuf, gensiods buflen, void *buf, const char *const *auxdata) { struct keepn_data *ndata = gensio_get_gensio_data(io); int err; switch (func) { case GENSIO_FUNC_WRITE_SG: err = gensio_call_func(ndata->child, func, count, cbuf, buflen, buf, auxdata); if (err) { keepn_handle_io_err(ndata, err); if (ndata->discard_badwrites) { gensiods i, amt = 0; const struct gensio_sg *sg = cbuf; for (i = 0; i < buflen; i++) amt += sg[i].buflen; *count = amt; } else { *count = 0; /* Tell the user to wait. */ } } return 0; case GENSIO_FUNC_OPEN: return keepn_open(io, (void *) cbuf, buf); case GENSIO_FUNC_CLOSE: return keepn_close(io, (void *) cbuf, buf); case GENSIO_FUNC_FREE: keepn_free(io); return 0; case GENSIO_FUNC_DISABLE: return keepn_disable(io); case GENSIO_FUNC_SET_READ_CALLBACK: keepn_lock(ndata); ndata->rx_enable = buflen; keepn_unlock(ndata); goto passon; case GENSIO_FUNC_SET_WRITE_CALLBACK: keepn_lock(ndata); ndata->tx_enable = buflen; keepn_unlock(ndata); goto passon; default: passon: /* Everything but the above just passes through. */ return gensio_call_func(ndata->child, func, count, cbuf, buflen, buf, auxdata); } } static int keepopen_gensio_alloc(struct gensio *child, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { struct keepn_data *ndata = NULL; int i; struct gensio_time retry_time = { 1, 0 }; bool discard_badwrites = false; GENSIO_DECLARE_PPGENSIO(p, o, cb, "keepopen", user_data); for (i = 0; args && args[i]; i++) { if (gensio_pparm_time(&p, args[i], "retry-time", 'm', &retry_time) > 0) continue; if (gensio_pparm_bool(&p, args[i], "discard-badwrites", &discard_badwrites) > 0) continue; return GE_INVAL; } ndata = o->zalloc(o, sizeof(*ndata)); if (!ndata) return GE_NOMEM; ndata->o = o; ndata->refcount = 1; ndata->retry_timer = o->alloc_timer(o, keepn_retry_timeout, ndata); if (!ndata->retry_timer) goto out_nomem; ndata->lock = o->alloc_lock(o); if (!ndata->lock) goto out_nomem; ndata->child = child; ndata->retry_time = retry_time; ndata->discard_badwrites = discard_badwrites; gensio_set_callback(child, keepn_event, ndata); ndata->io = gensio_data_alloc(ndata->o, cb, user_data, keepn_gensio_func, child, "keepopen", ndata); if (!ndata->io) goto out_nomem; gensio_set_is_client(ndata->io, true); *new_gensio = ndata->io; return 0; out_nomem: keepn_finish_free(ndata); return GE_NOMEM; } static int str_to_keepopen_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct gensio *io2; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio(str, o, cb, user_data, &io2); if (err) return err; err = keepopen_gensio_alloc(io2, args, o, cb, user_data, new_gensio); if (err) gensio_free(io2); return err; } int gensio_init_keepopen(struct gensio_os_funcs *o) { int rv; rv = register_filter_gensio(o, "keepopen", str_to_keepopen_gensio, keepopen_gensio_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/errtrig.h0000664000175000017500000000127014664224267011073 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2020 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* * Test code to trigger errors at specific counts. See errtrig.c for details. */ #ifndef _GENSIO_ERRTRIG_H #define _GENSIO_ERRTRIG_H #include "config.h" #include #include #include #ifdef ENABLE_INTERNAL_TRACE #define ENABLE_ERRTRIG_TEST #endif #ifdef ENABLE_ERRTRIG_TEST GENSIOOSH_DLL_PUBLIC bool do_errtrig(void); GENSIOOSH_DLL_PUBLIC void errtrig_exit(int rv); #else #define do_errtrig() false #define errtrig_exit(rv) exit(rv) #endif #endif /* _GENSIO_ERRTRIG_H */ gensio-3.0.0/lib/sergensio_telnet.c0000664000175000017500000020065215045153771012761 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include #include #include "utils.h" #include "telnet.h" struct gensio_telnet_filter_callbacks { void (*got_sync)(void *handler_data); void (*got_cmd)(void *handler_data, unsigned char cmd); int (*com_port_will_do)(void *handler_data, unsigned char cmd); void (*com_port_cmd)(void *handler_data, const unsigned char *option, unsigned int len); int (*rfc1073_will_do)(void *handler_data, unsigned char cmd); void (*rfc1073_cmd)(void *handler_data, const unsigned char *option, unsigned int len); void (*timeout)(void *handler_data); void (*free)(void *handler_data); int (*control)(void *handler_data, bool get, int option, char *data, gensiods *datalen); int (*acontrol)(void *hander_data, bool get, int option, struct gensio_func_acontrol *data); }; struct gensio_telnet_filter_rops { void (*send_option)(struct gensio_filter *filter, const unsigned char *buf, unsigned int len); void (*send_cmd)(struct gensio_filter *filter, const unsigned char *buf, unsigned int len); void (*start_timer)(struct gensio_filter *filter, gensio_time *timeout); }; enum telnet_write_state { TELNET_NOT_WRITING, TELNET_IN_TN_WRITE, TELNET_IN_USER_WRITE }; struct telnet_filter { struct gensio_filter *filter; struct gensio_os_funcs *o; bool is_client; struct gensio_lock *lock; bool setup_done; int in_urgent; struct telnet_cmd *telnet_cmds; struct telnet_cmd *working_telnet_cmds; unsigned char *telnet_init_seq; unsigned int telnet_init_seq_len; bool allow_rfc2217; bool rfc2217_set; bool allow_rfc1073; bool rfc1073_set; bool rfc1073_enabled; gensio_time init_end_wait; const struct gensio_telnet_filter_callbacks *telnet_cbs; void *handler_data; gensio_filter_cb filter_cb; void *filter_cb_data; /* * To avoid problems with splitting TN_IACs, we do not split up * telnet chunks or user chunks. We use this to mark what we * are doing. */ enum telnet_write_state write_state; struct telnet_data_s tn_data; /* Data waiting to be delivered to the user. */ unsigned char *read_data; gensiods max_read_size; gensiods read_data_pos; gensiods read_data_len; /* Data waiting to be written. */ unsigned char *write_data; gensiods max_write_size; gensiods write_data_pos; gensiods write_data_len; }; #define filter_to_telnet(v) ((struct telnet_filter *) \ gensio_filter_get_user_data(v)) static void telnet_filter_send_cmd(struct gensio_filter *filter, const unsigned char *buf, unsigned int len); static void telnet_lock(struct telnet_filter *tfilter) { tfilter->o->lock(tfilter->lock); } static void telnet_unlock(struct telnet_filter *tfilter) { tfilter->o->unlock(tfilter->lock); } static void telnet_set_callbacks(struct gensio_filter *filter, gensio_filter_cb cb, void *cb_data) { struct telnet_filter *tfilter = filter_to_telnet(filter); struct gensio_filter_cb_control_data ctrl; gensiods datalen = 1; tfilter->filter_cb = cb; tfilter->filter_cb_data = cb_data; /* Enable OOB data, as we need it from TCP for proper mark handling. */ ctrl.depth = 0; ctrl.get = false; ctrl.option = GENSIO_CONTROL_ENABLE_OOB; ctrl.data = "1"; ctrl.datalen = &datalen; cb(cb_data, GENSIO_FILTER_CB_CONTROL, &ctrl); } static bool telnet_ul_read_pending(struct gensio_filter *filter) { struct telnet_filter *tfilter = filter_to_telnet(filter); bool rv; telnet_lock(tfilter); rv = tfilter->read_data_len; telnet_unlock(tfilter); return rv; } static bool telnet_ll_write_pending(struct gensio_filter *filter) { struct telnet_filter *tfilter = filter_to_telnet(filter); bool rv; telnet_lock(tfilter); rv = tfilter->write_data_len || gensio_buffer_cursize(&tfilter->tn_data.out_telnet_cmd); telnet_unlock(tfilter); return rv; } static void telnet_clear_write(struct telnet_filter *tfilter) { tfilter->write_data_len = 0; gensio_buffer_reset(&tfilter->tn_data.out_telnet_cmd); } static bool telnet_ll_read_needed(struct gensio_filter *filter) { struct telnet_filter *tfilter = filter_to_telnet(filter); return ((tfilter->allow_rfc2217 && !tfilter->rfc2217_set) || (tfilter->allow_rfc1073 && !tfilter->rfc1073_set)); } static int telnet_check_open_done(struct gensio_filter *filter, struct gensio *io) { return 0; } static int telnet_try_connect(struct gensio_filter *filter, gensio_time *timeout) { struct telnet_filter *tfilter = filter_to_telnet(filter); gensio_time now; if (tfilter->rfc2217_set && tfilter->rfc1073_set) return 0; tfilter->o->get_monotonic_time(tfilter->o, &now); if (gensio_time_cmp(&now, &tfilter->init_end_wait) > 0) { tfilter->rfc2217_set = true; tfilter->rfc1073_set = true; return 0; } timeout->secs = 0; timeout->nsecs = 500000000; return GE_RETRY; } static int telnet_try_disconnect(struct gensio_filter *filter, gensio_time *timeout) { return 0; } struct telnet_buffer_data { gensio_ul_filter_data_handler handler; void *cb_data; const char *const *auxdata; }; static int telnet_buffer_do_write(void *cb_data, void *buf, unsigned int buflen, unsigned int *written) { struct telnet_buffer_data *data = cb_data; gensiods count; struct gensio_sg sg = { buf, buflen }; int err; err = data->handler(data->cb_data, &count, &sg, 1, data->auxdata); if (!err) *written = count; return err; } static int telnet_ul_write(struct gensio_filter *filter, gensio_ul_filter_data_handler handler, void *cb_data, gensiods *rcount, const struct gensio_sg *isg, gensiods sglen, const char *const *auxdata) { struct telnet_filter *tfilter = filter_to_telnet(filter); int err = 0; telnet_lock(tfilter); if (tfilter->write_data_len) { if (rcount) *rcount = 0; } else { gensiods i, writelen = 0; for (i = 0; i < sglen; i++) { size_t inlen = isg[i].buflen; const unsigned char *buf = isg[i].buf; tfilter->write_data_len = process_telnet_xmit(tfilter->write_data, tfilter->max_write_size, &buf, &inlen); writelen += isg[i].buflen - inlen; if (inlen != isg[i].buflen) break; } if (rcount) *rcount = writelen; } if (tfilter->write_state != TELNET_IN_USER_WRITE && gensio_buffer_cursize(&tfilter->tn_data.out_telnet_cmd)) { struct telnet_buffer_data data = { handler, cb_data, auxdata }; err = gensio_buffer_write(telnet_buffer_do_write, &data, &tfilter->tn_data.out_telnet_cmd); if (err) { telnet_clear_write(tfilter); } else { if (gensio_buffer_cursize(&tfilter->tn_data.out_telnet_cmd)) tfilter->write_state = TELNET_IN_TN_WRITE; else tfilter->write_state = TELNET_NOT_WRITING; } } if (tfilter->write_state != TELNET_IN_TN_WRITE && tfilter->write_data_len) { gensiods count = 0; struct gensio_sg sg = { tfilter->write_data + tfilter->write_data_pos, tfilter->write_data_len }; err = handler(cb_data, &count, &sg, 1, auxdata); if (err) { telnet_clear_write(tfilter); } else { if (count >= tfilter->write_data_len) { tfilter->write_state = TELNET_NOT_WRITING; tfilter->write_data_len = 0; tfilter->write_data_pos = 0; } else { tfilter->write_state = TELNET_IN_USER_WRITE; tfilter->write_data_len -= count; tfilter->write_data_pos += count; } } } telnet_unlock(tfilter); return err; } static int telnet_ll_write(struct gensio_filter *filter, gensio_ll_filter_data_handler handler, void *cb_data, gensiods *rcount, unsigned char *buf, gensiods buflen, const char *const *auxdata) { struct telnet_filter *tfilter = filter_to_telnet(filter); int err = 0; telnet_lock(tfilter); if (gensio_str_in_auxdata(auxdata, "oobtcp")) { /* * Just ignore OOB data, but set that we are looking for a * telnet mark. In some cases the IAC comes before the data * mark (so telnet_cmd_pos == 1), so we have to have a hack * for that. */ if (tfilter->tn_data.telnet_cmd_pos == 1) tfilter->in_urgent = 2; else tfilter->in_urgent = 1; /* Abandon any command handling on a sync. */ tfilter->tn_data.telnet_cmd_pos = 0; } else if (gensio_str_in_auxdata(auxdata, "oob")) { /* Ignore other oob data. */ if (rcount) *rcount = buflen; goto out_unlock; } if (tfilter->read_data_len || buflen == 0) { if (rcount) *rcount = 0; } else { unsigned int inlen = buflen, proclen; if (tfilter->in_urgent) { /* We are in urgent data, just read until we get a mark. */ for (; inlen > 0; inlen--, buf++) { if (tfilter->in_urgent == 2) { if (*buf == TN_DATA_MARK) { /* Found it. */ tfilter->in_urgent = 0; if (tfilter->telnet_cbs && tfilter->telnet_cbs->got_sync) { telnet_unlock(tfilter); tfilter->telnet_cbs->got_sync (tfilter->handler_data); telnet_lock(tfilter); } break; } tfilter->in_urgent = 1; } else if (*buf == TN_IAC) { tfilter->in_urgent = 2; } } } /* * Process the telnet receive data unlocked. It can do callbacks to * the users, and we are guaranteed to be single-threaded in the * data handling here. */ telnet_unlock(tfilter); proclen = process_telnet_data(tfilter->read_data + tfilter->read_data_len, tfilter->max_read_size - tfilter->read_data_len, &buf, &inlen, &tfilter->tn_data); telnet_lock(tfilter); tfilter->read_data_len += proclen; if (rcount) *rcount = buflen - inlen; } if (tfilter->read_data_len) { gensiods count = 0; telnet_unlock(tfilter); err = handler(cb_data, &count, tfilter->read_data + tfilter->read_data_pos, tfilter->read_data_len, NULL); telnet_lock(tfilter); if (!err) { if (count >= tfilter->read_data_len) { tfilter->read_data_len = 0; tfilter->read_data_pos = 0; } else { tfilter->read_data_len -= count; tfilter->read_data_pos += count; } } } out_unlock: telnet_unlock(tfilter); return err; } static int com_port_will_do(void *cb_data, unsigned char cmd) { struct telnet_filter *tfilter = cb_data; int err = 0; if (tfilter->telnet_cbs) err = tfilter->telnet_cbs->com_port_will_do(tfilter->handler_data, cmd); tfilter->rfc2217_set = true; return err; } static void com_port_handler(void *cb_data, unsigned char *option, int len) { struct telnet_filter *tfilter = cb_data; if (tfilter->telnet_cbs) tfilter->telnet_cbs->com_port_cmd(tfilter->handler_data, option, len); } static int rfc1073_will_do(void *cb_data, unsigned char cmd) { struct telnet_filter *tfilter = cb_data; int err = 0; if (tfilter->telnet_cbs) err = tfilter->telnet_cbs->rfc1073_will_do(tfilter->handler_data, cmd); tfilter->rfc1073_set = true; tfilter->rfc1073_enabled = !!err; return err; } static void rfc1073_handler(void *cb_data, unsigned char *option, int len) { struct telnet_filter *tfilter = cb_data; if (tfilter->telnet_cbs) tfilter->telnet_cbs->rfc1073_cmd(tfilter->handler_data, option, len); } static void telnet_output_ready(void *cb_data) { struct telnet_filter *tfilter = cb_data; if (tfilter->setup_done && tfilter->filter_cb) tfilter->filter_cb(tfilter->filter_cb_data, GENSIO_FILTER_CB_OUTPUT_READY, NULL); } static void telnet_cmd_handler(void *cb_data, unsigned char cmd) { struct telnet_filter *tfilter = cb_data; if (tfilter->telnet_cbs && tfilter->telnet_cbs->got_cmd) tfilter->telnet_cbs->got_cmd(tfilter->handler_data, cmd); } static struct telnet_cmd * telnet_cmds_copy(struct gensio_os_funcs *o, const struct telnet_cmd *in) { unsigned int i; struct telnet_cmd *out; for (i = 0; in[i].option != TELNET_CMD_END_OPTION; i++) ; i++; out = o->zalloc(o, i * sizeof(*out)); if (!out) return NULL; memcpy(out, in, i * sizeof(*out)); return out; } static int telnet_setup(struct gensio_filter *filter) { struct telnet_filter *tfilter = filter_to_telnet(filter); struct telnet_cmd *cmds; cmds = telnet_cmds_copy(tfilter->o, tfilter->telnet_cmds); if (!cmds) return GE_NOMEM; if (tfilter->working_telnet_cmds) tfilter->o->free(tfilter->o, tfilter->working_telnet_cmds); tfilter->working_telnet_cmds = cmds; telnet_init(&tfilter->tn_data, tfilter, telnet_output_ready, telnet_cmd_handler, cmds, tfilter->telnet_init_seq, tfilter->telnet_init_seq_len); tfilter->rfc2217_set = !tfilter->allow_rfc2217; tfilter->rfc1073_set = !tfilter->allow_rfc1073; if (!tfilter->rfc2217_set || !tfilter->rfc1073_set) { tfilter->o->get_monotonic_time(tfilter->o, &tfilter->init_end_wait); tfilter->init_end_wait.secs += 4; /* FIXME - magic number */ tfilter->setup_done = true; if (gensio_buffer_cursize(&tfilter->tn_data.out_telnet_cmd)) tfilter->write_state = TELNET_IN_TN_WRITE; else tfilter->write_state = TELNET_NOT_WRITING; } return 0; } static void telnet_filter_cleanup(struct gensio_filter *filter) { struct telnet_filter *tfilter = filter_to_telnet(filter); tfilter->setup_done = false; tfilter->in_urgent = 0; tfilter->read_data_len = 0; tfilter->read_data_pos = 0; tfilter->write_data_len = 0; tfilter->write_data_pos = 0; telnet_cleanup(&tfilter->tn_data); } static void telnet_filter_timeout(struct gensio_filter *filter) { struct telnet_filter *tfilter = filter_to_telnet(filter); if (tfilter->telnet_cbs && tfilter->telnet_cbs->timeout) tfilter->telnet_cbs->timeout(tfilter->handler_data); } static void tfilter_free(struct telnet_filter *tfilter) { if (tfilter->lock) tfilter->o->free_lock(tfilter->lock); if (tfilter->telnet_cmds) tfilter->o->free(tfilter->o, tfilter->telnet_cmds); if (tfilter->working_telnet_cmds) tfilter->o->free(tfilter->o, tfilter->working_telnet_cmds); if (tfilter->telnet_init_seq) tfilter->o->free(tfilter->o, tfilter->telnet_init_seq); if (tfilter->read_data) tfilter->o->free(tfilter->o, tfilter->read_data); if (tfilter->write_data) tfilter->o->free(tfilter->o, tfilter->write_data); if (tfilter->telnet_cbs) tfilter->telnet_cbs->free(tfilter->handler_data); if (tfilter->filter) gensio_filter_free_data(tfilter->filter); telnet_cleanup(&tfilter->tn_data); tfilter->o->free(tfilter->o, tfilter); } static void telnet_free(struct gensio_filter *filter) { struct telnet_filter *tfilter = filter_to_telnet(filter); tfilter_free(tfilter); } static int telnet_filter_control(struct gensio_filter *filter, bool get, int op, char *data, gensiods *datalen) { struct telnet_filter *tfilter = filter_to_telnet(filter); unsigned char buf[9]; unsigned int width, height; int rv; if (get) return GE_NOTSUP; switch (op) { case GENSIO_CONTROL_SEND_BREAK: buf[0] = TN_IAC; buf[1] = TN_BREAK; telnet_filter_send_cmd(filter, buf, 2); return 0; case GENSIO_CONTROL_WIN_SIZE: if (!tfilter->rfc1073_enabled) return GE_NOTSUP; buf[0] = TN_IAC; buf[1] = TN_SB; buf[2] = TN_OPT_NAWS; rv = sscanf(data, "%u:%u", &height, &width); if (rv != 2) return GE_INVAL; buf[3] = width >> 8; buf[4] = width; buf[5] = height >> 8; buf[6] = height; buf[7] = TN_IAC; buf[8] = TN_SE; telnet_filter_send_cmd(filter, buf, 9); return 0; default: if (tfilter->telnet_cbs->control) return tfilter->telnet_cbs->control(tfilter->handler_data, get, op, data, datalen); return GE_NOTSUP; } } static int telnet_filter_acontrol(struct gensio_filter *filter, bool get, int op, struct gensio_func_acontrol *data) { struct telnet_filter *tfilter = filter_to_telnet(filter); if (tfilter->telnet_cbs->acontrol) return tfilter->telnet_cbs->acontrol(tfilter->handler_data, get, op, data); return GE_NOTSUP; } static int gensio_telnet_filter_func(struct gensio_filter *filter, int op, void *func, void *data, gensiods *count, void *buf, const void *cbuf, gensiods buflen, const char *const *auxdata) { switch (op) { case GENSIO_FILTER_FUNC_SET_CALLBACK: telnet_set_callbacks(filter, func, data); return 0; case GENSIO_FILTER_FUNC_UL_READ_PENDING: return telnet_ul_read_pending(filter); case GENSIO_FILTER_FUNC_LL_WRITE_PENDING: return telnet_ll_write_pending(filter); case GENSIO_FILTER_FUNC_LL_READ_NEEDED: return telnet_ll_read_needed(filter); case GENSIO_FILTER_FUNC_CHECK_OPEN_DONE: return telnet_check_open_done(filter, data); case GENSIO_FILTER_FUNC_TRY_CONNECT: return telnet_try_connect(filter, data); case GENSIO_FILTER_FUNC_TRY_DISCONNECT: return telnet_try_disconnect(filter, data); case GENSIO_FILTER_FUNC_UL_WRITE_SG: return telnet_ul_write(filter, func, data, count, cbuf, buflen, auxdata); case GENSIO_FILTER_FUNC_LL_WRITE: return telnet_ll_write(filter, func, data, count, buf, buflen, auxdata); case GENSIO_FILTER_FUNC_SETUP: return telnet_setup(filter); case GENSIO_FILTER_FUNC_CLEANUP: telnet_filter_cleanup(filter); return 0; case GENSIO_FILTER_FUNC_FREE: telnet_free(filter); return 0; case GENSIO_FILTER_FUNC_TIMEOUT: telnet_filter_timeout(filter); return 0; case GENSIO_FILTER_FUNC_CONTROL: return telnet_filter_control(filter, *((bool *) cbuf), buflen, data, count); case GENSIO_FILTER_FUNC_ACONTROL: return telnet_filter_acontrol(filter, *((bool *) cbuf), buflen, data); default: return GE_NOTSUP; } } static void telnet_filter_send_option(struct gensio_filter *filter, const unsigned char *buf, unsigned int len) { struct telnet_filter *tfilter = filter_to_telnet(filter); telnet_lock(tfilter); telnet_send_option(&tfilter->tn_data, buf, len); tfilter->filter_cb(tfilter->filter_cb_data, GENSIO_FILTER_CB_OUTPUT_READY, NULL); telnet_unlock(tfilter); } static void telnet_filter_send_cmd(struct gensio_filter *filter, const unsigned char *buf, unsigned int len) { struct telnet_filter *tfilter = filter_to_telnet(filter); telnet_lock(tfilter); telnet_cmd_send(&tfilter->tn_data, buf, len); tfilter->filter_cb(tfilter->filter_cb_data, GENSIO_FILTER_CB_OUTPUT_READY, NULL); telnet_unlock(tfilter); } static void telnet_filter_start_timer(struct gensio_filter *filter, gensio_time *timeout) { struct telnet_filter *tfilter = filter_to_telnet(filter); tfilter->filter_cb(tfilter->filter_cb_data, GENSIO_FILTER_CB_START_TIMER, timeout); } const struct gensio_telnet_filter_rops telnet_filter_rops = { .send_option = telnet_filter_send_option, .send_cmd = telnet_filter_send_cmd, .start_timer = telnet_filter_start_timer }; static struct gensio_filter * gensio_telnet_filter_raw_alloc(struct gensio_os_funcs *o, bool is_client, bool allow_rfc2217, bool allow_rfc1073, gensiods max_read_size, gensiods max_write_size, const struct gensio_telnet_filter_callbacks *cbs, void *handler_data, struct telnet_cmd *telnet_cmds, unsigned char *telnet_init_seq, unsigned int telnet_init_seq_len, const struct gensio_telnet_filter_rops **rops) { struct telnet_filter *tfilter; tfilter = o->zalloc(o, sizeof(*tfilter)); if (!tfilter) return NULL; tfilter->o = o; tfilter->is_client = is_client; tfilter->allow_rfc2217 = allow_rfc2217; tfilter->allow_rfc1073 = allow_rfc1073; tfilter->max_write_size = max_write_size; tfilter->max_read_size = max_read_size; tfilter->telnet_cmds = telnet_cmds; tfilter->telnet_init_seq = telnet_init_seq; tfilter->telnet_init_seq_len = telnet_init_seq_len; tfilter->lock = o->alloc_lock(o); if (!tfilter->lock) goto out_nomem; tfilter->read_data = o->zalloc(o, max_read_size); if (!tfilter->read_data) goto out_nomem; tfilter->write_data = o->zalloc(o, max_write_size); if (!tfilter->write_data) goto out_nomem; *rops = &telnet_filter_rops; tfilter->filter = gensio_filter_alloc_data(o, gensio_telnet_filter_func, tfilter); if (!tfilter->filter) goto out_nomem; tfilter->telnet_cbs = cbs; tfilter->handler_data = handler_data; return tfilter->filter; out_nomem: tfilter_free(tfilter); return NULL; } static struct telnet_cmd telnet_server_cmds[] = { /* I will, I do, sent will, sent do */ { TN_OPT_SUPPRESS_GO_AHEAD, 1, 1, 1, 1, }, { TN_OPT_ECHO, 1, 0, 1, 1, }, { TN_OPT_BINARY_TRANSMISSION, 1, 1, 1, 1, }, #define SERV_COM_PORT_POS 3 { TN_OPT_COM_PORT, 0, 0, 0, 0, }, #define SERV_RFC1073_POS 4 { TN_OPT_NAWS, 0, 0, 0, 0, }, { TELNET_CMD_END_OPTION } }; static unsigned char telnet_server_init_seq[] = { TN_IAC, TN_WILL, TN_OPT_SUPPRESS_GO_AHEAD, TN_IAC, TN_DO, TN_OPT_SUPPRESS_GO_AHEAD, TN_IAC, TN_WILL, TN_OPT_ECHO, TN_IAC, TN_DONT, TN_OPT_ECHO, TN_IAC, TN_DO, TN_OPT_BINARY_TRANSMISSION, TN_IAC, TN_WILL, TN_OPT_BINARY_TRANSMISSION, }; static unsigned char telnet_server_rfc2217_seq[] = { TN_IAC, TN_DO, TN_OPT_COM_PORT, }; static unsigned char telnet_server_rfc1073_seq[] = { TN_IAC, TN_DO, TN_OPT_NAWS, }; static const struct telnet_cmd telnet_client_cmds[] = { /* I will, I do, sent will, sent do */ { TN_OPT_SUPPRESS_GO_AHEAD, 1, 0, 0, 0, }, { TN_OPT_ECHO, 1, 0, 0, 0, }, { TN_OPT_BINARY_TRANSMISSION, 1, 1, 0, 0, }, #define CLIENT_COM_PORT_POS 3 { TN_OPT_COM_PORT, 0, 0, 0, 0, }, #define CLIENT_RFC1073_POS 4 { TN_OPT_NAWS, 0, 0, 0, 0, }, { TELNET_CMD_END_OPTION } }; static const unsigned char telnet_client_rfc2217_seq[] = { TN_IAC, TN_WILL, TN_OPT_COM_PORT, }; static const unsigned char telnet_client_rfc1073_seq[] = { TN_IAC, TN_WILL, TN_OPT_NAWS, }; static int gensio_telnet_filter_alloc(struct gensio_pparm_info *p, struct gensio_os_funcs *o, const char * const args[], bool default_is_client, const struct gensio_telnet_filter_callbacks *cbs, void *handler_data, const struct gensio_telnet_filter_rops **rops, struct gensio_base_parms *parms, struct gensio_filter **rfilter) { struct gensio_filter *filter; unsigned int i; gensiods max_read_size = 4096; /* FIXME - magic number. */ gensiods max_write_size = 4096; /* FIXME - magic number. */ bool allow_rfc2217 = false; bool allow_rfc1073 = false; bool is_client = default_is_client; struct telnet_cmd *telnet_cmds = NULL; unsigned char *init_seq = NULL; unsigned int init_seq_len, pos; int rv, ival; char *str; rv = gensio_get_default(o, "telnet", "rfc2217", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (rv) return rv; allow_rfc2217 = ival; rv = gensio_get_default(o, "telnet", "winsize", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (rv) return rv; allow_rfc1073 = ival; rv = gensio_get_default(o, "telnet", "mode", false, GENSIO_DEFAULT_STR, &str, NULL); if (rv) { gensio_log(o, GENSIO_LOG_ERR, "Failed getting telnet mode: %s", gensio_err_to_str(rv)); return rv; } if (str) { if (strcasecmp(str, "client") == 0) is_client = true; else if (strcasecmp(str, "server") == 0) is_client = false; else { gensio_log(o, GENSIO_LOG_ERR, "Unknown default telnet mode (%s), ignoring", str); } o->free(o, str); } for (i = 0; args && args[i]; i++) { if (gensio_pparm_bool(p, args[i], "rfc2217", &allow_rfc2217) > 0) continue; if (gensio_pparm_bool(p, args[i], "winsize", &allow_rfc1073) > 0) continue; if (gensio_pparm_ds(p, args[i], "writebuf", &max_write_size) > 0) continue; if (gensio_pparm_ds(p, args[i], "readbuf", &max_read_size) > 0) continue; if (gensio_pparm_boolv(p, args[i], "mode", "client", "server", &is_client) > 0) continue; if (parms && gensio_base_parm(parms, p, args[i]) > 0) continue; gensio_pparm_unknown_parm(p, args[i]); return GE_INVAL; } if (is_client) { telnet_cmds = o->zalloc(o, sizeof(telnet_client_cmds)); if (!telnet_cmds) goto out_nomem; memcpy(telnet_cmds, telnet_client_cmds, sizeof(telnet_client_cmds)); init_seq_len = 0; if (allow_rfc2217) { telnet_cmds[CLIENT_COM_PORT_POS].i_will = 1; telnet_cmds[CLIENT_COM_PORT_POS].sent_will = 1; telnet_cmds[CLIENT_COM_PORT_POS].option_handler = com_port_handler; telnet_cmds[CLIENT_COM_PORT_POS].will_do_handler = com_port_will_do; init_seq_len += 3; } if (allow_rfc1073) { telnet_cmds[CLIENT_RFC1073_POS].i_will = 1; telnet_cmds[CLIENT_RFC1073_POS].sent_will = 1; telnet_cmds[CLIENT_RFC1073_POS].option_handler = rfc1073_handler; telnet_cmds[CLIENT_RFC1073_POS].will_do_handler = rfc1073_will_do; init_seq_len += 3; } if (init_seq_len != 0) { init_seq = o->zalloc(o, init_seq_len); if (!init_seq) goto out_nomem; pos = 0; if (allow_rfc2217) { memcpy(init_seq + pos, telnet_client_rfc2217_seq, 3); pos += 3; } if (allow_rfc1073) { memcpy(init_seq + pos, telnet_client_rfc1073_seq, 3); pos += 3; } } } else { telnet_cmds = o->zalloc(o, sizeof(telnet_server_cmds)); if (!telnet_cmds) goto out_nomem; memcpy(telnet_cmds, telnet_server_cmds, sizeof(telnet_server_cmds)); init_seq_len = sizeof(telnet_server_init_seq); if (allow_rfc2217) { telnet_cmds[SERV_COM_PORT_POS].option_handler = com_port_handler; telnet_cmds[SERV_COM_PORT_POS].will_do_handler = com_port_will_do; init_seq_len += 3; } if (allow_rfc1073) { telnet_cmds[SERV_RFC1073_POS].option_handler = rfc1073_handler; telnet_cmds[SERV_RFC1073_POS].will_do_handler = rfc1073_will_do; init_seq_len += 3; } init_seq = o->zalloc(o, init_seq_len); if (!init_seq) goto out_nomem; pos = 0; memcpy(init_seq + pos, telnet_server_init_seq, sizeof(telnet_server_init_seq)); pos += sizeof(telnet_server_init_seq); if (allow_rfc2217) { memcpy(init_seq + pos, telnet_server_rfc2217_seq, 3); pos += 3; } if (allow_rfc1073) { memcpy(init_seq + pos, telnet_server_rfc1073_seq, 3); pos += 3; } } filter = gensio_telnet_filter_raw_alloc(o, is_client, allow_rfc2217, allow_rfc1073, max_read_size, max_write_size, cbs, handler_data, telnet_cmds, init_seq, init_seq_len, rops); if (!filter) goto out_nomem; *rfilter = filter; return 0; out_nomem: if (init_seq) o->free(o, init_seq); if (telnet_cmds) o->free(o, telnet_cmds); return GE_NOMEM; } #define SERCTL_WAIT_TIME 5 struct stel_xlat_str { const char *sval; int ival; }; struct stel_req { int option; int minval; int maxval; gensio_control_done cdone; const struct stel_xlat_str *xlatstr; void *cb_data; int time_left; struct stel_req *next; }; struct stel_data { struct gensio *io; struct gensio_os_funcs *o; struct gensio_filter *filter; const struct gensio_telnet_filter_rops *rops; struct gensio_lock *lock; bool allow_rfc2217; bool do_rfc2217; bool allow_rfc1073; bool do_rfc1073; bool cisco_baud; bool reported_modemstate; bool is_client; struct stel_req *reqs; }; static struct cisco_baud_rates_s { int real_rate; int cisco_ios_val; } cisco_baud_rates[] = { { 300, 3 }, { 600 , 4}, { 1200, 5 }, { 2400, 6 }, { 4800, 7 }, { 9600, 8 }, { 19200, 10 }, { 38400, 12 }, { 57600, 13 }, { 115200, 14 }, { 230400, 15 }, }; #define CISCO_BAUD_RATES_LEN \ ((sizeof(cisco_baud_rates) / sizeof(struct cisco_baud_rates_s))) /* * Convert a Cisco version RFC2217 baud rate to an integer baud rate. * Returns 0 if unsuccessful. */ static int cisco_baud_to_baud(int cisco_val) { unsigned int i; for (i = 0; i < CISCO_BAUD_RATES_LEN; i++) { if (cisco_val == cisco_baud_rates[i].cisco_ios_val) return cisco_baud_rates[i].real_rate; } return 0; } /* * Convert an integer baud rate to a Cisco version RFC2217 baud rate. * Returns 0 if unsuccessful. */ static int baud_to_cisco_baud(int val) { unsigned int i; for (i = 0; i < CISCO_BAUD_RATES_LEN; i++) { if (val == cisco_baud_rates[i].real_rate) return cisco_baud_rates[i].cisco_ios_val; } return 0; } static void stel_lock(struct stel_data *sdata) { sdata->o->lock(sdata->lock); } static void stel_unlock(struct stel_data *sdata) { sdata->o->unlock(sdata->lock); } static int stel_queue(struct stel_data *sdata, int option, int minval, int maxval, gensio_control_done cdone, const struct stel_xlat_str *xlatstr, void *cb_data, gensio_time *timeout) { struct stel_req *curr, *req; gensio_time ntimeout; if (!sdata->do_rfc2217) return GE_NOTSUP; req = sdata->o->zalloc(sdata->o, sizeof(*req)); if (!req) return GE_NOMEM; req->option = option; req->cdone = cdone; req->xlatstr = xlatstr; req->cb_data = cb_data; req->minval = minval; if (!maxval) maxval = INT_MAX; req->maxval = maxval; if (timeout) { req->time_left = timeout->secs; if (timeout->nsecs > 0) req->time_left++; } else { req->time_left = SERCTL_WAIT_TIME; } req->next = NULL; stel_lock(sdata); curr = sdata->reqs; if (!curr) { sdata->reqs = req; } else { while (curr->next) curr = curr->next; curr->next = req; } stel_unlock(sdata); ntimeout.secs = 1; ntimeout.nsecs = 0; sdata->rops->start_timer(sdata->filter, &ntimeout); return 0; } static int stel_baud(struct stel_data *sdata, int baud, const char *sbaud, gensio_control_done cdone, void *cb_data, gensio_time *timeout) { bool is_client = gensio_is_client(sdata->io); unsigned char buf[6]; int err; if (sbaud) baud = strtol(sbaud, NULL, 0); if (is_client) { err = stel_queue(sdata, 1, 0, 0, cdone, NULL, cb_data, timeout); if (err) return err; buf[1] = 1; } else { buf[1] = 101; } buf[0] = 44; if (sdata->cisco_baud) { buf[2] = baud_to_cisco_baud(baud); sdata->rops->send_option(sdata->filter, buf, 3); } else { buf[2] = baud >> 24; buf[3] = baud >> 16; buf[4] = baud >> 8; buf[5] = baud; sdata->rops->send_option(sdata->filter, buf, 6); } return 0; } static int stel_queue_and_send(struct stel_data *sdata, int option, int val, const char *sval, int xmitbase, int minval, int maxval, gensio_control_done cdone, const struct stel_xlat_str *xlatstr, void *cb_data, gensio_time *timeout) { unsigned char buf[3]; bool is_client = gensio_is_client(sdata->io); int err; if (sval) { if (xlatstr) { unsigned int i; for (i = 0; xlatstr && xlatstr[i].sval; i++) { if (strcmp(xlatstr[i].sval, sval) == 0) { val = xlatstr[i].ival; goto found; } } return GE_INVAL; } else { val = strtoul(sval, NULL, 0); } } found: if (val < minval || val > maxval) return GE_INVAL; if (is_client) { err = stel_queue(sdata, option, xmitbase, xmitbase + maxval, cdone, xlatstr, cb_data, timeout); if (err) return err; } else { option += 100; } buf[0] = 44; buf[1] = option; buf[2] = val + xmitbase; sdata->rops->send_option(sdata->filter, buf, 3); return 0; } static int stel_datasize(struct stel_data *sdata, int datasize, const char *sdatasize, gensio_control_done cdone, void *cb_data, gensio_time *timeout) { return stel_queue_and_send(sdata, 2, datasize, sdatasize, 0, 0, 8, cdone, NULL, cb_data, timeout); } static const struct stel_xlat_str stel_parity_xlatstr[] = { { "0", 0 }, { "", 0 }, { "none", GENSIO_SER_PARITY_NONE }, { "odd", GENSIO_SER_PARITY_ODD }, { "even", GENSIO_SER_PARITY_EVEN }, { "mark", GENSIO_SER_PARITY_MARK }, { "space", GENSIO_SER_PARITY_SPACE }, {} }; static int stel_parity(struct stel_data *sdata, int parity, const char *sparity, gensio_control_done cdone, void *cb_data, gensio_time *timeout) { return stel_queue_and_send(sdata, 3, parity, sparity, 0, 0, 5, cdone, stel_parity_xlatstr, cb_data, timeout); } static int stel_stopbits(struct stel_data *sdata, int stopbits, const char *sstopbits, gensio_control_done cdone, void *cb_data, gensio_time *timeout) { return stel_queue_and_send(sdata, 4, stopbits, sstopbits, 0, 0, 3, cdone, NULL, cb_data, timeout); } static const struct stel_xlat_str stel_flow_xlatstr[] = { { "0", 0 }, { "", 0 }, { "none", GENSIO_SER_FLOWCONTROL_NONE }, { "xonxoff", GENSIO_SER_FLOWCONTROL_XON_XOFF }, { "rtscts", GENSIO_SER_FLOWCONTROL_RTS_CTS }, {} }; static int stel_flowcontrol(struct stel_data *sdata, int flowcontrol, const char *sflowcontrol, gensio_control_done cdone, void *cb_data, gensio_time *timeout) { return stel_queue_and_send(sdata, 5, flowcontrol, sflowcontrol, 0, 0, 3, cdone, stel_flow_xlatstr, cb_data, timeout); } static const struct stel_xlat_str stel_iflow_xlatstr[] = { { "0", 0 }, { "", 0 }, { "none", GENSIO_SER_FLOWCONTROL_NONE }, { "dcd", GENSIO_SER_FLOWCONTROL_DCD }, { "dtr", GENSIO_SER_FLOWCONTROL_DTR }, { "dsr", GENSIO_SER_FLOWCONTROL_DSR }, {} }; static int stel_iflowcontrol(struct stel_data *sdata, int iflowcontrol, const char *siflowcontrol, gensio_control_done cdone, void *cb_data, gensio_time *timeout) { return stel_queue_and_send(sdata, 5, iflowcontrol, siflowcontrol,13, 0, 6, cdone, stel_iflow_xlatstr, cb_data, timeout); } static const struct stel_xlat_str stel_on_off_xlatstr[] = { { "0", 0 }, { "", 0 }, { "on", GENSIO_SER_ON }, { "off", GENSIO_SER_OFF }, {} }; static int stel_sbreak(struct stel_data *sdata, int breakv, const char *sbreakv, gensio_control_done cdone, void *cb_data, gensio_time *timeout) { return stel_queue_and_send(sdata, 5, breakv, sbreakv, 4, 0, 2, cdone, stel_on_off_xlatstr, cb_data, timeout); } static int stel_dtr(struct stel_data *sdata, int dtr, const char *sdtr, gensio_control_done cdone, void *cb_data, gensio_time *timeout) { return stel_queue_and_send(sdata, 5, dtr, sdtr, 7, 0, 2, cdone, stel_on_off_xlatstr, cb_data, timeout); } static int stel_rts(struct stel_data *sdata, int rts, const char *srts, gensio_control_done cdone, void *cb_data, gensio_time *timeout) { return stel_queue_and_send(sdata, 5, rts, srts, 10, 0, 2, cdone, stel_on_off_xlatstr, cb_data, timeout); } static int stel_signature(struct stel_data *sdata, const char *sig, unsigned int sig_len, gensio_control_done cdone, void *cb_data, gensio_time *timeout) { unsigned char outopt[MAX_TELNET_CMD_XMIT_BUF]; bool is_client = gensio_is_client(sdata->io); if (sig_len > (MAX_TELNET_CMD_XMIT_BUF - 2)) sig_len = MAX_TELNET_CMD_XMIT_BUF - 2; if (is_client) { int err = stel_queue(sdata, 0, 0, 0, cdone, NULL, cb_data, timeout); if (err) return err; outopt[0] = 44; outopt[1] = 0; sdata->rops->send_option(sdata->filter, outopt, 2); } else { outopt[0] = 44; outopt[1] = 100; strncpy((char *) outopt + 2, sig, sig_len); sdata->rops->send_option(sdata->filter, outopt, sig_len + 2); } return 0; } static int stel_send(struct stel_data *sdata, unsigned int opt, unsigned int val) { unsigned char buf[3]; buf[0] = 44; buf[1] = opt; buf[2] = val; if (!gensio_is_client(sdata->io)) buf[1] += 100; sdata->rops->send_option(sdata->filter, buf, 3); return 0; } static int stel_modemstate(struct stel_data *sdata, unsigned int val, const char *sval) { unsigned int opt; if (sval) val = strtol(sval, NULL, 0); if (gensio_is_client(sdata->io)) opt = 11; else opt = 7; return stel_send(sdata, opt, val); } static int stel_linestate(struct stel_data *sdata, unsigned int val, const char *sval) { unsigned int opt; if (sval) val = strtol(sval, NULL, 0); if (gensio_is_client(sdata->io)) opt = 10; else opt = 6; return stel_send(sdata, opt, val); } static int stel_send_modemstate(struct stel_data *sdata, unsigned int val, const char *sval) { if (sval) val = strtol(sval, NULL, 0); return stel_send(sdata, 7, val); } static int stel_set_modemstate_mask(struct stel_data *sdata, unsigned int val, const char *sval, gensio_control_done cdone, void *cb_data, gensio_time *timeout) { if (sval) val = strtol(sval, NULL, 0); return stel_queue_and_send(sdata, 11, val, NULL, 0, 0, 255, cdone, NULL, cb_data, timeout); } static int stel_send_linestate(struct stel_data *sdata, unsigned int val, const char *sval) { if (sval) val = strtol(sval, NULL, 0); return stel_send(sdata, 6, val); } static int stel_set_linestate_mask(struct stel_data *sdata, unsigned int val, const char *sval, gensio_control_done cdone, void *cb_data, gensio_time *timeout) { if (sval) val = strtol(sval, NULL, 0); return stel_queue_and_send(sdata, 10, val, NULL, 0, 0, 255, cdone, NULL, cb_data, timeout); } static int stel_flowcontrol_state(struct stel_data *sdata, bool val, const char *sval) { unsigned char buf[2]; if (sval) { if (strcmp(sval, "true") == 0 || strcmp(sval, "on") == 0) val = true; else if (strcmp(sval, "false") == 0 || strcmp(sval, "off") == 0) val = false; else val = strtol(sval, NULL, 0); } buf[0] = 44; if (val) buf[1] = 8; else buf[1] = 9; if (!gensio_is_client(sdata->io)) buf[1] += 100; sdata->rops->send_option(sdata->filter, buf, 2); return 0; } static const struct stel_xlat_str stel_flush_xlatstr[] = { { "0", 0 }, { "", 0 }, { "recv", GENSIO_SER_FLUSH_RECV }, { "xmit", GENSIO_SER_FLUSH_XMIT }, { "both", GENSIO_SER_FLUSH_BOTH }, {} }; static int stel_flush(struct stel_data *sdata, unsigned int val, const char *sval, gensio_control_done cdone, void *cb_data, gensio_time *timeout) { return stel_queue_and_send(sdata, 12, val, sval, 0, 0, 3, cdone, stel_flush_xlatstr, cb_data, timeout); } static int stel_send_break(struct stel_data *sdata) { unsigned char buf[2]; buf[0] = TN_IAC; buf[1] = TN_BREAK; sdata->rops->send_cmd(sdata->filter, buf, 2); return 0; } static int stel_control(void *handler_data, bool get, int option, char *data, gensiods *datalen) { struct stel_data *sdata = handler_data; if (!gensio_is_serial(sdata->io)) return GE_NOTSUP; switch (option) { case GENSIO_CONTROL_SER_MODEMSTATE: return stel_modemstate(sdata, 0, data); case GENSIO_CONTROL_SER_LINESTATE: return stel_linestate(sdata, 0, data); case GENSIO_CONTROL_SER_SEND_MODEMSTATE: return stel_send_modemstate(sdata, 0, data); case GENSIO_CONTROL_SER_SEND_LINESTATE: return stel_send_linestate(sdata, 0, data); case GENSIO_CONTROL_SER_FLOWCONTROL_STATE: return stel_flowcontrol_state(sdata, 0, data); case GENSIO_CONTROL_SER_FLUSH: return stel_flush(sdata, 0, data, NULL, NULL, NULL); case GENSIO_CONTROL_SER_SEND_BREAK: return stel_send_break(sdata); default: return GE_NOTSUP; } } static int stel_acontrol(void *handler_data, bool get, int option, struct gensio_func_acontrol *idata) { struct stel_data *sdata = handler_data; const char *data = idata->data; gensio_control_done cdone = idata->done; void *cb_data = idata->cb_data; gensio_time *timeout = idata->timeout; gensiods datalen = idata->datalen; if (!gensio_is_serial(sdata->io)) return GE_NOTSUP; if (get) data = NULL; switch (option) { case GENSIO_ACONTROL_SER_BAUD: return stel_baud(sdata, 0, data, cdone, cb_data, timeout); case GENSIO_ACONTROL_SER_DATASIZE: return stel_datasize(sdata, 0, data, cdone, cb_data, timeout); case GENSIO_ACONTROL_SER_PARITY: return stel_parity(sdata, 0, data, cdone, cb_data, timeout); case GENSIO_ACONTROL_SER_STOPBITS: return stel_stopbits(sdata, 0, data, cdone, cb_data, timeout); case GENSIO_ACONTROL_SER_FLOWCONTROL: return stel_flowcontrol(sdata, 0, data, cdone, cb_data, timeout); case GENSIO_ACONTROL_SER_IFLOWCONTROL: return stel_iflowcontrol(sdata, 0, data, cdone, cb_data, timeout); case GENSIO_ACONTROL_SER_SBREAK: return stel_sbreak(sdata, 0, data, cdone, cb_data, timeout); case GENSIO_ACONTROL_SER_DTR: return stel_dtr(sdata, 0, data, cdone, cb_data, timeout); case GENSIO_ACONTROL_SER_RTS: return stel_rts(sdata, 0, data, cdone, cb_data, timeout); case GENSIO_ACONTROL_SER_FLUSH: return stel_flush(sdata, 0, data, cdone, cb_data, timeout); case GENSIO_ACONTROL_SER_SET_MODEMSTATE_MASK: return stel_set_modemstate_mask(sdata, 0, data, cdone, cb_data, timeout); case GENSIO_ACONTROL_SER_SET_LINESTATE_MASK: return stel_set_linestate_mask(sdata, 0, data, cdone, cb_data, timeout); case GENSIO_ACONTROL_SER_SIGNATURE: if (get) datalen = 0; return stel_signature(sdata, data, datalen, cdone, cb_data, timeout); default: return GE_NOTSUP; } } static int stelc_com_port_will_do(void *handler_data, unsigned char cmd) { struct stel_data *sdata = handler_data; if (cmd != TN_DO && cmd != TN_DONT) /* We only handle these. */ return 0; if (cmd == TN_DONT) /* The remote end turned off RFC2217 handling. */ sdata->do_rfc2217 = false; else sdata->do_rfc2217 = sdata->allow_rfc2217; return sdata->do_rfc2217; } static void stelc_com_port_cmd(void *handler_data, const unsigned char *option, unsigned int len) { struct stel_data *sdata = handler_data; int val = 0, cmd; struct stel_req *curr, *prev = NULL; char *sig = NULL; unsigned int sig_len; gensiods vlen = sizeof(int); struct gensio *io = sdata->io; if (len < 2) return; if (option[1] < 100) return; cmd = option[1] - 100; switch (cmd) { case 0: sig = (char *) (option + 2); sig_len = len - 2; break; case 1: if (len < 3) return; if (len < 6) { sdata->cisco_baud = true; val = cisco_baud_to_baud(option[2]); } else { val = option[2] << 24; val |= option[3] << 16; val |= option[4] << 8; val |= option[5]; } break; case 6: if (len < 3) return; val = option[2]; gensio_cb(io, GENSIO_EVENT_SER_LINESTATE, 0, (unsigned char *) &val, &vlen, NULL); return; case 7: if (len < 3) return; val = option[2]; gensio_cb(io, GENSIO_EVENT_SER_MODEMSTATE, 0, (unsigned char *) &val, &vlen, NULL); return; case 8: val = 1; gensio_cb(io, GENSIO_EVENT_SER_FLOW_STATE, 0, (unsigned char *) &val, &vlen, NULL); return; case 9: val = 0; gensio_cb(io, GENSIO_EVENT_SER_FLOW_STATE, 0, (unsigned char *) &val, &vlen, NULL); return; default: if (len < 3) return; val = option[2]; break; } stel_lock(sdata); curr = sdata->reqs; while (curr && !(curr->option == cmd && val >= curr->minval && val <= curr->maxval)) { prev = curr; curr = curr->next; } if (curr) { if (prev) prev->next = curr->next; else sdata->reqs = curr->next; } stel_unlock(sdata); if (curr) { if (curr->cdone) { if (sig) { curr->cdone(sdata->io, 0, sig, sig_len, curr->cb_data); } else { unsigned int i; const char *sval = NULL; char str[20]; val -= curr->minval; if (curr->xlatstr) { for (i = 0; curr->xlatstr[i].sval; i++) { if (val == curr->xlatstr[i].ival) { sval = curr->xlatstr[i].sval; break; } } } if (!sval) { snprintf(str, sizeof(str), "%d", val); sval = str; } curr->cdone(sdata->io, 0, sval, strlen(sval), curr->cb_data); } } sdata->o->free(sdata->o, curr); return; } } static int stelc_rfc1073_will_do(void *handler_data, unsigned char cmd) { struct stel_data *sdata = handler_data; if (cmd != TN_DO && cmd != TN_DONT) /* We only handle these. */ return 0; if (cmd == TN_DONT) /* The remote end turned off RFC1073 handling. */ sdata->do_rfc1073 = false; else sdata->do_rfc1073 = sdata->allow_rfc1073; return sdata->do_rfc1073; } static void stelc_rfc1073_cmd(void *handler_data, const unsigned char *option, unsigned int len) { /* We don't get these. */ } static void stelc_timeout(void *handler_data) { struct stel_data *sdata = handler_data; gensio_time timeout; struct stel_req *req, *curr, *prev = NULL, *to_complete = NULL; stel_lock(sdata); req = sdata->reqs; while (req) { if (--req->time_left == 0) { if (!prev) sdata->reqs = req->next; else prev->next = req->next; req->next = NULL; curr = to_complete; if (!curr) { to_complete = req; } else { while (curr->next) curr = curr->next; curr->next = req; } } else { prev = req; req = req->next; } } if (sdata->reqs) { timeout.secs = 1; timeout.nsecs = 0; sdata->rops->start_timer(sdata->filter, &timeout); } stel_unlock(sdata); req = to_complete; while (req) { if (req->cdone) req->cdone(sdata->io, GE_TIMEDOUT, NULL, 0, req->cb_data); prev = req; req = req->next; sdata->o->free(sdata->o, prev); } } static void stelc_got_sync(void *handler_data) { /* Nothing to do, break handling is only on the server side. */ } static void stel_free(void *handler_data) { struct stel_data *sdata = handler_data; if (sdata->lock) sdata->o->free_lock(sdata->lock); while (sdata->reqs) { struct stel_req *req = sdata->reqs; sdata->reqs = req->next; sdata->o->free(sdata->o, req); } sdata->o->free(sdata->o, sdata); } struct gensio_telnet_filter_callbacks sergensio_telnet_filter_cbs = { .got_sync = stelc_got_sync, .com_port_will_do = stelc_com_port_will_do, .com_port_cmd = stelc_com_port_cmd, .rfc1073_will_do = stelc_rfc1073_will_do, .rfc1073_cmd = stelc_rfc1073_cmd, .timeout = stelc_timeout, .free = stel_free, .control = stel_control, .acontrol = stel_acontrol }; static int stels_cb_com_port_will_do(void *handler_data, unsigned char cmd) { struct stel_data *sdata = handler_data; if (cmd != TN_WILL && cmd != TN_WONT) /* We only handle these. */ return 0; stel_lock(sdata); if (cmd == TN_WONT) /* The remote end turned off RFC2217 handling. */ sdata->do_rfc2217 = false; else sdata->do_rfc2217 = sdata->allow_rfc2217; if (!sdata->reported_modemstate && sdata->do_rfc2217) { struct gensio *io = sdata->io; if (gensio_get_cb(io)) { int val = 255; gensiods vlen = sizeof(val); sdata->reported_modemstate = true; gensio_cb(io, GENSIO_EVENT_SER_MODEMSTATE_MASK, 0, (unsigned char *) &val, &vlen, NULL); } else { gensio_time timeout; /* Schedule a modemstate report once the callbacks are set. */ timeout.secs = 0; timeout.nsecs = 1000000; sdata->rops->start_timer(sdata->filter, &timeout); } } stel_unlock(sdata); return sdata->do_rfc2217; } static void stels_cb_com_port_cmd(void *handler_data, const unsigned char *option, unsigned int len) { struct stel_data *sdata = handler_data; int val = 0; gensiods vlen = sizeof(int); struct gensio *io = sdata->io; if (len < 2) return; if (option[1] >= 100) return; switch (option[1]) { case 0: vlen = len - 2; gensio_cb(io, GENSIO_EVENT_SER_SIGNATURE, 0, (unsigned char *) (option + 2), &vlen, NULL); break; case 1: if (len < 3) return; if (len < 6) { sdata->cisco_baud = true; val = cisco_baud_to_baud(option[2]); } else { val = option[2] << 24; val |= option[3] << 16; val |= option[4] << 8; val |= option[5]; } gensio_cb(io, GENSIO_EVENT_SER_BAUD, 0, (unsigned char *) &val, &vlen, NULL); break; case 2: if (len < 3) return; val = option[2]; gensio_cb(io, GENSIO_EVENT_SER_DATASIZE, 0, (unsigned char *) &val, &vlen, NULL); break; case 3: if (len < 3) return; val = option[2]; gensio_cb(io, GENSIO_EVENT_SER_PARITY, 0, (unsigned char *) &val, &vlen, NULL); break; case 4: if (len < 3) return; val = option[2]; gensio_cb(io, GENSIO_EVENT_SER_STOPBITS, 0, (unsigned char *) &val, &vlen, NULL); break; case 5: if (len < 3) return; switch(option[2]) { case 0: case 1: case 2: case 3: val = option[2]; gensio_cb(io, GENSIO_EVENT_SER_FLOWCONTROL, 0, (unsigned char *) &val, &vlen, NULL); break; case 4: case 5: case 6: val = option[2] - 4; gensio_cb(io, GENSIO_EVENT_SER_SBREAK, 0, (unsigned char *) &val, &vlen, NULL); break; case 7: case 8: case 9: val = option[2] - 7; gensio_cb(io, GENSIO_EVENT_SER_DTR, 0, (unsigned char *) &val, &vlen, NULL); break; case 10: case 11: case 12: val = option[2] - 10; gensio_cb(io, GENSIO_EVENT_SER_RTS, 0, (unsigned char *) &val, &vlen, NULL); break; case 13: case 14: case 15: case 16: case 17: case 18: case 19: val = option[2] - 13; gensio_cb(io, GENSIO_EVENT_SER_IFLOWCONTROL, 0, (unsigned char *) &val, &vlen, NULL); } break; case 8: val = 1; gensio_cb(io, GENSIO_EVENT_SER_FLOWCONTROL, 0, (unsigned char *) &val, &vlen, NULL); break; case 9: val = 0; gensio_cb(io, GENSIO_EVENT_SER_FLOWCONTROL, 0, (unsigned char *) &val, &vlen, NULL); break; case 10: if (len < 3) return; val = option[2]; gensio_cb(io, GENSIO_EVENT_SER_LINESTATE_MASK, 0, (unsigned char *) &val, &vlen, NULL); break; case 11: if (len < 3) return; val = option[2]; gensio_cb(io, GENSIO_EVENT_SER_MODEMSTATE_MASK, 0, (unsigned char *) &val, &vlen, NULL); break; case 12: if (len < 3) return; val = option[2]; gensio_cb(io, GENSIO_EVENT_SER_FLUSH, 0, (unsigned char *) &val, &vlen, NULL); break; default: break; } } static int stels_cb_rfc1073_will_do(void *handler_data, unsigned char cmd) { struct stel_data *sdata = handler_data; if (cmd != TN_WILL && cmd != TN_WONT) /* We only handle these. */ return 0; if (cmd == TN_WONT) /* The remote end turned off RFC1073 handling. */ sdata->do_rfc1073 = false; else sdata->do_rfc1073 = sdata->allow_rfc1073; return sdata->do_rfc1073; } static void stels_cb_rfc1073_cmd(void *handler_data, const unsigned char *option, unsigned int len) { struct stel_data *sdata = handler_data; struct gensio *io = sdata->io; char buf[30]; gensiods buflen; unsigned int width, height; if (len < 5) return; option++; /* Skip the option number. */ width = (option[0] << 8) | option[1]; height = (option[2] << 8) | option[3]; buflen = snprintf(buf, sizeof(buf), "%u:%u", height, width); if (buflen >= sizeof(buf)) buflen = sizeof(buf) - 1; gensio_cb(io, GENSIO_EVENT_WIN_SIZE, 0, (unsigned char *) buf, &buflen, NULL); } static void stels_got_cmd(void *handler_data, unsigned char cmd) { struct stel_data *sdata = handler_data; struct gensio *io = sdata->io; if (cmd == TN_BREAK) gensio_cb(io, GENSIO_EVENT_SEND_BREAK, 0, NULL, NULL, NULL); } static void stels_cb_got_sync(void *handler_data) { struct stel_data *sdata = handler_data; struct gensio *io = sdata->io; gensio_cb(io, GENSIO_EVENT_SER_SYNC, 0, NULL, NULL, NULL); } static void stels_timeout(void *handler_data) { struct stel_data *sdata = handler_data; stel_lock(sdata); if (!sdata->reported_modemstate && sdata->do_rfc2217) { struct gensio *io = sdata->io; int val = 255; gensiods vlen = sizeof(val); if (gensio_get_cb(io)) { sdata->reported_modemstate = true; gensio_cb(io, GENSIO_EVENT_SER_MODEMSTATE_MASK, 0, (unsigned char *) &val, &vlen, NULL); } else { gensio_time timeout; timeout.secs = 0; timeout.nsecs = 1000000; sdata->rops->start_timer(sdata->filter, &timeout); } } stel_unlock(sdata); } struct gensio_telnet_filter_callbacks sergensio_telnet_server_filter_cbs = { .got_sync = stels_cb_got_sync, .got_cmd = stels_got_cmd, .com_port_will_do = stels_cb_com_port_will_do, .com_port_cmd = stels_cb_com_port_cmd, .rfc1073_will_do = stels_cb_rfc1073_will_do, .rfc1073_cmd = stels_cb_rfc1073_cmd, .timeout = stels_timeout, .free = stel_free, .control = stel_control, .acontrol = stel_acontrol }; static int stel_setup(struct gensio_pparm_info *p, const char * const args[], bool default_is_client, struct gensio_os_funcs *o, struct gensio_base_parms *parms, struct stel_data **rsdata) { struct stel_data *sdata; unsigned int i; bool allow_rfc2217 = false; bool allow_rfc1073 = false; bool is_client = default_is_client; int err; int rv, ival; rv = gensio_get_default(o, "telnet", "rfc2217", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (rv) return rv; allow_rfc2217 = ival; rv = gensio_get_default(o, "telnet", "winsize", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (rv) return rv; allow_rfc1073 = ival; for (i = 0; args && args[i]; i++) { if (gensio_pparm_bool(p, args[i], "rfc2217", &allow_rfc2217) > 0) continue; if (gensio_pparm_bool(p, args[i], "winsize", &allow_rfc1073) > 0) continue; if (gensio_pparm_boolv(p, args[i], "mode", "client", "server", &is_client) > 0) continue; /* Ignore everything else, the filter will handle it. */ } if (p->err) return GE_INVAL; sdata = o->zalloc(o, sizeof(*sdata)); if (!sdata) return GE_NOMEM; sdata->o = o; sdata->allow_rfc2217 = allow_rfc2217; sdata->allow_rfc1073 = allow_rfc1073; sdata->is_client = is_client; sdata->lock = o->alloc_lock(o); if (!sdata->lock) goto out_nomem; err = gensio_telnet_filter_alloc(p, o, args, true, (is_client ? &sergensio_telnet_filter_cbs : &sergensio_telnet_server_filter_cbs), sdata, &sdata->rops, parms, &sdata->filter); if (err) goto out_err; if (is_client) { sdata->reported_modemstate = true; } *rsdata = sdata; return 0; out_nomem: err = GE_NOMEM; out_err: /* Freeing the filter frees sdata. */ if (sdata->filter) gensio_filter_free(sdata->filter); else stel_free(sdata); return err; } static int telnet_gensio_alloc2(struct gensio *child, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio_base_parms *parms, struct gensio **rio) { struct stel_data *sdata; struct gensio_ll *ll = NULL; struct gensio *io = NULL; int err; GENSIO_DECLARE_PPGENSIO(p, o, cb, "telnet", user_data); if (!parms) { err = gensio_base_parms_alloc(o, true, "telnet", &parms); if (err) goto out_err2; } err = stel_setup(&p, args, true, o, parms, &sdata); if (err) goto out_err2; ll = gensio_gensio_ll_alloc(o, child); if (!ll) goto out_nomem; gensio_ref(child); /* So gensio_ll_free doesn't free the child if fail */ io = base_gensio_alloc(o, ll, sdata->filter, child, "telnet", cb, user_data); if (!io) goto out_nomem; err = gensio_base_parms_set(io, &parms); if (err) goto out_err; sdata->io = io; if (sdata->allow_rfc2217) gensio_set_is_serial(io, true); gensio_free(child); /* Lose the ref we acquired. */ gensio_set_is_client(io, sdata->is_client); *rio = io; return 0; out_nomem: err = GE_NOMEM; out_err: if (io) { gensio_free(io); } else { /* Freeing the filter frees sdata. */ if (sdata->filter) gensio_filter_free(sdata->filter); else stel_free(sdata); if (ll) gensio_ll_free(ll); } out_err2: if (parms) gensio_base_parms_free(&parms); return err; } static int telnet_gensio_alloc(struct gensio *child, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **rio) { return telnet_gensio_alloc2(child, args, o, cb, user_data, NULL, rio); } static int str_to_telnet_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct gensio *io2; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio(str, o, cb, user_data, &io2); if (err) return err; err = telnet_gensio_alloc(io2, args, o, cb, user_data, new_gensio); if (err) gensio_free(io2); return err; } struct stela_data { struct gensio_accepter *acc; gensiods max_read_size; gensiods max_write_size; struct gensio_os_funcs *o; gensio_accepter_event cb; void *user_data; bool allow_rfc2217; bool allow_rfc1073; bool is_client; }; static void stela_free(void *acc_data) { struct stela_data *stela = acc_data; /* stela->acc will be freed in the class callback. */ stela->o->free(stela->o, stela); } static int stela_alloc_gensio(void *acc_data, const char * const *iargs, struct gensio *child, struct gensio **rio) { struct stela_data *stela = acc_data; struct gensio_os_funcs *o = stela->o; const char *args[6] = { NULL, NULL, NULL, NULL, NULL, NULL }; char buf1[50], buf2[50]; unsigned int i; bool allow_rfc2217 = stela->allow_rfc2217; bool allow_rfc1073 = stela->allow_rfc1073; gensiods max_write_size = stela->max_write_size; gensiods max_read_size = stela->max_read_size; bool is_client = stela->is_client; struct gensio_base_parms *parms = NULL; GENSIO_DECLARE_PPACCEPTER(p, stela->o, stela->cb, "telnet", stela->user_data); parms = gensio_acc_base_parms_dup(stela->acc); if (!parms) return GE_NOMEM; for (i = 0; iargs && iargs[i]; i++) { if (gensio_pparm_bool(&p, iargs[i], "rfc2217", &allow_rfc2217) > 0) continue; if (gensio_pparm_bool(&p, iargs[i], "winsize", &allow_rfc1073) > 0) continue; if (gensio_pparm_ds(&p, iargs[i], "writebuf", &max_write_size) > 0) continue; if (gensio_pparm_ds(&p, iargs[i], "readbuf", &max_read_size) > 0) continue; if (gensio_pparm_boolv(&p, iargs[i], "mode", "client", "server", &is_client) > 0) continue; if (gensio_base_parm(parms, &p, iargs[i]) > 0) continue; gensio_pparm_unknown_parm(&p, iargs[i]); gensio_base_parms_free(&parms); return GE_INVAL; } i = 0; if (allow_rfc2217) args[i++] = "rfc2217=true"; if (allow_rfc1073) args[i++] = "winsize=true"; if (max_read_size != GENSIO_DEFAULT_BUF_SIZE) { snprintf(buf1, sizeof(buf1), "readbuf=%lu", (unsigned long) max_read_size); args[i++] = buf1; } if (max_write_size != GENSIO_DEFAULT_BUF_SIZE) { snprintf(buf2, sizeof(buf2), "writebuf=%lu", (unsigned long) max_write_size); args[i++] = buf2; } if (!is_client) args[i++] = "mode=server"; return telnet_gensio_alloc2(child, args, o, NULL, NULL, parms, rio); } static int stela_new_child(void *acc_data, void **finish_data, struct gensio_filter **filter, struct gensio *child) { struct stela_data *stela = acc_data; struct gensio_os_funcs *o = stela->o; struct stel_data *sdata; int err; char arg1[25], arg2[25], arg3[25], arg4[25], arg5[25]; const char *args[6] = { arg1, arg2, arg3, arg4, arg5, NULL }; GENSIO_DECLARE_PPACCEPTER(p, stela->o, stela->cb, "telnet", stela->user_data); snprintf(arg1, sizeof(arg1), "rfc2217=%d", stela->allow_rfc2217); snprintf(arg2, sizeof(arg2), "winsize=%d", stela->allow_rfc1073); snprintf(arg3, sizeof(arg3), "writebuf=%lu", (unsigned long) stela->max_write_size); snprintf(arg4, sizeof(arg4), "readbuf=%lu", (unsigned long) stela->max_read_size); snprintf(arg5, sizeof(arg5), "mode=%s", stela->is_client ? "client" : "server"); err = stel_setup(&p, args, false, o, NULL, &sdata); if (err) return err; *filter = sdata->filter; *finish_data = sdata; return 0; } static int stela_finish_parent(void *acc_data, void *finish_data, struct gensio *io, struct gensio *child) { struct stel_data *sdata = finish_data; struct stela_data *stela = acc_data; int err; err = gensio_acc_base_parms_apply(stela->acc, io); if (err) return err; sdata->io = io; if (sdata->allow_rfc2217) gensio_set_is_serial(io, true); gensio_set_is_client(io, sdata->is_client); return 0; } static int gensio_gensio_acc_telnet_cb(void *acc_data, int op, void *data1, void *data2, void *data3, const void *data4) { switch (op) { case GENSIO_GENSIO_ACC_ALLOC_GENSIO: return stela_alloc_gensio(acc_data, data4, data1, data2); case GENSIO_GENSIO_ACC_NEW_CHILD: return stela_new_child(acc_data, data1, data2, data3); case GENSIO_GENSIO_ACC_FINISH_PARENT: return stela_finish_parent(acc_data, data1, data2, data3); case GENSIO_GENSIO_ACC_FREE: stela_free(acc_data); return 0; default: return GE_NOTSUP; } } static int telnet_gensio_accepter_alloc(struct gensio_accepter *child, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **raccepter) { struct stela_data *stela; unsigned int i; gensiods max_read_size = GENSIO_DEFAULT_BUF_SIZE; gensiods max_write_size = GENSIO_DEFAULT_BUF_SIZE; bool allow_rfc2217 = false; bool allow_rfc1073 = false; bool is_client = false; struct gensio_accepter *accepter = NULL; int rv, ival; struct gensio_base_parms *parms; GENSIO_DECLARE_PPACCEPTER(p, o, cb, "telnet", user_data); rv = gensio_base_parms_alloc(o, true, "telnet", &parms); if (rv) goto out_err2; rv = gensio_get_default(o, "telnet", "rfc2217", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (rv) goto out_err2; allow_rfc2217 = ival; rv = gensio_get_default(o, "telnet", "winsize", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (rv) goto out_err2; allow_rfc1073 = ival; for (i = 0; args && args[i]; i++) { if (gensio_pparm_bool(&p, args[i], "rfc2217", &allow_rfc2217) > 0) continue; if (gensio_pparm_bool(&p, args[i], "winsize", &allow_rfc1073) > 0) continue; if (gensio_pparm_ds(&p, args[i], "writebuf", &max_write_size) > 0) continue; if (gensio_pparm_ds(&p, args[i], "readbuf", &max_read_size) > 0) continue; if (gensio_pparm_boolv(&p, args[i], "mode", "client", "server", &is_client) > 0) continue; if (gensio_base_parm(parms, &p, args[i]) > 0) continue; gensio_pparm_unknown_parm(&p, args[i]); rv = GE_INVAL; goto out_err2; } stela = o->zalloc(o, sizeof(*stela)); if (!stela) { rv = GE_NOMEM; goto out_err2; } stela->o = o; stela->cb = cb; stela->user_data = user_data; stela->max_write_size = max_write_size; stela->max_read_size = max_read_size; stela->allow_rfc2217 = allow_rfc2217; stela->allow_rfc1073 = allow_rfc1073; stela->is_client = is_client; rv = gensio_gensio_accepter_alloc(child, o, "telnet", cb, user_data, gensio_gensio_acc_telnet_cb, stela, &accepter); if (rv) goto out_err; rv = gensio_acc_base_parms_set(accepter, &parms); if (rv) goto out_err; if (allow_rfc2217) gensio_acc_set_is_serial(accepter, true); stela->acc = accepter; gensio_acc_set_is_reliable(accepter, gensio_acc_is_reliable(child)); *raccepter = accepter; return 0; out_err: if (accepter) gensio_gensio_acc_free_nochild(accepter); else stela_free(stela); out_err2: if (parms) gensio_base_parms_free(&parms); return rv; } static int str_to_telnet_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { int err; struct gensio_accepter *acc2 = NULL; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio_accepter(str, o, cb, user_data, &acc2); if (!err) { err = telnet_gensio_accepter_alloc(acc2, args, o, cb, user_data, acc); if (err) gensio_acc_free(acc2); } return err; } int gensio_init_telnet(struct gensio_os_funcs *o) { int rv; rv = register_filter_gensio(o, "telnet", str_to_telnet_gensio, telnet_gensio_alloc); if (rv) return rv; rv = register_filter_gensio_accepter(o, "telnet", str_to_telnet_gensio_accepter, telnet_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/gensio_pty.c0000664000175000017500000004346414753174002011571 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* This code handles running a child process using a pty. */ #if defined(linux) || defined(__MSYS__) #define _GNU_SOURCE /* Get ptsname_r(). */ #endif #include "config.h" #include #include #include #if HAVE_PTSNAME_R #include #include #include #include #include #include #endif #include #include #include #include #include #include #ifdef _WIN32 #include #endif struct pty_data { struct gensio_os_funcs *o; struct gensio_ll *ll; struct gensio_lock *lock; struct gensio_iod *iod; intptr_t pid; const char **argv; const char **env; char *start_dir; #if HAVE_PTSNAME_R mode_t mode; bool mode_set; char *owner; char *group; /* Symbolic link to create (if not NULL). */ char *link; bool forcelink; bool link_created; #endif #ifdef _WIN32 char *user; char *passwd; char *module; HANDLE userh; #endif unsigned int check_close_count; bool raw; int last_err; /* exit code from the sub-program, after close. */ int exit_code; bool exit_code_set; }; static int pty_check_open(void *handler_data, struct gensio_iod *iod, gensio_time *timeout) { return 0; } static int gensio_setup_pty(struct pty_data *tdata, struct gensio_iod *iod) { int err = 0; #if HAVE_PTSNAME_R /* uid_t can be unsigned, do a cast to avoid warnings. */ #define GENSIO_UID_INVALID_VAL ((uid_t) -1) uid_t ownerid = GENSIO_UID_INVALID_VAL; uid_t groupid = GENSIO_UID_INVALID_VAL; char ptsstr[PATH_MAX]; char pwbuf[16384]; err = ptsname_r(tdata->o->iod_get_fd(iod), ptsstr, sizeof(ptsstr)); if (err) goto out_errno; if (tdata->mode_set) { err = chmod(ptsstr, tdata->mode); if (err) goto out_errno; } if (tdata->owner) { struct passwd pwdbuf, *pwd; err = getpwnam_r(tdata->owner, &pwdbuf, pwbuf, sizeof(pwbuf), &pwd); if (err) goto out_errno; if (!pwd) { err = ENOENT; goto out_err; } ownerid = pwd->pw_uid; } if (tdata->group) { struct group grpbuf, *grp; err = getgrnam_r(tdata->group, &grpbuf, pwbuf, sizeof(pwbuf), &grp); if (err) goto out_errno; if (!grp) { err = ENOENT; goto out_err; } groupid = grp->gr_gid; } if (ownerid != GENSIO_UID_INVALID_VAL || groupid != GENSIO_UID_INVALID_VAL) { err = chown(ptsstr, ownerid, groupid); if (err) goto out_errno; } if (tdata->link) { bool delretry = false; retry: err = symlink(ptsstr, tdata->link); if (err) { if (errno == EEXIST && tdata->forcelink && !delretry) { err = unlink(tdata->link); if (!err) { delretry = true; goto retry; } } goto out_errno; } tdata->link_created = true; } return 0; out_errno: err = errno; out_err: err = gensio_os_err_to_err(tdata->o, err); #endif return err; } static void gensio_cleanup_pty(struct pty_data *tdata) { #if HAVE_PTSNAME_R if (tdata->link_created) { unlink(tdata->link); tdata->link_created = false; } #endif } #ifndef _WIN32 static int setup_for_user(struct pty_data *tdata) { return 0; } static void cleanup_for_user(struct pty_data *tdata) {} #else static int setup_for_user(struct pty_data *tdata) { DWORD err; if (!tdata->user) return 0; err = gensio_win_get_user_token(tdata->user, tdata->passwd, tdata->module, NULL, true, &tdata->userh); if (err) goto out_win_err; #if 0 /* * Password authenticated logins are normal Interactive logins and * can be used directly. S4U logins are Network logins and not * set up as such. */ if (!tdata->passwd) { err = setup_network_token(&tdata->userh, tdata->privileged); if (err) { char errbuf[128]; CloseHandle(tdata->userh); tdata->userh = NULL; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, errbuf, sizeof(errbuf), NULL); log_event(LOG_ERR, "Could not setup process token '%s': %s", tdata->user, errbuf); goto out_win_err; } } #endif if (!SetThreadToken(NULL, tdata->userh)) { CloseHandle(tdata->userh); tdata->userh = NULL; err = GetLastError(); } out_win_err: if (err) return gensio_os_err_to_err(tdata->o, err); return 0; } static void cleanup_for_user(struct pty_data *tdata) { if (!tdata->userh) return; CloseHandle(tdata->userh); tdata->userh = NULL; RevertToSelf(); } #endif static int gensio_setup_child_on_pty(struct pty_data *tdata) { struct gensio_os_funcs *o = tdata->o; int err = 0; struct gensio_iod *iod = NULL; err = o->add_iod(o, GENSIO_IOD_PTY, 0, &iod); if (err) goto out_err; err = o->set_non_blocking(iod); if (err) goto out_err; err = gensio_setup_pty(tdata, iod); if (tdata->raw) { err = o->makeraw(iod); if (err) goto out_err; } if (tdata->argv) err = o->iod_control(iod, GENSIO_IOD_CONTROL_ARGV, false, (intptr_t) tdata->argv); if (!err && tdata->env) err = o->iod_control(iod, GENSIO_IOD_CONTROL_ENV, false, (intptr_t) tdata->env); if (!err && tdata->start_dir) err = o->iod_control(iod, GENSIO_IOD_CONTROL_START_DIR, false, (intptr_t) tdata->start_dir); if (!err) { err = setup_for_user(tdata); if (err) goto out_err; } if (!err) { err = o->iod_control(iod, GENSIO_IOD_CONTROL_START, false, 0); cleanup_for_user(tdata); } if (err) goto out_err; if (tdata->argv) { err = o->iod_control(iod, GENSIO_IOD_CONTROL_PID, true, (intptr_t) &tdata->pid); if (err) goto out_err; } tdata->iod = iod; return 0; out_err: gensio_cleanup_pty(tdata); if (iod) o->close(&iod); return err; } static int pty_sub_open(void *handler_data, struct gensio_iod **riod, gensio_time *timeout) { struct pty_data *tdata = handler_data; int err; tdata->check_close_count = 0; err = gensio_setup_child_on_pty(tdata); if (!err) *riod = tdata->iod; return err; } static int pty_check_exit_code(struct pty_data *tdata) { struct gensio_os_funcs *o = tdata->o; int err = 0; o->lock(tdata->lock); if (tdata->exit_code_set) goto out_unlock; if (tdata->pid == -1) { err = GE_NOTREADY; } else { err = o->wait_subprog(o, tdata->pid, &tdata->exit_code); if (!err) tdata->exit_code_set = true; } out_unlock: o->unlock(tdata->lock); return err; } static int pty_check_close(void *handler_data, struct gensio_iod *iod, enum gensio_ll_close_state state, gensio_time *timeout) { struct pty_data *tdata = handler_data; struct gensio_os_funcs *o = tdata->o; int err; if (state != GENSIO_LL_CLOSE_STATE_DONE) return 0; gensio_cleanup_pty(tdata); if (tdata->iod) { err = o->iod_control(iod, GENSIO_IOD_CONTROL_STOP, false, 0); if (err) goto out_finish; } err = pty_check_exit_code(tdata); if (err == GE_INPROGRESS) { /* FIXME - this should probably be configurable. */ if (tdata->check_close_count >= 500) { /* Wait for 5 seconds. */ err = GE_TIMEDOUT; goto out_finish; } tdata->check_close_count++; timeout->secs = 0; timeout->nsecs = 10000000; return err; } out_finish: if (tdata->iod) { tdata->iod = NULL; gensio_fd_ll_close_now(tdata->ll); } return err; } static void pty_free(void *handler_data) { struct pty_data *tdata = handler_data; struct gensio_os_funcs *o = tdata->o; #ifdef _WIN32 if (tdata->user) free(tdata->user); if (tdata->module) free(tdata->module); if (tdata->passwd) { memset(tdata->passwd, 0, strlen(tdata->passwd)); free(tdata->passwd); } #endif #if HAVE_PTSNAME_R if (tdata->link) o->free(o, tdata->link); if (tdata->owner) o->free(o, tdata->owner); if (tdata->group) o->free(o, tdata->group); #endif if (tdata->argv) gensio_argv_free(o, tdata->argv); if (tdata->env) gensio_argv_free(o, tdata->env); if (tdata->start_dir) o->free(o, tdata->start_dir); if (tdata->lock) o->free_lock(tdata->lock); o->free(o, tdata); } static int pty_write(void *handler_data, struct gensio_iod *iod, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { int rv = iod->f->write(iod, sg, sglen, rcount); if (rv && rv == GE_IOERR) return GE_REMCLOSE; /* We don't seem to get EPIPE from ptys */ return rv; } static int pty_do_read(struct gensio_iod *iod, void *data, gensiods count, gensiods *rcount, const char ***auxdata, void *cb_data) { int rv = iod->f->read(iod, data, count, rcount); if (rv && rv == GE_IOERR) return GE_REMCLOSE; /* We don't seem to get EPIPE from ptys */ return rv; } static void pty_read_ready(void *handler_data, struct gensio_iod *iod) { struct pty_data *tdata = handler_data; gensio_fd_ll_handle_incoming(tdata->ll, pty_do_read, NULL, tdata); } static int pty_control(void *handler_data, struct gensio_iod *iod, bool get, unsigned int option, char *data, gensiods *datalen) { struct pty_data *tdata = handler_data; struct gensio_os_funcs *o = tdata->o; const char **env, **argv; int err, val; switch (option) { case GENSIO_CONTROL_ENVIRONMENT: if (get) return GE_NOTSUP; if (!tdata->argv) return GE_NOTSUP; if (data) { err = gensio_argv_copy(o, (const char **) data, NULL, &env); if (err) return err; } else { env = NULL; } if (tdata->env) gensio_argv_free(o, tdata->env); tdata->env = env; return 0; case GENSIO_CONTROL_ARGS: if (get) return GE_NOTSUP; if (tdata->iod) return GE_NOTREADY; /* Have to do this while closed. */ if (data) { err = gensio_argv_copy(o, (const char **) data, NULL, &argv); if (err) return err; } else { argv = NULL; } if (tdata->argv) gensio_argv_free(o, tdata->argv); tdata->argv = argv; return 0; case GENSIO_CONTROL_EXIT_CODE: if (!get) return GE_NOTSUP; err = 0; o->lock(tdata->lock); if (!tdata->exit_code_set) err = GE_NOTREADY; o->unlock(tdata->lock); if (!err) *datalen = snprintf(data, *datalen, "%d", tdata->exit_code); return err; case GENSIO_CONTROL_KILL_TASK: if (get) return GE_NOTSUP; o->lock(tdata->lock); if (tdata->pid == -1) { err = GE_NOTREADY; } else { val = strtoul(data, NULL, 0); err = o->kill_subprog(o, tdata->pid, !!val); } o->unlock(tdata->lock); return err; case GENSIO_CONTROL_WAIT_TASK: if (!get) return GE_NOTSUP; err = pty_check_exit_code(tdata); if (err) return err; *datalen = snprintf(data, *datalen, "%d", tdata->exit_code); return 0; #if HAVE_PTSNAME_R case GENSIO_CONTROL_LADDR: case GENSIO_CONTROL_LPORT: { char ptsstr[PATH_MAX]; if (!get) return GE_NOTSUP; if (strtoul(data, NULL, 0) > 0) return GE_NOTFOUND; if (!tdata->iod) return GE_NOTREADY; err = ptsname_r(o->iod_get_fd(tdata->iod), ptsstr, sizeof(ptsstr)); if (err) err = gensio_os_err_to_err(o, errno); else *datalen = snprintf(data, *datalen, "%s", ptsstr); return err; } #endif case GENSIO_CONTROL_RADDR: if (!get) return GE_NOTSUP; if (strtoul(data, NULL, 0) > 0) return GE_NOTFOUND; if (!tdata->argv) return GE_NODATA; *datalen = gensio_argv_snprintf(data, *datalen, NULL, tdata->argv); return 0; case GENSIO_CONTROL_RADDR_BIN: if (!get) return GE_NOTSUP; if (!tdata->iod) return GE_NOTREADY; if (*datalen >= sizeof(int)) *((int *) data) = o->iod_get_fd(tdata->iod); *datalen = sizeof(int); return 0; case GENSIO_CONTROL_REMOTE_ID: if (!get) return GE_NOTSUP; if (tdata->pid == -1) return GE_NOTREADY; *datalen = snprintf(data, *datalen, "%llu", (unsigned long long) tdata->pid); return 0; case GENSIO_CONTROL_WIN_SIZE: { struct gensio_winsize ws = {0, 0, 0, 0}; int c; if (get) return GE_NOTSUP; if (!tdata->iod) return GE_NOTREADY; c = sscanf(data, "%d:%d:%d:%d", &ws.ws_row, &ws.ws_col, &ws.ws_xpixel, &ws.ws_ypixel); if (c < 0) return gensio_os_err_to_err(o, errno); if (c < 2) return GE_INVAL; return o->iod_control(tdata->iod, GENSIO_IOD_CONTROL_WIN_SIZE, get, (intptr_t) &ws); } case GENSIO_CONTROL_START_DIRECTORY: if (get) { *datalen = snprintf(data, *datalen, "%s", tdata->start_dir); } else { char *dir; dir = gensio_strdup(o, (char *) data); if (!dir) return GE_NOMEM; if (tdata->start_dir) o->free(o, tdata->start_dir); tdata->start_dir = dir; } return 0; } return GE_NOTSUP; } static const struct gensio_fd_ll_ops pty_fd_ll_ops = { .sub_open = pty_sub_open, .check_open = pty_check_open, .read_ready = pty_read_ready, .check_close = pty_check_close, .free = pty_free, .write = pty_write, .control = pty_control }; static int pty_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { const char * const *argv = gdata; struct pty_data *tdata = NULL; struct gensio *io; gensiods max_read_size = GENSIO_DEFAULT_BUF_SIZE; unsigned int i; #if HAVE_PTSNAME_R unsigned int umode = 6, gmode = 6, omode = 6, mode; bool mode_set = false; const char *owner = NULL, *group = NULL, *link = NULL; bool forcelink = false; #endif #ifdef _WIN32 const char *user = NULL, *passwd = NULL, *module = NULL; #endif const char *start_dir = NULL; bool raw = false; int err; GENSIO_DECLARE_PPGENSIO(p, o, cb, "pty", user_data); for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(&p, args[i], "readbuf", &max_read_size) > 0) continue; if (gensio_pparm_value(&p, args[i], "start-dir", &start_dir) > 0) continue; #if HAVE_PTSNAME_R if (gensio_pparm_value(&p, args[i], "link", &link)) continue; if (gensio_pparm_bool(&p, args[i], "forcelink", &forcelink) > 0) continue; if (gensio_pparm_mode(&p, args[i], "umode", &umode) > 0) { mode_set = true; continue; } if (gensio_pparm_mode(&p, args[i], "gmode", &gmode) > 0) { mode_set = true; continue; } if (gensio_pparm_mode(&p, args[i], "omode", &omode) > 0) { mode_set = true; continue; } if (gensio_pparm_perm(&p, args[i], "perm", &mode) > 0) { mode_set = true; umode = mode >> 6 & 7; gmode = mode >> 3 & 7; omode = mode & 7; continue; } if (gensio_pparm_value(&p, args[i], "owner", &owner)) continue; if (gensio_pparm_value(&p, args[i], "group", &group)) continue; #endif #ifdef _WIN32 if (gensio_pparm_value(&p, args[i], "user", &user)) continue; if (gensio_pparm_value(&p, args[i], "passwd", &passwd)) continue; if (gensio_pparm_value(&p, args[i], "module", &module)) continue; #endif if (gensio_pparm_bool(&p, args[i], "raw", &raw) > 0) continue; gensio_pparm_unknown_parm(&p, args[i]); return GE_INVAL; } #ifdef _WIN32 if (user && !argv) { gensio_pparm_slog(&p, "If user is specified, you must run a program"); return GE_INVAL; } if (passwd && !user) { gensio_pparm_slog(&p, "passwd requires a user to be set"); return GE_INVAL; } if (module && !user) { gensio_pparm_slog(&p, "module requires a user to be set"); return GE_INVAL; } #endif tdata = o->zalloc(o, sizeof(*tdata)); if (!tdata) return GE_NOMEM; tdata->o = o; tdata->pid = -1; if (start_dir) { tdata->start_dir = gensio_strdup(o, start_dir); if (!tdata->start_dir) goto out_nomem; } tdata->lock = o->alloc_lock(o); if (!tdata->lock) goto out_nomem; #if HAVE_PTSNAME_R if (link) { tdata->link = gensio_strdup(o, link); if (!tdata->link) goto out_nomem; } tdata->forcelink = forcelink; tdata->raw = raw; tdata->mode = umode << 6 | gmode << 3 | omode; tdata->mode_set = mode_set; if (owner) { tdata->owner = gensio_strdup(o, owner); if (!tdata->owner) goto out_nomem; } if (group) { tdata->group = gensio_strdup(o, group); if (!tdata->group) goto out_nomem; } #endif #ifdef _WIN32 if (user) { tdata->user = gensio_strdup(o, user); if (!tdata->user) goto out_nomem; } if (passwd) { tdata->passwd = gensio_strdup(o, passwd); if (!tdata->passwd) goto out_nomem; } if (!module) module = "gensio"; tdata->module = gensio_strdup(o, module); if (!tdata->module) goto out_nomem; #endif if (argv && argv[0]) { #if HAVE_PTSNAME_R if (mode_set || owner || group) { /* These are only for non-subprogram ptys. */ err = GE_INCONSISTENT; goto out_err; } #endif err = gensio_argv_copy(o, argv, NULL, &tdata->argv); if (err) goto out_nomem; } tdata->ll = fd_gensio_ll_alloc(o, NULL, &pty_fd_ll_ops, tdata, max_read_size, false, false); if (!tdata->ll) goto out_nomem; io = base_gensio_alloc(o, tdata->ll, NULL, NULL, "pty", cb, user_data); if (!io) goto out_nomem; gensio_set_is_reliable(io, true); *new_gensio = io; return 0; out_nomem: err = GE_NOMEM; #if HAVE_PTSNAME_R out_err: #endif if (tdata->ll) gensio_ll_free(tdata->ll); else pty_free(tdata); return err; } static int str_to_pty_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err, argc; const char **argv; err = gensio_str_to_argv(o, str, &argc, &argv, NULL); if (!err) { err = pty_gensio_alloc(argv, args, o, cb, user_data, new_gensio); gensio_argv_free(o, argv); } return err; } int gensio_init_pty(struct gensio_os_funcs *o) { int rv; rv = register_gensio(o, "pty", str_to_pty_gensio, pty_gensio_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/os_osops.c0000664000175000017500000031067515045153771011263 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2019 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #if defined(linux) || defined(__MSYS__) #define _XOPEN_SOURCE 600 /* Get posix_openpt() and friends. */ #define _GNU_SOURCE /* Get ptsname_r(). */ #endif #include "config.h" #define _DEFAULT_SOURCE /* Get getgrouplist(), setgroups() */ #include #include #include #include #ifdef HAVE_TCPD_H #include #endif /* HAVE_TCPD_H */ #include #include #include #include #include #include #include #include #include "errtrig.h" #include static const char *progname = "gensio"; bool gensio_set_progname(const char *iprogname) { progname = iprogname; return true; } const char *gensio_get_progname(void) { return progname; } #ifdef _WIN32 #include /* For AF_UNSPEC */ #include #include #else #include #include /* For AF_UNSPEC */ #include #include #include #include #include #include #include #include #include #include #if USE_OPENPTY #include #endif #if USE_GGL_INT #define GID_CAST (int *) #else #define GID_CAST #endif int gensio_unix_os_setupnewprog(void) { struct passwd *pw; int err; uid_t uid = getuid(); if (do_errtrig()) return GE_NOMEM; if (uid == geteuid()) return 0; pw = getpwuid(uid); if (!pw) return errno; /* Sets the real, effective, and saved group. */ err = setgid(getgid()); if (err) return errno; #ifdef HAVE_INITGROUPS err = initgroups(pw->pw_name, pw->pw_gid); if (err) return errno; #else /* * Get the list of groups. getgrouplist doesn't work the same on * macos (and I assume BSD), it returns the number of values put * into groups, not the total number of available values. So we * have to loop :-(. */ #define NGROUP_INCR 32 { gid_t *groups = NULL; int cgroup = 0, ngroup; err = -1; while (err == -1) { if (groups) free(groups); cgroup += NGROUP_INCR; ngroup = cgroup; groups = malloc(ngroup * sizeof(*groups)); if (!groups) return ENOMEM; err = getgrouplist(pw->pw_name, pw->pw_gid, GID_CAST groups, &ngroup); } if (ngroup == 0) { /* Need at least one value. groups can't be NULL here. */ ngroup = 1; groups[0] = getgid(); } err = setgroups(ngroup, groups); if (err) { err = errno; free(groups); return err; } free(groups); } #endif /* Sets the real, effective, and saved userid. */ err = setuid(uid); if (err) return errno; return 0; } #endif int gensio_os_open_listen_sockets(struct gensio_os_funcs *o, struct gensio_addr *addr, void (*readhndlr)(struct gensio_iod *, void *), void (*writehndlr)(struct gensio_iod *, void *), void (*fd_handler_cleared)(struct gensio_iod *, void *), int (*call_b4_listen)(struct gensio_iod *, void *), void *data, unsigned int opensock_flags, struct gensio_opensocks **rfds, unsigned int *rnr_fds) { struct gensio_opensocks *fds; unsigned int nr_fds, i; int rv; rv = o->open_listen_sockets(o, addr, call_b4_listen, data, opensock_flags, &fds, &nr_fds); if (rv) return rv; for (i = 0; i < nr_fds; i++) { rv = o->set_fd_handlers(fds[i].iod, data, readhndlr, writehndlr, NULL, fd_handler_cleared); if (rv) break; } if (!rv) { *rfds = fds; *rnr_fds = nr_fds; return 0; } for (i = 0; i < nr_fds; i++) { o->clear_fd_handlers_norpt(fds[i].iod); o->close(&fds[i].iod); } o->free(o, fds); return rv; } int gensio_scan_network_port(struct gensio_os_funcs *o, const char *str, bool listen, struct gensio_addr **raddr, int *rprotocol, bool *is_port_set, int *rargc, const char ***rargs) { int err = 0, family = AF_UNSPEC, argc = 0; const char **args = NULL; bool doskip = true; int protocol; if (strncmp(str, "ipv4,", 5) == 0) { family = AF_INET; str += 5; } else if (strncmp(str, "ipv6,", 5) == 0) { #ifdef AF_INET6 family = AF_INET6; str += 5; #else return GE_NOTSUP; #endif } if (strncmp(str, "unix,", 5) == 0 || (rargs && strncmp(str, "unix(", 5) == 0)) { if (family != AF_UNSPEC) return GE_INVAL; str += 4; handle_unix: protocol = GENSIO_NET_PROTOCOL_UNIX; #ifdef SOCK_SEQPACKET } else if (strncmp(str, "unixseq,", 8) == 0 || (rargs && strncmp(str, "unixseq(", 8) == 0)) { if (family != AF_UNSPEC) return GE_INVAL; str += 7; handle_unix_seqpacket: protocol = GENSIO_NET_PROTOCOL_UNIX_SEQPACKET; #endif } else if (strncmp(str, "unixdgram,", 10) == 0 || (rargs && strncmp(str, "unixdgram(", 10) == 0)) { if (family != AF_UNSPEC) return GE_INVAL; str += 9; handle_unix_dgram: protocol = GENSIO_NET_PROTOCOL_UNIX_DGRAM; } else if (strncmp(str, "tcp,", 4) == 0 || (rargs && strncmp(str, "tcp(", 4) == 0)) { str += 3; handle_tcp: protocol = GENSIO_NET_PROTOCOL_TCP; } else if (strncmp(str, "udp,", 4) == 0 || (rargs && strncmp(str, "udp(", 4) == 0)) { str += 3; handle_udp: protocol = GENSIO_NET_PROTOCOL_UDP; } else if (strncmp(str, "sctp,", 5) == 0 || (rargs && strncmp(str, "sctp(", 5) == 0)) { str += 4; handle_sctp: #if HAVE_LIBSCTP protocol = GENSIO_NET_PROTOCOL_SCTP; #else return GE_NOTSUP; #endif } else if (rprotocol && *rprotocol != GENSIO_NET_PROTOCOL_UNSPEC) { doskip = false; switch (*rprotocol) { case GENSIO_NET_PROTOCOL_UNIX: goto handle_unix; case GENSIO_NET_PROTOCOL_UNIX_DGRAM: goto handle_unix_dgram; #ifdef SOCK_SEQPACKET case GENSIO_NET_PROTOCOL_UNIX_SEQPACKET: goto handle_unix_seqpacket; #endif case GENSIO_NET_PROTOCOL_TCP: goto handle_tcp; case GENSIO_NET_PROTOCOL_UDP: goto handle_udp; case GENSIO_NET_PROTOCOL_SCTP: goto handle_sctp; default: goto default_protocol; } } else { default_protocol: doskip = false; protocol = GENSIO_NET_PROTOCOL_TCP; } if (doskip) { if (*str == '(') { if (!rargs) return GE_INVAL; err = gensio_scan_args(o, &str, &argc, &args); if (err) return err; } else if (*str != ',') { return GE_INVAL; } else { str++; /* Skip the ',' */ } } err = o->addr_scan_ips(o, str, listen, family, protocol, is_port_set, true, raddr); if (err) { if (args) gensio_argv_free(o, args); return err; } if (rargc) *rargc = argc; if (rargs) *rargs = args; if (rprotocol) *rprotocol = protocol; return 0; } int gensio_scan_network_addr(struct gensio_os_funcs *o, const char *str, int protocol, struct gensio_addr **raddr) { return o->addr_scan_ips(o, str, false, AF_UNSPEC, protocol, NULL, false, raddr); } int gensio_os_scan_netaddr(struct gensio_os_funcs *o, const char *str, bool listen, int protocol, struct gensio_addr **raddr) { bool is_port_set; struct gensio_addr *addr; int rv; if (protocol == GENSIO_NET_PROTOCOL_UNSPEC && strncmp(str, "ax25:", 5) == 0) return gensio_ax25_str_to_addr(o, str, raddr); rv = o->addr_scan_ips(o, str, listen, AF_UNSPEC, protocol, &is_port_set, true, &addr); if (!rv && !listen && !is_port_set && protocol != GENSIO_NET_PROTOCOL_UNIX && protocol != GENSIO_NET_PROTOCOL_UNIX_DGRAM && protocol != GENSIO_NET_PROTOCOL_UNIX_SEQPACKET) { gensio_addr_free(addr); rv = GE_INVAL; } else if (!rv) { *raddr = addr; } return rv; } void gensio_os_free_net_ifs(struct gensio_os_funcs *o, struct gensio_net_if **ifs, unsigned int nifs) { unsigned int i, j; if (!ifs) return; for (i = 0; i < nifs; i++) { if (!ifs[i]) continue; if (ifs[i]->name) gensio_os_funcs_zfree(o, ifs[i]->name); if (ifs[i]->addrs) { for (j = 0; j < ifs[i]->naddrs; j++) { if (ifs[i]->addrs[j].addrstr) gensio_os_funcs_zfree(o, ifs[i]->addrs[j].addrstr); } gensio_os_funcs_zfree(o, ifs[i]->addrs); } gensio_os_funcs_zfree(o, ifs[i]); } gensio_os_funcs_zfree(o, ifs); } #ifndef _WIN32 static bool is_inet_family(struct sockaddr *s) { if (!s) /* This can happen on down interfaces. */ return false; return (s->sa_family == AF_INET || s->sa_family == AF_INET6); } #endif int gensio_os_get_net_ifs(struct gensio_os_funcs *o, struct gensio_net_if ***rifs, unsigned int *rnifs) { struct gensio_net_if **ifs = NULL; char buf[100], *addrtype; #ifdef _WIN32 IP_ADAPTER_ADDRESSES *t, *c; ULONG err; unsigned int i, j, nifs; ULONG buflen = 15 * 1024; while (true) { t = o->zalloc(o, buflen); if (!t) return GE_NOMEM; err = GetAdaptersAddresses(AF_UNSPEC, (GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME), NULL, t, &buflen); if (err == NO_ERROR) break; o->free(o, t); if (err == ERROR_BUFFER_OVERFLOW) { /* Just retry */ } else if (err == ERROR_NOT_ENOUGH_MEMORY) { return GE_NOMEM; } else { return GE_OSERR; } } i = 0; for (c = t; c; c = c->Next) { if (c->IfIndex != c->Ipv6IfIndex && c->Ipv6IfIndex != 0) continue; /* FIXME - Not sure what to do with these. */ i++; } nifs = i; ifs = gensio_os_funcs_zalloc(o, sizeof(*ifs) * (nifs + 1)); if (!ifs) goto out_err; i = 0; for (c = t; c; c = c->Next) { IP_ADAPTER_UNICAST_ADDRESS *al; unsigned int slen; size_t rlen; if (c->IfIndex != c->Ipv6IfIndex && c->Ipv6IfIndex != 0) continue; /* FIXME - Not sure what to do with these. */ ifs[i] = gensio_os_funcs_zalloc(o, sizeof(**ifs)); if (!ifs[i]) goto out_err; ifs[i]->ifindex = c->IfIndex; if (c->IfType == IF_TYPE_SOFTWARE_LOOPBACK) ifs[i]->flags |= GENSIO_NET_IF_LOOPBACK; if (c->OperStatus == IfOperStatusUp) ifs[i]->flags |= GENSIO_NET_IF_UP; if (!c->NoMulticast) ifs[i]->flags |= GENSIO_NET_IF_MULTICAST; slen = wcslen(c->FriendlyName) * 2; ifs[i]->name = o->zalloc(o, slen + 1); if (!ifs[i]->name) goto out_err; wcstombs_s(&rlen, ifs[i]->name, slen + 1, c->FriendlyName, slen); for (j = 0, al = c->FirstUnicastAddress; al; j++, al = al->Next) ; ifs[i]->addrs = o->zalloc(o, sizeof(struct gensio_net_addr) * j); if (!ifs[i]->addrs) goto out_err; for (j = 0, al = c->FirstUnicastAddress; al; al = al->Next) { struct sockaddr *a = (void *) al->Address.lpSockaddr; if (a->sa_family == AF_INET) { struct sockaddr_in *ia = (void *) a; ifs[i]->addrs[j].family = GENSIO_NETTYPE_IPV4; ifs[i]->addrs[j].netbits = al->OnLinkPrefixLength; ifs[i]->addrs[j].addrlen = 4; memcpy(ifs[i]->addrs[j].addr, &ia->sin_addr, 4); addrtype = "ipv4:"; } else if (a->sa_family == AF_INET6) { struct sockaddr_in6 *ia = (void *) a; ifs[i]->addrs[j].family = GENSIO_NETTYPE_IPV6; ifs[i]->addrs[j].netbits = al->OnLinkPrefixLength; ifs[i]->addrs[j].addrlen = 16; memcpy(ifs[i]->addrs[j].addr, &ia->sin6_addr, 16); addrtype = "ipv6:"; } else { continue; } memcpy(buf, addrtype, 5); inet_ntop(a->sa_family, ifs[i]->addrs[j].addr, buf + 5, sizeof(buf) - 5); ifs[i]->addrs[j].addrstr = gensio_strdup(o, buf); if (!ifs[i]->addrs[j].addrstr) goto out_err; j++; } ifs[i]->naddrs = j; i++; assert(i <= nifs); } o->free(o, t); *rifs = ifs; *rnifs = i; return 0; out_err: o->free(o, t); if (ifs) gensio_os_free_net_ifs(o, ifs, nifs); return GE_NOMEM; #else struct ifaddrs *ifap, *ifp, *ifp2; unsigned int i, j, k, nifs = 0, naddrs, addrlen, nbits; unsigned char *addr, *netmask; int rv; bool found; rv = getifaddrs(&ifap); if (rv) { rv = gensio_os_err_to_err(o, errno); return rv; } /* Count the number of unique interfaces by name. */ for (ifp = ifap; ifp; ifp = ifp->ifa_next) { if (!is_inet_family(ifp->ifa_addr)) continue; found = false; for (ifp2 = ifap; ifp2 != ifp; ifp2 = ifp2->ifa_next) { if (!is_inet_family(ifp2->ifa_addr)) continue; if (strcmp(ifp2->ifa_name, ifp->ifa_name) == 0) { found = true; break; } } if (found) continue; nifs++; } rv = GE_NOMEM; ifs = gensio_os_funcs_zalloc(o, sizeof(*ifs) * (nifs + 1)); if (!ifs) goto out_err; for (ifp = ifap; ifp; ifp = ifp->ifa_next) { if (!is_inet_family(ifp->ifa_addr)) continue; for (i = 0; i < nifs && ifs[i]; i++) { if (strcmp(ifs[i]->name, ifp->ifa_name) == 0) break; } if (!ifs[i]) { /* * First occurence of this name, allocate info and the * if address array. */ ifs[i] = gensio_os_funcs_zalloc(o, sizeof(**ifs)); if (!ifs[i]) goto out_err; ifs[i]->name = gensio_strdup(o, ifp->ifa_name); if (!ifs[i]->name) goto out_err; ifs[i]->ifindex = if_nametoindex(ifp->ifa_name); if (!ifs[i]->ifindex) { rv = gensio_os_err_to_err(o, errno); goto out_err; } /* Count the number of addresses for this interface. */ naddrs = 1; for (ifp2 = ifp->ifa_next; ifp2; ifp2 = ifp2->ifa_next) { if (!is_inet_family(ifp2->ifa_addr)) continue; if (strcmp(ifp2->ifa_name, ifp->ifa_name) == 0) naddrs++; } ifs[i]->addrs = gensio_os_funcs_zalloc(o, naddrs * sizeof(struct gensio_net_addr)); if (!ifs[i]->addrs) goto out_err; } if (ifp->ifa_flags & IFF_UP) ifs[i]->flags |= GENSIO_NET_IF_UP; if (ifp->ifa_flags & IFF_LOOPBACK) ifs[i]->flags |= GENSIO_NET_IF_LOOPBACK; if (ifp->ifa_flags & IFF_MULTICAST) ifs[i]->flags |= GENSIO_NET_IF_MULTICAST; if (ifp->ifa_addr->sa_family == AF_INET) { struct sockaddr_in *s; s = (struct sockaddr_in *) ifp->ifa_addr; addr = (unsigned char *) &s->sin_addr; s = (struct sockaddr_in *) ifp->ifa_netmask; netmask = (unsigned char *) &s->sin_addr; addrlen = 4; addrtype = "ipv4:"; } else { struct sockaddr_in6 *s; s = (struct sockaddr_in6 *) ifp->ifa_addr; addr = s->sin6_addr.s6_addr; s = (struct sockaddr_in6 *) ifp->ifa_netmask; netmask = s->sin6_addr.s6_addr; addrlen = 16; addrtype = "ipv6:"; } j = (ifs[i]->naddrs)++; memcpy(ifs[i]->addrs[j].addr, addr, addrlen); ifs[i]->addrs[j].addrlen = addrlen; if (ifp->ifa_addr->sa_family == AF_INET) ifs[i]->addrs[j].family = GENSIO_NETTYPE_IPV4; else ifs[i]->addrs[j].family = GENSIO_NETTYPE_IPV6; for (nbits = 0, k = 0; k < addrlen && netmask[k] == 0xff; k++) nbits += 8; if (k < addrlen) { unsigned char v = netmask[k]; while (v & 0xff) { if (v & 0x80) nbits++; else break; v <<= 1; } } ifs[i]->addrs[j].netbits = nbits; memcpy(buf, addrtype, 5); inet_ntop(ifp->ifa_addr->sa_family, addr, buf + 5, sizeof(buf) - 5); ifs[i]->addrs[j].addrstr = gensio_strdup(o, buf); if (!ifs[i]->addrs[j].addrstr) goto out_err; } freeifaddrs(ifap); *rifs = ifs; *rnifs = nifs; return 0; out_err: freeifaddrs(ifap); if (ifs) gensio_os_free_net_ifs(o, ifs, nifs); return rv; #endif } const char * gensio_os_check_tcpd_ok(struct gensio_iod *iod, const char *iprogname) { #ifdef HAVE_TCPD_H struct request_info req; if (!iprogname) iprogname = progname; request_init(&req, RQ_DAEMON, iprogname, RQ_FILE, iod->f->iod_get_fd(iod), NULL); fromhost(&req); if (!hosts_access(&req)) return "Access denied\r\n"; #endif return NULL; } /* * Serial port handling. */ #ifdef _WIN32 #include #include #include #include struct stdio_mode { DWORD old_mode_flags; }; int gensio_win_stdin_makeraw(struct gensio_os_funcs *o, HANDLE h, struct stdio_mode **rm) { DWORD mode, omode; struct stdio_mode *m = NULL; if (!GetConsoleMode(h, &omode)) return GE_NOTSUP; if (!*rm) { m = o->zalloc(o, sizeof(*m)); if (!m) return GE_NOMEM; m->old_mode_flags = omode; } mode = omode & ~(ENABLE_LINE_INPUT | ENABLE_INSERT_MODE | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT); mode |= ENABLE_WINDOW_INPUT | ENABLE_VIRTUAL_TERMINAL_INPUT; if (!SetConsoleMode(h, mode)) { if (m) o->free(o, m); return gensio_os_err_to_err(o, GetLastError()); } if (m) *rm = m; return 0; } int gensio_win_stdout_makeraw(struct gensio_os_funcs *o, HANDLE h, struct stdio_mode **rm) { DWORD mode, omode; struct stdio_mode *m = NULL; if (!GetConsoleMode(h, &omode)) return GE_NOTSUP; if (!*rm) { m = o->zalloc(o, sizeof(*m)); if (!m) return GE_NOMEM; m->old_mode_flags = omode; } mode = omode; mode |= (ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_WRAP_AT_EOL_OUTPUT); if (!SetConsoleMode(h, mode)) { if (m) o->free(o, m); return gensio_os_err_to_err(o, GetLastError()); } if (m) *rm = m; return 0; } void gensio_win_stdio_cleanup(struct gensio_os_funcs *o, HANDLE h, struct stdio_mode **m) { if (!*m) return; SetConsoleMode(h, (*m)->old_mode_flags); o->free(o, *m); *m = NULL; } struct gensio_win_commport { BOOL orig_dcb_set; DCB orig_dcb; DCB curr_dcb; BOOL orig_timeouts_set; COMMTIMEOUTS orig_timeouts; /* * Windows has no way to fetch if break, dtr, or rts is set. So * try to keep track of it as best as possible. */ BOOL break_set; BOOL dtr_set; BOOL dtr_val; BOOL rts_set; BOOL rts_val; BOOL first_applied; BOOL break_timer_running; HANDLE break_timer; }; int gensio_win_setup_commport(struct gensio_os_funcs* o, HANDLE h, struct gensio_win_commport** rc, HANDLE* break_timer) { DCB* t; COMMTIMEOUTS timeouts; int rv = 0; struct gensio_win_commport* c; if (*rc) return GE_INUSE; c = o->zalloc(o, sizeof(*c)); if (!c) return GE_NOMEM; t = &c->curr_dcb; if (!GetCommTimeouts(h, &c->orig_timeouts)) goto out_err; c->orig_timeouts_set = TRUE; timeouts.ReadIntervalTimeout = 1; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 0; if (!SetCommTimeouts(h, &timeouts)) goto out_err; if (!GetCommState(h, &c->orig_dcb)) goto out_err; c->orig_dcb_set = TRUE; *t = c->orig_dcb; t->fBinary = TRUE; t->BaudRate = 9600; t->fParity = NOPARITY; t->fDsrSensitivity = TRUE; t->fTXContinueOnXoff = FALSE; t->fOutX = FALSE; t->fInX = FALSE; t->fErrorChar = FALSE; t->fNull = FALSE; t->fOutxCtsFlow = FALSE; t->fAbortOnError = FALSE; t->XonLim = 50; t->XoffLim = 50; t->ByteSize = 8; t->StopBits = ONESTOPBIT; if (t->fDtrControl == DTR_CONTROL_ENABLE) { c->dtr_val = 1; c->rts_val = 1; t->fRtsControl = RTS_CONTROL_ENABLE; } else { c->dtr_val = 0; c->rts_val = 0; /* Note that we don't support DTR_CONTROL_HANDSHAKE. */ t->fDtrControl = DTR_CONTROL_DISABLE; t->fRtsControl = RTS_CONTROL_DISABLE; } c->break_set = FALSE; /* Break timer */ c->break_timer = CreateWaitableTimer(NULL, FALSE, NULL); if (!c->break_timer) { rv = GE_NOMEM; } else { *break_timer = c->break_timer; *rc = c; } return rv; out_err: return gensio_os_err_to_err(o, GetLastError()); } DWORD gensio_win_commport_break_done(struct gensio_os_funcs *o, HANDLE h, struct gensio_win_commport **c) { if (!(*c)->break_set) if (!EscapeCommFunction(h, CLRBREAK)) return GetLastError(); (*c)->break_timer_running = FALSE; return 0; } void gensio_win_cleanup_commport(struct gensio_os_funcs *o, HANDLE h, struct gensio_win_commport **c) { if (!*c) return; CloseHandle((*c)->break_timer); if ((*c)->orig_dcb_set) SetCommState(h, &(*c)->orig_dcb); if ((*c)->orig_timeouts_set) SetCommTimeouts(h, &(*c)->orig_timeouts); o->free(o, *c); *c = NULL; } int gensio_win_commport_control(struct gensio_os_funcs *o, int op, bool get, intptr_t val, struct gensio_win_commport **c, HANDLE h) { DCB *t = &(*c)->curr_dcb; int rv = 0; switch (op) { case GENSIO_IOD_CONTROL_SERDATA: if (get) { t = o->zalloc(o, sizeof(*t)); if (!t) { rv = GE_NOMEM; } else { *t = (*c)->curr_dcb; *((void **) val) = t; } } else { (*c)->curr_dcb = *((DCB *) val); } break; case GENSIO_IOD_CONTROL_FREE_SERDATA: o->free(o, (void *) val); break; case GENSIO_IOD_CONTROL_BAUD: if (get) *((int *) val) = t->BaudRate; else t->BaudRate = val; break; case GENSIO_IOD_CONTROL_PARITY: if (get) { if (t->fParity) { switch (t->Parity) { case NOPARITY: *((int *) val) = GENSIO_SER_PARITY_NONE; break; case EVENPARITY: *((int *) val) = GENSIO_SER_PARITY_EVEN; break; case ODDPARITY: *((int *) val) = GENSIO_SER_PARITY_ODD; break; case MARKPARITY: *((int *) val) = GENSIO_SER_PARITY_MARK; break; case SPACEPARITY: *((int *) val) = GENSIO_SER_PARITY_SPACE; break; default: rv = GE_IOERR; } } else { *((int *) val) = GENSIO_SER_PARITY_NONE; } } else { t->fParity = 1; switch (val) { case GENSIO_SER_PARITY_NONE: t->fParity = 0; t->Parity = NOPARITY; break; case GENSIO_SER_PARITY_EVEN: t->Parity = EVENPARITY; break; case GENSIO_SER_PARITY_ODD: t->Parity = ODDPARITY; break; case GENSIO_SER_PARITY_MARK: t->Parity = MARKPARITY; break; case GENSIO_SER_PARITY_SPACE: t->Parity = SPACEPARITY; break; default: rv = GE_INVAL; } } break; case GENSIO_IOD_CONTROL_XONXOFF: if (get) *((int *) val) = t->fOutX; else { t->XonChar = 17; t->XoffChar = 19; t->fOutX = !!val; } break; case GENSIO_IOD_CONTROL_RTSCTS: if (get) { *((int *) val) = t->fOutxCtsFlow; } else { /* Will get applied later. */ t->fOutxCtsFlow = !!val; if (val) t->fRtsControl = RTS_CONTROL_HANDSHAKE; else if (t->fDtrControl == DTR_CONTROL_ENABLE) t->fRtsControl = RTS_CONTROL_ENABLE; else t->fRtsControl = RTS_CONTROL_DISABLE; } break; case GENSIO_IOD_CONTROL_DATASIZE: if (get) *((int *) val) = t->ByteSize; else t->ByteSize = val; break; case GENSIO_IOD_CONTROL_STOPBITS: if (get) { switch (t->StopBits) { case ONESTOPBIT: *((int *) val) = 1; break; case TWOSTOPBITS: *((int *) val) = 2; break; default: rv = GE_INVAL; } } else { switch (val) { case 1: t->StopBits = ONESTOPBIT; break; case 2: t->StopBits = TWOSTOPBITS; break; default: rv = GE_INVAL; } } break; case GENSIO_IOD_CONTROL_LOCAL: if (get) *((int *) val) = !t->fDsrSensitivity; else t->fDsrSensitivity = !val; break; case GENSIO_IOD_CONTROL_HANGUP_ON_DONE: if (get) { *((int *) val) = t->fDtrControl == DTR_CONTROL_ENABLE; } else { int oldval = t->fDtrControl == DTR_CONTROL_ENABLE; val = !!val; if (val != oldval) { if (val) { t->fDtrControl = DTR_CONTROL_ENABLE; (*c)->dtr_val = TRUE; if (t->fRtsControl == RTS_CONTROL_DISABLE) { t->fRtsControl = RTS_CONTROL_ENABLE; (*c)->rts_val = TRUE; } /* * If the user explicitly sets this, we must set it in * the original as well as in the current DCB, or it * won't work because we will restore it to it's original * value which might not cause the desired behavior. */ (*c)->orig_dcb.fDtrControl = DTR_CONTROL_ENABLE; (*c)->orig_dcb.fDtrControl = RTS_CONTROL_ENABLE; } else { t->fDtrControl = DTR_CONTROL_DISABLE; (*c)->dtr_val = FALSE; if (t->fRtsControl == RTS_CONTROL_ENABLE) { t->fRtsControl = RTS_CONTROL_DISABLE; (*c)->rts_val = FALSE; } /* See comment above on this. */ (*c)->orig_dcb.fDtrControl = DTR_CONTROL_DISABLE; (*c)->orig_dcb.fDtrControl = RTS_CONTROL_DISABLE; } } } break; case GENSIO_IOD_CONTROL_RS485: rv = GE_NOTSUP; break; case GENSIO_IOD_CONTROL_IXONXOFF: if (get) { *((int *) val) = t->fInX; } else { t->fInX = !!val; t->XonChar = 17; t->XoffChar = 19; } break; case GENSIO_IOD_CONTROL_APPLY: if (!SetCommState(h, &(*c)->curr_dcb)) goto out_err; if ((*c)->break_set) { if (!EscapeCommFunction(h, SETBREAK)) goto out_err; } else { if (!EscapeCommFunction(h, CLRBREAK)) goto out_err; } if ((*c)->rts_set) { if ((*c)->rts_val) { if (!EscapeCommFunction(h, SETRTS)) goto out_err; } else { if (!EscapeCommFunction(h, CLRRTS)) goto out_err; } } if ((*c)->dtr_set) { if ((*c)->dtr_val) { if (!EscapeCommFunction(h, SETDTR)) goto out_err; } else { if (!EscapeCommFunction(h, CLRDTR)) goto out_err; } } (*c)->first_applied = TRUE; break; case GENSIO_IOD_CONTROL_SET_BREAK: if (get) { *((int *) val) = (*c)->break_set; } else { if ((*c)->first_applied) { if (val) { if (!EscapeCommFunction(h, SETBREAK)) goto out_err; } else { if (!EscapeCommFunction(h, CLRBREAK)) goto out_err; } } (*c)->break_set = val; } break; case GENSIO_IOD_CONTROL_SEND_BREAK: if (!((*c)->break_set || (*c)->break_timer_running)) { LARGE_INTEGER timeout; /* .25 seconds. */ timeout.QuadPart = 2500000LL; if (!EscapeCommFunction(h, SETBREAK)) goto out_err; if (!SetWaitableTimer((*c)->break_timer, &timeout, 0, NULL, NULL, 0)) { EscapeCommFunction(h, CLRBREAK); goto out_err; } (*c)->break_timer_running = true; } break; case GENSIO_IOD_CONTROL_DTR: if (get) { *((int *) val) = (*c)->dtr_val; } else if (!!val != (*c)->dtr_val || !(*c)->dtr_set) { if ((*c)->first_applied) { if (val) { if (!EscapeCommFunction(h, SETDTR)) goto out_err; } else { if (!EscapeCommFunction(h, CLRDTR)) goto out_err; } } (*c)->dtr_val = !!val; (*c)->dtr_set = TRUE; } break; case GENSIO_IOD_CONTROL_RTS: if (get) { *((int *) val) = (*c)->rts_val; } else { if ((*c)->first_applied) { if (val) { if (!EscapeCommFunction(h, SETRTS)) goto out_err; } else { if (!EscapeCommFunction(h, CLRRTS)) goto out_err; } } (*c)->rts_val = !!val; (*c)->rts_set = TRUE; } break; case GENSIO_IOD_CONTROL_MODEMSTATE: { DWORD dval; int rval = 0; if (!get) { rv = GE_NOTSUP; } else { if (!GetCommModemStatus(h, &dval)) goto out_err; if (dval & MS_CTS_ON) rval |= GENSIO_SER_MODEMSTATE_CTS; if (dval & MS_DSR_ON) rval |= GENSIO_SER_MODEMSTATE_DSR; if (dval & MS_RING_ON) rval |= GENSIO_SER_MODEMSTATE_RI; if (dval & MS_RLSD_ON) rval |= GENSIO_SER_MODEMSTATE_CD; *((int *) val) = rval; } break; } case GENSIO_IOD_CONTROL_FLOWCTL_STATE: default: rv = GE_NOTSUP; } return rv; out_err: return gensio_os_err_to_err(o, GetLastError()); } /* * Windows quoting and escaping rules are insane. * * This information is pulled from https://ss64.com/nt/syntax-esc.html * as I couldn't find any useful information on Microsoft's site. I * was hoping to use the /s option to cmd. The Microsoft docs on this * are incomprehensible, but elsewhere you can find that you can put * the entire command in quotes and it will remove the first and last * quote on the entire line. But that doesn't help in some cases, * like if you have just a command that has spaces in it. * * The documentation on "cmd" says: You must use quotation marks * around the following special characters: & < > [ ] | { } ^ = ; ! ' * + , ` ~ [white space] * * A number of characters, namely '<>&^|', have special meanings as * documented in the set command. You appear to be able to escape * them with the "^" character. However, putting them in quotes * works, too, so that's what we do. * * We put an empty parameter in quotes. * * So that's what we do. If we encounter one of these characters, a * ", or an empty string, we put it in quotes. * * Windows has no way to call a command and pass it an argv-style set * of parameters. You can only put them on the command line as a * single string. So, anything passed in has to be formatted with * escapes and quotes to come back out like it was entered originally. * * The rules for handling a '"' inside a quoted string are bizarre. A * \" is a quote. But the \ is only valid that way before a quote, a * \ without a " following is just a \. But any number of \ before a * " will be converted from two \ to a single \. So "\\\" is \", but * \\" is \ and the " terminates the string. * * But... if you use the echo command, the double quote things are all * ignored and the quotes always come through. The other commands * don't seem to do this, just echo. So we scan for echo as best we * can and handle it specially. * * You also cannot quote built-in commands, like dir and echo. So you * just can't quote anything. So we only quote if we have to. */ static bool needs_quote(char c) { static char *s = "\"&<>[]|{}^=;!'+,`~"; return isspace(c) || strchr(s, c); } static bool endswith(const char *s, const char *end) { unsigned int l1 = strlen(s), l2 = strlen(end); if (l2 > l1) return false; return strcasecmp(s + (l1 - l2), end) == 0; } /* Is "s" a command or powershell invokation. */ static bool iscmd(const char *s, bool *is_powershell) { if (endswith(s, "cmd") || endswith(s, "cmd.exe")) { *is_powershell = false; return true; } if (endswith(s, "powershell") || endswith(s, "powershell.exe")) { *is_powershell = true; return true; } *is_powershell = false; return false; } /* Is this the cmd/powershell option saying the next thing is a command.? */ static bool iscmdstr(const char *s, bool is_powershell) { static char *scmd = "cCkK"; if (!is_powershell) { if (s[0] != '/') return false; return !!strchr(scmd, s[1]); } if (s[0] != '/' && s[0] != '-') return false; if (!s[1]) /* Handle a lone "/" or "-". */ return false; /* Any number of characters of "command" is ok. */ return strncasecmp(s+1, "command", strlen(s)) == 0; } static int argv_to_win_cmdline(struct gensio_os_funcs *o, const char *argv[], char **rcmdline) { unsigned int cmdlen = 0, i, j, k, l, p = 0; char *cmdline; bool is_echo_cmd = false; /* * We do a complicated check for the echo command, because the * quoting is different just for that command. */ for (i = 0; argv[i];) { bool is_powershell = false; is_echo_cmd = strcasecmp(argv[i], "echo") == 0; /* Is this a command invocation? */ if (!is_echo_cmd && iscmd(argv[i], &is_powershell)) { for (i++; argv[i]; i++) { /* Looking for /c or /k. */ if (iscmdstr(argv[i], is_powershell)) break; } } else { break; } } for (i = 0; argv[i]; i++) { const char *s = argv[i]; bool quotestr = false; unsigned int orig_cmdlen = cmdlen; if (s[0] == '\0') { /* Need quotes around an empty parameter to preserve it. */ quotestr = true; } else { for (j = 0; s[j]; j++) { if (needs_quote(s[j]) && !is_echo_cmd) { quotestr = true; break; } cmdlen++; } } if (quotestr) { /* Back up and start over with quotes. */ cmdlen = orig_cmdlen; cmdlen += 2; /* Room for two quotes. */ for (j = 0; s[j]; j++) { if (s[j] == '"') { cmdlen += 2; /* Add room for the \ */ for (k = j; k > 0; ) { k--; if (s[k] == '\\') cmdlen++; /* Double every \ before a " */ else break; } } else { cmdlen++; } } for (k = j; k > 0; ) { k--; if (s[k] == '\\') cmdlen++; /* Double every \ at the end, we are adding a " */ } } cmdlen++; /* Space between arguments. */ } if (cmdlen >= 32766) /* Maximum size for Windows. */ return GE_TOOBIG; cmdline = o->zalloc(o, cmdlen + 1); if (!cmdline) return GE_NOMEM; for (i = 0; argv[i]; i++) { const char *s = argv[i]; bool quotestr = false; unsigned int orig_p = p; if (s[0] == '\0') { quotestr = true; } else { for (j = 0; s[j]; j++) { if (needs_quote(s[j]) && !is_echo_cmd) { quotestr = true; break; } cmdline[p++] = s[j]; } } if (quotestr) { /* Back up and start over with quotes. */ p = orig_p; cmdline[p++] = '"'; for (j = 0; s[j]; j++) { if (s[j] == '"') { l = 0; for (k = j; k > 0; ) { k--; if (s[k] == '\\') { l++; p--; /* Back up over the \s */ } else { break; } } for (; l > 0; l--) { cmdline[p++] = '\\'; cmdline[p++] = '\\'; } cmdline[p++] = '\\'; cmdline[p++] = '"'; } else { cmdline[p++] = s[j]; } } l = 0; for (k = j; k > 0; ) { k--; if (s[k] == '\\') { l++; p--; /* Back up over the \s */ } else { break; } } for (; l > 0; l--) { cmdline[p++] = '\\'; cmdline[p++] = '\\'; } cmdline[p++] = '"'; } /* Add a space between arguments. */ if (argv[i + 1]) cmdline[p++] = ' '; } cmdline[p++] = '\0'; *rcmdline = cmdline; return 0;; } /* * Convert a normal env array to a Windows environment block, which is * a single block of memory with each entry separated by a \0, and * terminated by two \0. */ static char * win_env_to_block(struct gensio_os_funcs *o, const char **env, gensiods *rsize) { /* * Start with size=2 because this must be terminated with two nil * chars. If the environment was empty, we would only get one nil * char otherwise. We waste a byte, but no big deal. */ gensiods i, size = 2, len; char *envb, *pos; for (i = 0; env[i]; i++) size += strlen(env[i]) + 1; envb = o->zalloc(o, size); if (!envb) return NULL; for (i = 0, pos = envb; env[i]; i++) { len = strlen(env[i]); memcpy(pos, env[i], len); pos += len + 1; } if (rsize) *rsize = size; return envb; } int gensio_win_do_exec(struct gensio_os_funcs *o, const char *argv[], const char **env, const char *start_dir, unsigned int flags, HANDLE *phandle, HANDLE *rin, HANDLE *rout, HANDLE *rerr) { int rv = 0; char *cmdline, *envb = NULL; STARTUPINFOA suinfo; PROCESS_INFORMATION procinfo; HANDLE stdin_m = NULL, stdin_s = NULL; HANDLE stdout_m = NULL, stdout_s = NULL; HANDLE stderr_m = NULL, stderr_s = NULL; if (rerr && (flags & GENSIO_EXEC_STDERR_TO_STDOUT)) return GE_INVAL; rv = argv_to_win_cmdline(o, argv, &cmdline); if (rv) return rv; if (env) { envb = win_env_to_block(o, env, NULL); if (!envb) { rv = GE_NOMEM; goto out; } } memset(&suinfo, 0, sizeof(suinfo)); memset(&procinfo, 0, sizeof(procinfo)); if (!CreatePipe(&stdin_s, &stdin_m, NULL, 0)) goto out_err_conv; if (!SetHandleInformation(stdin_s, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) goto out_err_conv; if (!CreatePipe(&stdout_m, &stdout_s, NULL, 0)) goto out_err_conv; if (!SetHandleInformation(stdout_s, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) goto out_err_conv; if (flags & GENSIO_EXEC_STDERR_TO_STDOUT) { if (!DuplicateHandle(GetCurrentProcess(), stdout_s, GetCurrentProcess(), &stderr_s, 0, TRUE, DUPLICATE_SAME_ACCESS)) goto out_err_conv; } else if (rerr) { if (!CreatePipe(&stderr_m, &stderr_s, NULL, 0)) goto out_err_conv; } else { if (!DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_ERROR_HANDLE), GetCurrentProcess(), &stderr_s, 0, TRUE, DUPLICATE_SAME_ACCESS)) goto out_err_conv; } if (!SetHandleInformation(stderr_s, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) goto out_err_conv; suinfo.cb = sizeof(STARTUPINFO); suinfo.hStdInput = stdin_s; suinfo.hStdOutput = stdout_s; suinfo.hStdError = stderr_s; suinfo.dwFlags |= STARTF_USESTDHANDLES; if (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, envb, start_dir, &suinfo, &procinfo)) goto out_err_conv; /* We have to close these here or we won't see the child process die. */ CloseHandle(stdin_s); CloseHandle(stdout_s); CloseHandle(stderr_s); CloseHandle(procinfo.hThread); *phandle = procinfo.hProcess; *rin = stdin_m; *rout = stdout_m; if (rerr) *rerr = stderr_m; goto out; out_err_conv: rv = gensio_os_err_to_err(o, GetLastError()); if (stdin_m) CloseHandle(stdin_m); if (stdout_m) CloseHandle(stdout_m); if (stderr_m) CloseHandle(stderr_m); if (stdin_s) CloseHandle(stdin_s); if (stdout_s) CloseHandle(stdout_s); if (stderr_s) CloseHandle(stderr_s); out: if (envb) o->free(o, envb); if (cmdline) o->free(o, cmdline); return rv; } static DWORD read_token_info(HANDLE h, TOKEN_INFORMATION_CLASS type, void **rval, DWORD *rlen) { DWORD err, len = 0; void *val; if (GetTokenInformation(h, type, NULL, 0, &len)) /* This should fail. */ return ERROR_INVALID_DATA; err = GetLastError(); assert(err != 0); /* Keep scan-build happy, but probably a good idea. */ if (err != ERROR_INSUFFICIENT_BUFFER) return err; val = malloc(len); if (!val) return STATUS_NO_MEMORY; if (!GetTokenInformation(h, type, val, len, &len)) { free(val); err = GetLastError(); assert(err != 0); /* Keep scan-build happy, but probably a good idea. */ return err; } *rval = val; if (rlen) *rlen = len; return 0; } static DWORD get_logon_sid_from_token(HANDLE h, SID **logon_sid, bool *found) { DWORD err; unsigned int i; TOKEN_GROUPS *grps = NULL; SID *sid = NULL; err = read_token_info(h, TokenGroups, (void **) &grps, NULL); if (err) { /* Not an error if the token doesn't have groups. */ err = 0; goto out_err; } /* Now scan for a logon id SID. */ for (i = 0; i < grps->GroupCount; i++) { if ((grps->Groups[i].Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID) { int len = GetLengthSid(grps->Groups[i].Sid); sid = (SID *) malloc(len); if (!sid) { err = STATUS_NO_MEMORY; goto out_err; } if (!CopySid(len, sid, grps->Groups[i].Sid)) { err = GetLastError(); goto out_err; } *logon_sid = sid; sid = NULL; *found = true; break; } } out_err: if (grps) free(grps); if (sid) free(sid); return err; } static DWORD get_logon_sid(SID *user, SID **logon_sid, bool *rfound) { DWORD err; unsigned int i; bool found = false; WTS_SESSION_INFOA *sesinfo = NULL; DWORD sescount; TOKEN_USER *usid = NULL; HANDLE h = NULL; /* * Try the calling user's token first. */ OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &h); err = get_logon_sid_from_token(h, logon_sid, &found); CloseHandle(h); h = NULL; if (!err && found) { *rfound = true; return 0; } /* * Find a session with the same user SID as the passed in user. */ if (!WTSEnumerateSessionsA(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sesinfo, &sescount)) { err = GetLastError(); assert(err != 0); /* Keep scan-build happy, but probably a good idea. */ goto out_err; } for (i = 0; !found && i < sescount; i++) { if (!WTSQueryUserToken(sesinfo[i].SessionId, &h)) continue; /* Check to make sure it's our user. */ err = read_token_info(h, TokenUser, (void **) &usid, NULL); if (err) goto continue_scan; if (!EqualSid(usid->User.Sid, user)) goto continue_scan; err = get_logon_sid_from_token(h, logon_sid, &found); if (err) goto out_err; continue_scan: if (h) { CloseHandle(h); h = NULL; } if (usid) { free(usid); usid = NULL; } } /* Not finding is not an error, we just report it. */ *rfound = found; err = 0; out_err: if (h) CloseHandle(h); if (sesinfo) WTSFreeMemory(sesinfo); if (usid) free(usid); return err; } static void set_lsa_string(LSA_STRING *a, const char *b) { a->Length = (USHORT) strlen(b); a->MaximumLength = (USHORT)(a->Length + sizeof(*b)); a->Buffer = (char *) b; } static void add_unicode_str(UNICODE_STRING *ustr, const char *str, unsigned int len, char **pos) { unsigned int blen = len * sizeof(wchar_t); ustr->Buffer = (wchar_t *) *pos; mbstowcs(ustr->Buffer, str, len); ustr->Length = blen; ustr->MaximumLength = blen; *pos += blen; } static DWORD get_kerb_logon(const char *user, const char *password, bool interactive, void **logon_info, DWORD *logon_info_len, SECURITY_LOGON_TYPE *logon_type) { DWORD user_chars = mbstowcs(NULL, user, strlen(user)); DWORD user_bytes = user_chars * sizeof(wchar_t); DWORD domain_chars = strchr(user, '\\') - user; DWORD real_user_chars = strlen(user + domain_chars + 1); DWORD logon_len; char *pos; if (password) { DWORD pw_chars = mbstowcs(NULL, password, strlen(password)); DWORD pw_bytes = pw_chars * sizeof(wchar_t); KERB_INTERACTIVE_LOGON *int_logon; /* * KERB_S4U_LOGON must be passed as a single contiguous buffer * that includes all strings, otherwise LsaLogonUser will * complain. Add an extra char for the termination, just in * case. */ logon_len = sizeof(KERB_INTERACTIVE_LOGON) + user_bytes + pw_bytes; int_logon = calloc(logon_len + sizeof(wchar_t), 1); if (!int_logon) return STATUS_NO_MEMORY; int_logon->MessageType = KerbInteractiveLogon; pos = (char *) (int_logon + 1); add_unicode_str(&int_logon->LogonDomainName, user, domain_chars, &pos); user += domain_chars + 1; /* SKip over domain\ */ add_unicode_str(&int_logon->UserName, user, real_user_chars, &pos); add_unicode_str(&int_logon->Password, password, pw_chars, &pos); *logon_info = int_logon; *logon_type = Interactive; } else { /* look up the Kerb authentication provider's index */ KERB_S4U_LOGON *s4u_logon; char *tmpstr, *upnstr; upnstr = malloc(user_chars + 1); if (!upnstr) return STATUS_NO_MEMORY; tmpstr = upnstr; memcpy(tmpstr, user + domain_chars + 1, real_user_chars); tmpstr += real_user_chars; *tmpstr++ = '@'; memcpy(tmpstr, user, domain_chars); tmpstr += domain_chars; *tmpstr = '\0'; /* * KERB_S4U_LOGON must be passed as a single contiguous buffer * that includes all strings, otherwise LsaLogonUser will * complain. Add an extra char for the termination, just in * case. */ logon_len = sizeof(KERB_S4U_LOGON) + user_bytes; s4u_logon = calloc(logon_len + sizeof(wchar_t), 1); if (!s4u_logon) { free(upnstr); return STATUS_NO_MEMORY; } s4u_logon->MessageType = KerbS4ULogon; if (interactive) s4u_logon->Flags = KERB_S4U_LOGON_FLAG_IDENTIFY; pos = (char *) (s4u_logon + 1); add_unicode_str(&s4u_logon->ClientUpn, upnstr, user_chars, &pos); free(upnstr); *logon_info = s4u_logon; *logon_type = Network; } *logon_info_len = logon_len; return 0; } static DWORD get_local_logon(const char *user, const char *password, void **logon_info, DWORD *logon_info_len, SECURITY_LOGON_TYPE *logon_type) { DWORD user_chars = mbstowcs(NULL, user, strlen(user)); DWORD user_bytes = user_chars * sizeof(wchar_t); DWORD logon_len; char *pos; if (password) { DWORD pw_chars = mbstowcs(NULL, password, strlen(password)); DWORD pw_bytes = pw_chars * sizeof(wchar_t); MSV1_0_INTERACTIVE_LOGON *mi_logon; /* * MSV1_0_INTERACTIVE_LOGON must be passed as a single * contiguous buffer that includes all strings, otherwise * LsaLogonUser will complain. Add an extra char for the * termination, just in case. */ logon_len = (sizeof(*mi_logon) + user_bytes + pw_bytes + sizeof(wchar_t)); mi_logon = (MSV1_0_INTERACTIVE_LOGON *) malloc(logon_len); if (!mi_logon) return STATUS_NO_MEMORY; mi_logon->MessageType = MsV1_0InteractiveLogon; pos = (char *) (mi_logon + 1); add_unicode_str(&mi_logon->LogonDomainName, ".", 1, &pos); add_unicode_str(&mi_logon->UserName, user, user_chars, &pos); add_unicode_str(&mi_logon->Password, password, pw_chars, &pos); *logon_info = mi_logon; *logon_type = Interactive; } else { MSV1_0_S4U_LOGON *s4u_logon; /* * MSV1_0_S4U_LOGON must be passed as a single contiguous * buffer that includes all strings, otherwise LsaLogonUser * will complain. Add an extra char for the termination, just * in case. */ logon_len = sizeof(MSV1_0_S4U_LOGON) + user_bytes + sizeof(wchar_t); s4u_logon = (MSV1_0_S4U_LOGON *) calloc(logon_len + sizeof(wchar_t), 1); if (!s4u_logon) return STATUS_NO_MEMORY; s4u_logon->MessageType = MsV1_0S4ULogon; pos = (char *) (s4u_logon + 1); add_unicode_str(&s4u_logon->UserPrincipalName, user, user_chars, &pos); add_unicode_str(&s4u_logon->DomainName, ".", 1, &pos); *logon_info = s4u_logon; *logon_type = Network; } *logon_info_len = logon_len; return 0; } static const char *add_groups[] = { "S-1-2-0", /* LOCAL */ NULL }; /* Supply either isid or sidstr, not both. */ static DWORD append_group(TOKEN_GROUPS *grps, SID *sid, const char *sidstr, DWORD attrs) { SID *new_sid, *free_sid = NULL; size_t len; unsigned int i = grps->GroupCount; int err = 0; if (sidstr) { if (!ConvertStringSidToSid(sidstr, (void **) &free_sid)) return GetLastError(); /* Can't use free_sid directly, it's allocated with LocalAlloc(). */ sid = free_sid; } len = GetLengthSid(sid); new_sid = malloc(len); if (!new_sid) { err = STATUS_NO_MEMORY; goto out_err; } if (!CopySid(len, new_sid, sid)) { err = GetLastError(); free(new_sid); goto out_err; } grps->Groups[i].Attributes = attrs; grps->Groups[i].Sid = new_sid; grps->GroupCount++; out_err: if (free_sid) LocalFree(free_sid); return err; } static void free_groups(TOKEN_GROUPS *grps) { unsigned int i; for (i = 0; i < grps->GroupCount; i++) free(grps->Groups[i].Sid); free(grps); } #if 0 static void pr_sid(int indent, const char *str, SID *sid) { char *sidstr; if (!sid) { printf("%*s%s: NULL Sid\n", indent, "", str); } else if (ConvertSidToStringSidA(sid, &sidstr)) { printf("%*s%s: %s\n", indent, "", str, sidstr); LocalFree(sidstr); } else { printf("%*s%s: Bad Sid\n", indent, "", str); } } static void print_sid(const char *str, SID *sid) { pr_sid(0, str, sid); } #endif static wchar_t * str_to_wstr(const char *str) { DWORD nchars; DWORD nbytes; wchar_t *wstr; if (!str) return NULL; nchars = mbstowcs(NULL, str, strlen(str)); nbytes = nchars * sizeof(wchar_t); wstr = calloc(nbytes + sizeof(wchar_t), 1); if (!wstr) return NULL; mbstowcs(wstr, str, nchars); return wstr; } int gensio_win_get_user_token(const char *user, const char *password, const char *src_module, const char **groups, bool interactive, HANDLE *userh) { HANDLE lsah; NTSTATUS rv; DWORD err = 0; void *logon_info = NULL; LSA_STRING package_name; ULONG package_auth; wchar_t *wuser = NULL; bool domain_user; DWORD logon_len; TOKEN_SOURCE token_source; LSA_STRING origin_name; void *profile = NULL; DWORD profile_len = 0; LUID logon_id; HANDLE htok = NULL, tmptok; QUOTA_LIMITS quota_limits; NTSTATUS sub_status; PROFILEINFOW profile_info = { 0 }; SECURITY_LOGON_TYPE logon_type; TOKEN_USER *usersid = NULL; SID *logon_sid = NULL; TOKEN_GROUPS *extra_groups = NULL; MSV1_0_INTERACTIVE_PROFILE *iprofile; bool found; DWORD len; const char **grpp; domain_user = strchr(user, '\\'); if (interactive && domain_user) { LSA_STRING name; LSA_OPERATIONAL_MODE dummy1; /* Interactive, get a token we can use for that. */ set_lsa_string(&name, src_module); rv = LsaRegisterLogonProcess(&name, &lsah, &dummy1); } else { /* Just getting information, no need for a token requiring auth. */ rv = LsaConnectUntrusted(&lsah); } if (rv) return LsaNtStatusToWinError(rv); if (domain_user) set_lsa_string(&package_name, MICROSOFT_KERBEROS_NAME_A); else set_lsa_string(&package_name, MSV1_0_PACKAGE_NAME); rv = LsaLookupAuthenticationPackage(lsah, &package_name, &package_auth); if (rv) { err = LsaNtStatusToWinError(rv); goto out_err; } if (domain_user) err = get_kerb_logon(user, password, interactive, &logon_info, &logon_len, &logon_type); else err = get_local_logon(user, password, &logon_info, &logon_len, &logon_type); if (err) goto out_err; /* * This information is copied into the resulting token. Note that * SourceName is an 8 character ASCII buffer. */ AllocateLocallyUniqueId(&token_source.SourceIdentifier); strncpy(token_source.SourceName, src_module, 7); token_source.SourceName[7] = 0; set_lsa_string(&origin_name, src_module); /* * Do a first run. For just query request (not interactive) this * is all we need, but for interactive, we use this to pull * information from for the real logon. * * Pass in NULL for groups so this will generate a new logon sid, * which we may or may not use. */ rv = LsaLogonUser(lsah, &origin_name, logon_type, package_auth, logon_info, logon_len, NULL, &token_source, &profile, &profile_len, &logon_id, &htok, "a_limits, &sub_status); if (rv) { err = LsaNtStatusToWinError(rv); goto out_err; } if (profile) LsaFreeReturnBuffer(profile); if (!interactive) /* We have all we need, no setup is necessary. */ goto out_finish; /* * For interactive, the created handle does not have a proper * logon SID (maybe) and doesn't have the extra groups. So we * will need to find the right SID and use that. If the user is * currently logged on, we will pull that logon sid. If they are * not, we will use the logon SID from the token we just created. */ /* First find the proper logon sid. */ err = read_token_info(htok, TokenUser, (void **) &usersid, NULL); if (err) goto out_err; err = get_logon_sid(usersid->User.Sid, &logon_sid, &found); if (err) goto out_err; if (!found) { /* * The user isn't logged on, use the logon sid from the token. * we just created. */ err = get_logon_sid_from_token(htok, &logon_sid, &found); if (err) goto out_err; if (!found) { err = ERROR_INVALID_DATA; goto out_err; } } /* * Now add the logon sid to the extra groups. If it's a network * logon, convert it to interactive by adding the proper sids. */ len = sizeof(TOKEN_GROUPS) + sizeof(SID_AND_ATTRIBUTES); for (grpp = add_groups; grpp && *grpp; grpp++) len += sizeof(SID_AND_ATTRIBUTES); for (grpp = groups; grpp && *grpp; grpp++) len += sizeof(SID_AND_ATTRIBUTES); extra_groups = (TOKEN_GROUPS *) malloc(len); if (!extra_groups) { err = STATUS_NO_MEMORY; goto out_err; } memset(extra_groups, 0, len); append_group(extra_groups, logon_sid, NULL, (SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY | SE_GROUP_LOGON_ID)); for (grpp = add_groups; grpp && *grpp; grpp++) { err = append_group(extra_groups, NULL, *grpp, (SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY)); if (err) goto out_err; } for (grpp = groups; grpp && *grpp; grpp++) { err = append_group(extra_groups, NULL, *grpp, (SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY)); if (err) goto out_err; } /* Now get the actual token. */ rv = LsaLogonUser(lsah, &origin_name, logon_type, package_auth, logon_info, logon_len, extra_groups, &token_source, &profile, &profile_len, &logon_id, &tmptok, "a_limits, &sub_status); if (rv) { err = LsaNtStatusToWinError(rv); goto out_err; } CloseHandle(htok); htok = tmptok; /* Interactive logons should have the profile loaded. */ iprofile = (MSV1_0_INTERACTIVE_PROFILE *) profile; if (iprofile->MessageType == MsV1_0InteractiveProfile) profile_info.lpServerName = iprofile->LogonServer.Buffer; profile_info.dwSize = sizeof(profile_info); profile_info.dwFlags = PI_NOUI; wuser = str_to_wstr(user); if (!wuser) { err = STATUS_NO_MEMORY; goto out_err; } profile_info.lpUserName = wuser; if (!LoadUserProfileW(htok, &profile_info)) { err = GetLastError(); goto out_err; } out_finish: if (logon_type != Network) { /* * We want an impersonation token. Network tokens do that, * but others do not. */ if (!DuplicateToken(htok, SecurityImpersonation, &tmptok)) err = GetLastError(); CloseHandle(htok); htok = tmptok; } *userh = htok; htok = NULL; out_err: if (extra_groups) free_groups(extra_groups); if (usersid) free(usersid); if (wuser) free(wuser); if (logon_info) free(logon_info); if (htok) { if (profile_info.hProfile) UnloadUserProfile(htok, profile_info.hProfile); CloseHandle(htok); } if (profile) LsaFreeReturnBuffer(profile); if (lsah) LsaDeregisterLogonProcess(lsah); LsaClose(lsah); return err; } int gensio_win_pty_alloc(struct gensio_os_funcs *o, HANDLE *rreadh, HANDLE *rwriteh, HANDLE *child_in, HANDLE *child_out, HPCON *rptyh) { HANDLE readh_m = NULL, readh_s = NULL; HANDLE writeh_m = NULL, writeh_s = NULL; HANDLE imptokh; HPCON ptyh = NULL; COORD winsize; HRESULT hr; int err; if (!CreatePipe(&writeh_s, &writeh_m, NULL, 0)) goto out_err_conv; if (!SetHandleInformation(writeh_s, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) goto out_err_conv; if (!CreatePipe(&readh_m, &readh_s, NULL, 0)) goto out_err_conv; if (!SetHandleInformation(readh_s, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) goto out_err_conv; if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &imptokh)) { if (GetLastError() != ERROR_NO_TOKEN) /* Error getting the token. */ goto out_err_conv; /* No token was present, just create the pseudo console. */ } else { /* * An impersonation token is present, the pseudo console will * be created in a special child process. */ CloseHandle(imptokh); goto out; } winsize.X = 80; winsize.Y = 25; hr = CreatePseudoConsole(winsize, writeh_s, readh_s, 0, &ptyh); if (hr != S_OK) { if (HRESULT_FACILITY(hr) == FACILITY_WIN32) err = gensio_os_err_to_err(o, HRESULT_CODE(hr)); else err = gensio_os_err_to_err(o, hr); /* Force an OS_ERR. */ goto out_err; } out: *child_in = writeh_s; *child_out = readh_s; *rwriteh = writeh_m; *rreadh = readh_m; *rptyh = ptyh; return 0; out_err_conv: err = gensio_os_err_to_err(o, GetLastError()); out_err: if (ptyh) ClosePseudoConsole(ptyh); if (readh_m) CloseHandle(readh_m); if (readh_s) CloseHandle(readh_s); if (writeh_m) CloseHandle(writeh_m); if (writeh_s) CloseHandle(writeh_s); return err; } /* * Start a special process that will be an intermediary between this * process and the main user process. * * If you create a pseudo console under Windows, it will be created * with the integrity level of the calling process, even if the * impersonation token is set. This means that the child process will * not be able to do certain operations on the console handles, like * WriteConsoleInput. A discussion of the security limitiations is at * https://learn.microsoft.com/en-us/windows/console/console-buffer-security-and-access-rights * * This was discussed by me with others at: * * https://learn.microsoft.com/en-us/answers/questions/1040676/createpseudoconsole-with-reduced-integrity-level.html * * The only reasonable approach seems to be to create another process * with the user's token and have it create the pty. That process is * gensio_pty_helper in tools. That way the pty gets created at the * user's integrity level. We talk to that process over it's stdio, * which is relayed to the real child process. * * The environment and starting directory can be set here and it will * propagate down. However, the command line is a different issue. * That is passed in some shared memory. * * There is yet another snag, though. The console resize events need * to be done on the pty. So another pipe is created to send commands * to gensio_pty_helper to handle resize events. * * The command line shared memory handle, size, and the rcontrol * shared memory handle is passed on the command line to * gensio_pty_helper. * * Also, the exit code must be propagated back through gensio_pty_helper. * * This is not really ideal, as the subprocess is not directly * attached to us and the pid really isn't right. But there's not * much else we can do. */ static int start_pty_helper(struct gensio_os_funcs *o, HANDLE tokh, const char *cmdline, char *envb, const char *start_dir, STARTUPINFO *si, PROCESS_INFORMATION *procinfo, HANDLE *rcontrol) { SECURITY_ATTRIBUTES secattr; HANDLE shmem = NULL, ctl_s = NULL, ctl_m = NULL; DWORD cmdline_len; char *buf = NULL; char cmd[50]; int err = 0; if (!CreatePipe(&ctl_s, &ctl_m, NULL, 0)) goto out_err_conv; if (!SetHandleInformation(ctl_s, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) goto out_err_conv; cmdline_len = strlen(cmdline) + 1; memset(&secattr, 0, sizeof(secattr)); secattr.nLength = sizeof(secattr); secattr.bInheritHandle = TRUE; /* Add 1 to the length for the version. */ shmem = CreateFileMappingA(INVALID_HANDLE_VALUE, &secattr, PAGE_READWRITE, 0, cmdline_len + 1, NULL); if (!shmem) goto out_err_conv; buf = (char *) MapViewOfFile(shmem, FILE_MAP_ALL_ACCESS, 0, 0, cmdline_len + 1); if (!buf) goto out_err_conv; buf[0] = 1; /* Version */ memcpy(buf + 1, cmdline, cmdline_len); UnmapViewOfFile(buf); /* Pass the handle in the command line. */ snprintf(cmd, sizeof(cmd), "gensio_pty_helper %llu %lu %llu", (unsigned long long) (intptr_t) shmem, (unsigned long) cmdline_len + 1, (unsigned long long) (intptr_t) ctl_s); if (!CreateProcessAsUserA(tokh, NULL, cmd, NULL, NULL, TRUE, (NORMAL_PRIORITY_CLASS | CREATE_NEW_PROCESS_GROUP), envb, start_dir, si, procinfo)) goto out_err_conv; out: if (shmem) CloseHandle(shmem); if (ctl_s) CloseHandle(ctl_s); if (err && ctl_m) CloseHandle(ctl_m); else *rcontrol = ctl_m; return err; out_err_conv: err = gensio_os_err_to_err(o, GetLastError()); goto out; } int gensio_win_pty_start(struct gensio_os_funcs *o, HPCON ptyh, HANDLE *child_in, HANDLE *child_out, const char **argv, const char **env, const char *start_dir, HANDLE *child, HANDLE *rcontrol) { char *cmdline, *envb = NULL; STARTUPINFOEX si; PROCESS_INFORMATION procinfo; SIZE_T len; HANDLE tokh = NULL, imptokh = NULL, control = NULL; int err; bool setuser = true; bool attrs_added = false; memset(&si, 0, sizeof(si)); memset(&procinfo, 0, sizeof(procinfo)); /* Keep scan-build happy. */ err = argv_to_win_cmdline(o, argv, &cmdline); if (err) return err; if (env) { envb = win_env_to_block(o, env, NULL); if (!envb) { err = GE_NOMEM; goto out_err; } } si.StartupInfo.cb = sizeof(STARTUPINFOEX); /* * This is not in any of the examples on Microsoft's site, but if * the application has stdio relocated, anything that uses stdio * in the child will get the parent's stdio. If the child opens * the console, all is good, but that's not the normal case. * * So set the stdio to the pipe, too. * * Plus this is necessary if we are using the pty helper. */ si.StartupInfo.hStdInput = *child_in; si.StartupInfo.hStdOutput = *child_out; si.StartupInfo.hStdError = *child_out; si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES; /* * Get the impersonation token, convert it to a real token, and * create the process as that user. */ if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &imptokh)) { if (GetLastError() == ERROR_NO_TOKEN) /* Impersonation token not set, just do a normal create process. */ setuser = false; else goto out_err_conv; } if (setuser) { if (!DuplicateTokenEx(imptokh, 0, NULL, SecurityImpersonation, TokenPrimary, &tokh)) goto out_err_conv; err = start_pty_helper(o, tokh, cmdline, envb, start_dir, &si.StartupInfo, &procinfo, &control); if (err) goto out_err; } else { InitializeProcThreadAttributeList(NULL, 1, 0, &len); si.lpAttributeList = o->zalloc(o, len); if (!si.lpAttributeList) { err = GE_NOMEM; goto out_err; } if (!InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &len)) goto out_err_conv; if (!UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, ptyh, sizeof(ptyh), NULL, NULL)) goto out_err_conv; attrs_added = true; if (!CreateProcess(NULL, cmdline, NULL, NULL, FALSE, (NORMAL_PRIORITY_CLASS | EXTENDED_STARTUPINFO_PRESENT | CREATE_NEW_PROCESS_GROUP), envb, start_dir, &si.StartupInfo, &procinfo)) goto out_err_conv; } CloseHandle(*child_in); *child_in = NULL; CloseHandle(*child_out); *child_out = NULL; if (imptokh) CloseHandle(imptokh); if (tokh) CloseHandle(tokh); CloseHandle(procinfo.hThread); DeleteProcThreadAttributeList(si.lpAttributeList); o->free(o, si.lpAttributeList); *child = procinfo.hProcess; *rcontrol = control; return 0; out_err_conv: err = gensio_os_err_to_err(o, GetLastError()); out_err: if (imptokh) CloseHandle(imptokh); if (tokh) CloseHandle(tokh); if (attrs_added) DeleteProcThreadAttributeList(si.lpAttributeList); if (si.lpAttributeList) o->free(o, si.lpAttributeList); if (cmdline) o->free(o, cmdline); if (envb) o->free(o, envb); return err; } bool gensio_os_loadlib(struct gensio_os_funcs *o, const char *name) { char *dllname; char *initfuncname; int (*initfunc)(struct gensio_os_funcs *); HINSTANCE handle; int err; dllname = gensio_alloc_sprintf(o, "libgensio_%s.DLL", name); if (!dllname) return false; initfuncname = gensio_alloc_sprintf(o, "gensio_init_%s", name); if (!initfuncname) { o->free(o, dllname); return false; } handle = LoadLibrary(dllname); o->free(o, dllname); if (!handle) { o->free(o, initfuncname); return false; } initfunc = (int (*)(struct gensio_os_funcs *)) GetProcAddress(handle, initfuncname); o->free(o, initfuncname); if (!initfunc) { FreeLibrary(handle); return false; } err = initfunc(o); if (err) { FreeLibrary(handle); return false; } /* Libraries are never unloaded, so there's no need to manage handle. */ return true; } #else /* _WIN32 */ #include #include struct stdio_mode { int orig_file_flags; }; int gensio_unix_do_nonblock(struct gensio_os_funcs *o, int fd, struct stdio_mode **rm) { int rv; struct stdio_mode *r = NULL; rv = fcntl(fd, F_GETFL, 0); if (rv == -1) return gensio_os_err_to_err(o, errno); if (!*rm) { r = o->zalloc(o, sizeof(*r)); if (!r) return GE_NOMEM; r->orig_file_flags = rv; } rv |= O_NONBLOCK; if (fcntl(fd, F_SETFL, rv) == -1) { if (r) o->free(o, r); return gensio_os_err_to_err(o, errno); } if (r) *rm = r; return 0; } void gensio_unix_do_cleanup_nonblock(struct gensio_os_funcs *o, int fd, struct stdio_mode **m) { if (!*m) return; fcntl(fd, F_SETFL, (*m)->orig_file_flags); o->free(o, *m); *m = NULL; } #if HAVE_DECL_TIOCSRS485 #include #endif #ifdef HAVE_TERMIOS2 #include typedef struct termios2 g_termios; #else #include #include typedef struct termios g_termios; #endif struct gensio_unix_termios { g_termios orig_termios; int orig_mctl; g_termios curr_termios; bool break_set; bool recv_err_enabled; /* * If do_recv_err is set, if this is 1 then we have received a \377, * and if this is 2 we have received \377\0. */ unsigned int brk_pos; /* Set at termios time so we aren't misinterpreting received data. */ bool do_recv_err; #if HAVE_DECL_TIOCSRS485 struct serial_rs485 rs485; struct serial_rs485 orig_rs485; #endif }; #ifdef HAVE_TERMIOS2 int ioctl(int fd, int op, ...); /* * termios2 allows the setting of custom serial port speeds. * * There is unfortunate complexity with handling termios2 on Linux. * You cannot include asm/termios.h and termios.h or sys/ioctl.h at * the same time. So that means a lot of stuff has to be be handled * by hand, not with the tcxxx() functions. The standard tcxxx() * function do not use the termios2 ioctls when talking to the * kernel (at the current time). It's kind of a mess. */ static int set_termios(int fd, struct termios2 *t) { return ioctl(fd, TCSETS2, t); } static int get_termios(int fd, struct termios2 *t) { return ioctl(fd, TCGETS2, t); } static int do_flush(int fd, int val) { return ioctl(fd, TCFLSH, val); } static int set_flowcontrol(int fd, bool val) { return ioctl(fd, TCXONC, val ? TCOOFF : TCOON); } static int do_break(int fd) { return ioctl(fd, TCSBRK, 0); } #else static int set_termios(int fd, struct termios *t) { return tcsetattr(fd, TCSANOW, t); } static int get_termios(int fd, struct termios *t) { return tcgetattr(fd, t); } static int do_flush(int fd, int val) { return tcflush(fd, val); } static int set_flowcontrol(int fd, bool val) { return tcflow(fd, val ? TCOOFF : TCOON); } static int do_break(int fd) { return tcsendbreak(fd, 0); } #endif static void s_cfmakeraw(g_termios *termios_p) { unsigned int i; /* Zero out the c_cc array. */ for (i = 0; i < sizeof(termios_p->c_cc); i++) termios_p->c_cc[i] = 0; /* Standard make raw. */ termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); termios_p->c_oflag &= ~OPOST; termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); termios_p->c_cflag &= ~(CSIZE|PARENB); termios_p->c_cflag |= CS8; termios_p->c_cc[VMIN] = 1; /* Our additions to makeraw, to make things always consistent. */ termios_p->c_iflag &= ~(IXOFF | IXANY); termios_p->c_iflag &= ~(IGNPAR|INPCK); termios_p->c_iflag |= IGNBRK; termios_p->c_oflag &= ~(ONLCR); termios_p->c_lflag &= ~(ECHOK|ECHOE|ECHONL); #ifdef ECHOCTL termios_p->c_lflag &= ~ECHOCTL; #endif #ifdef ECHOPRT termios_p->c_lflag &= ~ECHOPRT; #endif #ifdef ECHOKE termios_p->c_lflag &= ~ECHOKE; #endif termios_p->c_cflag &= ~(CRTSCTS | PARODD); termios_p->c_cflag |= CREAD; termios_p->c_cc[VSTART] = 17; termios_p->c_cc[VSTOP] = 19; } int gensio_unix_setup_termios(struct gensio_os_funcs *o, int fd, struct gensio_unix_termios **it) { struct gensio_unix_termios *t; int rv; if (*it) return 0; t = o->zalloc(o, sizeof(*t)); if (!t) return GE_NOMEM; rv = get_termios(fd, &t->curr_termios); if (rv) { o->free(o, t); return gensio_os_err_to_err(o, errno); } t->orig_termios = t->curr_termios; ioctl(fd, TIOCMGET, &t->orig_mctl); #if HAVE_DECL_TIOCSRS485 ioctl(fd, TIOCGRS485, &t->orig_rs485); #endif s_cfmakeraw(&t->curr_termios); rv = set_termios(fd, &t->curr_termios); if (rv) { o->free(o, t); return gensio_os_err_to_err(o, errno); } *it = t; return 0; } void gensio_unix_cleanup_termios(struct gensio_os_funcs *o, struct gensio_unix_termios **it, int fd) { if (!*it) return; #if HAVE_DECL_TIOCSRS485 ioctl(fd, TIOCSRS485, &(*it)->orig_rs485); #endif ioctl(fd, TIOCMSET, &(*it)->orig_mctl); set_termios(fd, &(*it)->orig_termios); o->free(o, *it); *it = NULL; } static struct baud_rates_s { int real_rate; int val; } baud_rates[] = { { 50, B50 }, { 75, B75 }, { 110, B110 }, { 134, B134 }, { 150, B150 }, { 200, B200 }, { 300, B300 }, { 600, B600 }, { 1200, B1200 }, { 1800, B1800 }, { 2400, B2400 }, { 4800, B4800 }, { 9600, B9600 }, /* We don't support 14400 baud */ { 19200, B19200 }, /* We don't support 28800 baud */ { 38400, B38400 }, { 57600, B57600 }, { 115200, B115200 }, #ifdef B230400 { 230400, B230400 }, #endif #ifdef B460800 { 460800, B460800 }, #endif #ifdef B500000 { 500000, B500000 }, #endif #ifdef B576000 { 576000, B576000 }, #endif #ifdef B921600 { 921600, B921600 }, #endif #ifdef B1000000 { 1000000, B1000000 }, #endif #ifdef B1152000 { 1152000, B1152000 }, #endif #ifdef B1500000 { 1500000, B1500000 }, #endif #ifdef B2000000 { 2000000, B2000000 }, #endif #ifdef B2500000 { 2500000, B2500000 }, #endif #ifdef B3000000 { 3000000, B3000000 }, #endif #ifdef B3500000 { 3500000, B3500000 }, #endif #ifdef B4000000 { 4000000, B4000000 }, #endif }; #define BAUD_RATES_LEN ((sizeof(baud_rates) / sizeof(struct baud_rates_s))) static int set_baud_rate(g_termios *t, int rate) { unsigned int i; for (i = 0; i < BAUD_RATES_LEN; i++) { if (rate == baud_rates[i].real_rate) { #ifdef HAVE_TERMIOS2 t->c_cflag &= ~CBAUD; t->c_cflag |= baud_rates[i].val; t->c_ispeed = rate; t->c_ospeed = rate; #else cfsetispeed(t, baud_rates[i].val); cfsetospeed(t, baud_rates[i].val); #endif return 0; } } #ifdef HAVE_TERMIOS2 t->c_cflag &= ~CBAUD; t->c_cflag |= CBAUDEX; t->c_ispeed = rate; t->c_ospeed = rate; return 0; #endif return GE_INVAL; } static int get_baud_rate(g_termios *t) { unsigned int i; int baud_rate; #ifdef HAVE_TERMIOS2 if ((t->c_cflag & CBAUD) == CBAUDEX) return t->c_ospeed; baud_rate = t->c_cflag & CBAUD; #else baud_rate = cfgetospeed(t); #endif for (i = 0; i < BAUD_RATES_LEN; i++) { if (baud_rate == baud_rates[i].val) return baud_rates[i].real_rate; } return 0; } static int process_rs485(struct gensio_os_funcs *o, struct gensio_unix_termios *t, int fd, const char *str) { #if HAVE_DECL_TIOCSRS485 int argc, i; const char **argv; char *end; int err; if (!str || strcasecmp(str, "off") == 0) { t->rs485.flags &= ~SER_RS485_ENABLED; return 0; } err = gensio_str_to_argv(o, str, &argc, &argv, ":"); if (err) return err; if (argc < 2) return GE_INVAL; t->rs485.delay_rts_before_send = strtoul(argv[0], &end, 10); if (end == argv[0] || *end != '\0') goto out_inval; t->rs485.delay_rts_after_send = strtoul(argv[1], &end, 10); if (end == argv[1] || *end != '\0') goto out_inval; for (i = 2; i < argc; i++) { if (strcmp(argv[i], "rts_on_send") == 0) { t->rs485.flags |= SER_RS485_RTS_ON_SEND; } else if (strcmp(argv[i], "rts_after_send") == 0) { t->rs485.flags |= SER_RS485_RTS_AFTER_SEND; } else if (strcmp(argv[i], "rx_during_tx") == 0) { t->rs485.flags |= SER_RS485_RX_DURING_TX; #ifdef SER_RS485_TERMINATE_BUS } else if (strcmp(argv[i], "terminate_bus") == 0) { t->rs485.flags |= SER_RS485_TERMINATE_BUS; #endif } else { goto out_inval; } } t->rs485.flags |= SER_RS485_ENABLED; out: gensio_argv_free(o, argv); return err; out_inval: err = GE_INVAL; goto out; #else return GE_NOTSUP; #endif } int gensio_unix_termios_control(struct gensio_os_funcs *o, int op, bool get, intptr_t val, struct gensio_unix_termios **it, int fd) { int rv = 0, nval, modemstate; struct gensio_unix_termios *t; switch (op) { case GENSIO_IOD_CONTROL_SERDATA: case GENSIO_IOD_CONTROL_BAUD: case GENSIO_IOD_CONTROL_PARITY: case GENSIO_IOD_CONTROL_XONXOFF: case GENSIO_IOD_CONTROL_RTSCTS: case GENSIO_IOD_CONTROL_DATASIZE: case GENSIO_IOD_CONTROL_STOPBITS: case GENSIO_IOD_CONTROL_LOCAL: case GENSIO_IOD_CONTROL_HANGUP_ON_DONE: case GENSIO_IOD_CONTROL_IXONXOFF: case GENSIO_IOD_CONTROL_RS485: case GENSIO_IOD_CONTROL_APPLY: case GENSIO_IOD_CONTROL_SET_BREAK: rv = gensio_unix_setup_termios(o, fd, it); if (rv) return rv; assert(*it); break; case GENSIO_IOD_CONTROL_FREE_SERDATA: o->free(o, (void *) val); return 0; default: break; } t = *it; switch (op) { case GENSIO_IOD_CONTROL_SERDATA: if (get) { g_termios *rt; rt = o->zalloc(o, sizeof(*t)); if (!rt) return GE_NOMEM; *rt = t->curr_termios; *((void **) val) = rt; } else { t->curr_termios = *((g_termios *) val); return 0; } break; case GENSIO_IOD_CONTROL_BAUD: if (get) { rv = get_baud_rate(&t->curr_termios); if (rv == 0) return GE_IOERR; *((int *) val) = rv; rv = 0; } else { rv = set_baud_rate(&t->curr_termios, val); } break; case GENSIO_IOD_CONTROL_PARITY: if (get) { if (t->curr_termios.c_cflag & PARENB) { #ifdef CMSPAR if (t->curr_termios.c_cflag & CMSPAR) { if (t->curr_termios.c_cflag & PARODD) *((int *) val) = GENSIO_SER_PARITY_MARK; else *((int *) val) = GENSIO_SER_PARITY_SPACE; break; } #endif if (t->curr_termios.c_cflag & PARODD) *((int *) val) = GENSIO_SER_PARITY_ODD; else *((int *) val) = GENSIO_SER_PARITY_EVEN; } else { *((int *) val) = GENSIO_SER_PARITY_NONE; } } else { switch (val) { case GENSIO_SER_PARITY_NONE: t->curr_termios.c_cflag &= ~PARENB; break; case GENSIO_SER_PARITY_ODD: t->curr_termios.c_cflag |= PARENB | PARODD; break; case GENSIO_SER_PARITY_EVEN: t->curr_termios.c_cflag |= PARENB; t->curr_termios.c_cflag &= ~PARODD; break; #ifdef CMSPAR case GENSIO_SER_PARITY_MARK: t->curr_termios.c_cflag |= PARENB | PARODD | CMSPAR; break; case GENSIO_SER_PARITY_SPACE: t->curr_termios.c_cflag |= PARENB | CMSPAR; t->curr_termios.c_cflag &= ~PARODD; break; #endif default: return GE_NOTSUP; } } break; case GENSIO_IOD_CONTROL_XONXOFF: if (get) { if (t->curr_termios.c_iflag & IXON) *((int *) val) = 1; else *((int *) val) = 0; } else { if (val) { t->curr_termios.c_iflag |= IXON; t->curr_termios.c_cc[VSTART] = 17; t->curr_termios.c_cc[VSTOP] = 19; } else { t->curr_termios.c_iflag &= ~IXON; } } break; case GENSIO_IOD_CONTROL_RTSCTS: if (get) { if (t->curr_termios.c_cflag & CRTSCTS) *((int *) val) = 1; else *((int *) val) = 0; } else { if (val) t->curr_termios.c_cflag |= CRTSCTS; else t->curr_termios.c_cflag &= ~CRTSCTS; } break; case GENSIO_IOD_CONTROL_DATASIZE: if (get) { switch (t->curr_termios.c_cflag & CSIZE) { case CS5: *((int *) val) = 5; break; case CS6: *((int *) val) = 6; break; case CS7: *((int *) val) = 7; break; case CS8: *((int *) val) = 8; break; } } else { switch (val) { case 5: nval = CS5; break; case 6: nval = CS6; break; case 7: nval = CS7; break; case 8: nval = CS8; break; default: return GE_INVAL; } t->curr_termios.c_cflag &= ~CSIZE; t->curr_termios.c_cflag |= nval; } break; case GENSIO_IOD_CONTROL_STOPBITS: if (get) { if (t->curr_termios.c_cflag & CSTOPB) *((int *) val) = 2; else *((int *) val) = 1; } else { if (val == 1) t->curr_termios.c_cflag &= ~CSTOPB; else if (val == 2) t->curr_termios.c_cflag |= CSTOPB; else return GE_INVAL; } break; case GENSIO_IOD_CONTROL_LOCAL: if (get) { *((int *) val) = !!(t->curr_termios.c_cflag & CLOCAL); } else { if (val) t->curr_termios.c_cflag |= CLOCAL; else t->curr_termios.c_cflag &= ~CLOCAL; } break; case GENSIO_IOD_CONTROL_HANGUP_ON_DONE: if (get) { *((int *) val) = !!(t->curr_termios.c_cflag & HUPCL); } else { /* * Setup hupcl on the original termios that will be * restored as wellas the current termios. Otherwise when * we close will will restore the original termios and * hupcl won't work. */ if (val) { t->orig_termios.c_cflag |= HUPCL; t->curr_termios.c_cflag |= HUPCL; } else { t->orig_termios.c_cflag &= ~HUPCL; t->curr_termios.c_cflag &= ~HUPCL; } } break; case GENSIO_IOD_CONTROL_IXONXOFF: if (get) { if (t->curr_termios.c_iflag & IXOFF) *((int *) val) = 1; else *((int *) val) = 0; } else { if (val) { t->curr_termios.c_iflag |= IXOFF; t->curr_termios.c_cc[VSTART] = 17; t->curr_termios.c_cc[VSTOP] = 19; } else { t->curr_termios.c_iflag &= ~IXOFF; } } break; case GENSIO_IOD_CONTROL_RS485: rv = process_rs485(o, t, fd, (const char *) val); break; case GENSIO_IOD_CONTROL_APPLY: rv = set_termios(fd, &t->curr_termios); if (!rv) { bool nbval = !!t->recv_err_enabled; if (nbval != t->do_recv_err) { t->do_recv_err = nbval; t->brk_pos = 0; } } if (rv) { rv = gensio_os_err_to_err(o, errno); #if HAVE_DECL_TIOCSRS485 } else if (t->rs485.flags & SER_RS485_ENABLED) { if (ioctl(fd, TIOCSRS485, &t->rs485) < 0) rv = gensio_os_err_to_err(o, errno); } else { /* If the disable fails, we don't care. */ ioctl(fd, TIOCSRS485, &t->rs485); #endif } break; case GENSIO_IOD_CONTROL_SET_BREAK: if (get) { *((int *) val) = t->break_set; } else { if (val) nval = TIOCSBRK; else nval = TIOCCBRK; if (ioctl(fd, nval) == -1) { if (errno != ENOTTY) /* Happens with PTYs. */ return gensio_os_err_to_err(o, errno); } t->break_set = val; } break; case GENSIO_IOD_CONTROL_SEND_BREAK: if (get) { *((int *) val) = 0; } else { rv = do_break(fd); if (rv) rv = gensio_os_err_to_err(o, errno); } break; case GENSIO_IOD_CONTROL_ENABLE_RECV_ERR: if (get) { *((int *) val) = t->recv_err_enabled; } else { if (val) { t->curr_termios.c_iflag &= ~IGNBRK; t->curr_termios.c_iflag &= ~IGNPAR; t->curr_termios.c_iflag |= PARMRK; t->curr_termios.c_iflag |= INPCK; } else { t->curr_termios.c_iflag |= IGNBRK; t->curr_termios.c_iflag |= IGNPAR; t->curr_termios.c_iflag &= ~PARMRK; t->curr_termios.c_iflag &= ~INPCK; } t->recv_err_enabled = val; } break; case GENSIO_IOD_CONTROL_DTR: if (ioctl(fd, TIOCMGET, &nval) == -1) return gensio_os_err_to_err(o, errno); if (get) { *((int *) val) = !!(nval & TIOCM_DTR); } else { if (val) nval |= TIOCM_DTR; else nval &= ~TIOCM_DTR; if (ioctl(fd, TIOCMSET, &nval) == -1) return gensio_os_err_to_err(o, errno); } break; case GENSIO_IOD_CONTROL_RTS: if (ioctl(fd, TIOCMGET, &nval) == -1) return gensio_os_err_to_err(o, errno); if (get) { *((int *) val) = !!(nval & TIOCM_RTS); } else { if (val) nval |= TIOCM_RTS; else nval &= ~TIOCM_RTS; if (ioctl(fd, TIOCMSET, &nval) == -1) return gensio_os_err_to_err(o, errno); } break; case GENSIO_IOD_CONTROL_MODEMSTATE: if (!get) return GE_NOTSUP; if (ioctl(fd, TIOCMGET, &nval) == -1) { if (errno == ENOTTY) nval = 0; /* Happens with PTYs. */ else return gensio_os_err_to_err(o, errno); } modemstate = 0; if (nval & TIOCM_CD) modemstate |= GENSIO_SER_MODEMSTATE_CD; if (nval & TIOCM_RI) modemstate |= GENSIO_SER_MODEMSTATE_RI; if (nval & TIOCM_DSR) modemstate |= GENSIO_SER_MODEMSTATE_DSR; if (nval & TIOCM_CTS) modemstate |= GENSIO_SER_MODEMSTATE_CTS; *((int *) val) = modemstate; break; case GENSIO_IOD_CONTROL_FLOWCTL_STATE: if (get) return GE_NOTSUP; set_flowcontrol(fd, val); break; } return rv; } #define ERRHANDLE() \ do { \ int err = 0; \ if (rv < 0) { \ if (errno == EINTR) \ goto retry; \ if (errno == EWOULDBLOCK || errno == EAGAIN) \ rv = 0; /* Handle like a zero-byte write. */ \ else { \ err = errno; \ assert(err); \ } \ } else if (rv == 0) { \ err = EPIPE; \ } \ if (err) { \ rv = gensio_os_err_to_err(o, err); \ } else { \ recvcount = rv; \ rv = 0; \ } \ } while(0) int gensio_unix_termios_read_flags(struct gensio_os_funcs *o, unsigned char *buf, unsigned char *flags, gensiods buflen, gensiods *rcount, struct gensio_unix_termios *t, int fd) { ssize_t rv = 0; gensiods recvcount = 0; retry: rv = read(fd, buf, buflen); ERRHANDLE(); if (rv) return rv; if (t->do_recv_err) { gensiods i, bufpos; /* * We enabled PARMRK, so any receive error will come in as * \377\0\???. An incoming \377 will come in as \377\377. */ for (bufpos = 0, i = 0; i < recvcount; i++) { if (t->brk_pos == 1) { if (buf[i] == 0xff) { flags[bufpos] = 0; buf[bufpos++] = 0xff; t->brk_pos = 0; } else if (buf[i] == 0) { t->brk_pos = 2; } else { t->brk_pos = 0; /* Shouldn't be possible. */ } } else if (t->brk_pos == 2) { if (buf[i] == 0) flags[bufpos] = GENSIO_IOD_READ_FLAGS_BREAK; else flags[bufpos] = GENSIO_IOD_READ_FLAGS_ERR; buf[bufpos++] = buf[i]; t->brk_pos = 0; } else if (buf[i] == 0xff) { t->brk_pos = 1; } else { flags[bufpos] = 0; buf[bufpos++] = buf[i]; } } if (rcount) *rcount = bufpos; } else { memset(flags, 0, recvcount); if (rcount) *rcount = recvcount; } return 0; } void gensio_unix_do_flush(struct gensio_os_funcs *o, int fd, int whichbuf) { int arg; if ((whichbuf & (GENSIO_IN_BUF | GENSIO_OUT_BUF)) == (GENSIO_IN_BUF | GENSIO_OUT_BUF)) arg = TCIOFLUSH; else if (whichbuf & GENSIO_IN_BUF) arg = TCIFLUSH; else if (whichbuf & GENSIO_OUT_BUF) arg = TCIOFLUSH; else return; do_flush(fd, arg); } int gensio_unix_get_bufcount(struct gensio_os_funcs *o, int fd, int whichbuf, gensiods *rcount) { int rv = 0, count; switch (whichbuf) { case GENSIO_IN_BUF: #ifdef TIOCINQ rv = ioctl(fd, TIOCINQ, &count); #elif defined(FIONREAD) rv = ioctl(fd, FIONREAD, &count); #else #error "No way to read tty bufcount" #endif break; #ifdef TIOCOUTQ case GENSIO_OUT_BUF: rv = ioctl(fd, TIOCOUTQ, &count); break; #endif default: return GE_NOTSUP; } if (rv) { if (errno == EINVAL || errno == ENOTTY) /* These are special from ioctl, probably means not supported. */ rv = GE_NOTSUP; else rv = gensio_os_err_to_err(o, errno); } else { *rcount = count; } return rv; } extern char **environ; int gensio_unix_do_exec(struct gensio_os_funcs *o, const char *argv[], const char **env, const char *start_dir, unsigned int flags, int *rpid, int *rin, int *rout, int *rerr) { int err; int stdinpipe[2] = {-1, -1}; int stdoutpipe[2] = {-1, -1}; int stderrpipe[2] = {-1, -1}; int pid = -1; if (rerr && (flags & GENSIO_EXEC_STDERR_TO_STDOUT)) return GE_INVAL; err = pipe(stdinpipe); if (err) { err = errno; goto out_err; } err = pipe(stdoutpipe); if (err) { err = errno; goto out_err; } if (rerr) { err = pipe(stderrpipe); if (err) { err = errno; goto out_err; } } pid = fork(); if (pid < 0) { err = errno; goto out_err; } if (pid == 0) { int i, openfiles = sysconf(_SC_OPEN_MAX); dup2(stdinpipe[0], 0); dup2(stdoutpipe[1], 1); if (flags & GENSIO_EXEC_STDERR_TO_STDOUT) dup2(stdoutpipe[1], 2); else if (rerr) dup2(stderrpipe[1], 2); /* Close everything but stdio. */ for (i = 3; i < openfiles; i++) close(i); if (start_dir) { if (chdir(start_dir)) { fprintf(stderr, "stdio fork: chdir to %s failed: %s", start_dir, strerror(errno)); exit(1); } } err = gensio_unix_os_setupnewprog(); if (err) { fprintf(stderr, "Unable to set groups or user: %s\r\n", strerror(err)); exit(1); } if (env) environ = (char **) env; execvp(argv[0], (char * const *) argv); fprintf(stderr, "Err: %s %s\r\n", argv[0], strerror(errno)); exit(1); /* Only reached on error. */ } close(stdinpipe[0]); close(stdoutpipe[1]); if (rerr) close(stderrpipe[1]); *rpid = pid; *rin = stdinpipe[1]; *rout = stdoutpipe[0]; if (rerr) *rerr = stderrpipe[0]; return 0; out_err: err = gensio_os_err_to_err(o, err); if (stdinpipe[0] != -1) close(stdinpipe[0]); if (stdinpipe[1] != -1) close(stdinpipe[1]); if (stdoutpipe[0] != -1) close(stdoutpipe[0]); if (stdoutpipe[1] != -1) close(stdoutpipe[1]); if (stderrpipe[0] != -1) close(stderrpipe[0]); if (stderrpipe[1] != -1) close(stderrpipe[1]); return err; } int gensio_unix_pty_alloc(struct gensio_os_funcs *o, int *rfd, int *rsfd) { #if USE_OPENPTY int fd; int sfd = -1; if (openpty(&fd, &sfd, NULL, NULL, NULL) == -1) return gensio_os_err_to_err(o, errno); #else int fd = posix_openpt(O_RDWR | O_NOCTTY), sfd = -1; if (fd == -1) return gensio_os_err_to_err(o, errno); #endif /* Set the owner of the slave PT. */ if (grantpt(fd) < 0) { close(fd); if (sfd != -1) close(sfd); return gensio_os_err_to_err(o, errno); }; *rfd = fd; *rsfd = sfd; return 0; } int gensio_unix_pty_start(struct gensio_os_funcs *o, int pfd, int *psfd, const char **argv, const char **env, const char *start_dir, pid_t *rpid) { const char *pgm; pid_t pid = -1; int err; if (unlockpt(pfd) < 0) goto out_errno; if (!argv) goto skip_child; pid = fork(); if (pid < 0) goto out_errno; if (pid == 0) { /* * Delay getting the slave until here becase ptsname is not * thread-safe, but after the fork we are single-threaded. */ char *slave = ptsname(pfd); int i, openfiles = sysconf(_SC_OPEN_MAX); int fd; if (start_dir) { if (chdir(start_dir)) { fprintf(stderr, "pty fork: chdir to %s failed: %s", start_dir, strerror(errno)); exit(1); } } if (setsid() == -1) { fprintf(stderr, "pty fork: failed to start new session: %s\r\n", strerror(errno)); exit(1); } if (*psfd == -1) { fd = open(slave, O_RDWR); if (fd == -1) { fprintf(stderr, "pty fork: failed to open slave terminal: %s\r\n", strerror(errno)); exit(1); } } else { fd = *psfd; } #if defined(TIOCSCTTY) && !defined(linux) /* Linux sets the first opened TTY to the controlling terminal. */ if (ioctl(fd, TIOCSCTTY, NULL) == -1) { fprintf(stderr, "pty fork: failed to set controlling tty: %s\r\n", strerror(errno)); exit(1); } #endif /* fd will be closed by the loop to close everything. */ if (open("/dev/tty", O_RDWR) == -1) { fprintf(stderr, "pty fork: failed to set control term: %s\r\n", strerror(errno)); exit(1); } if (dup2(fd, 0) == -1) { fprintf(stderr, "pty fork: stdin open fail\r\n"); exit(1); } if (dup2(fd, 1) == -1) { fprintf(stderr, "pty fork: stdout open fail\r\n"); exit(1); } if (dup2(fd, 2) == -1) { fprintf(stderr, "pty fork: stderr open fail\r\n"); exit(1); } /* Close everything. */ for (i = 3; i < openfiles; i++) close(i); err = gensio_unix_os_setupnewprog(); if (err) { fprintf(stderr, "Unable to set groups or user: %s\r\n", strerror(err)); exit(1); } if (env) environ = (char **) env; pgm = argv[0]; if (*pgm == '-') pgm++; execvp(pgm, (char **) argv); fprintf(stderr, "Unable to exec %s: %s\r\n", argv[0], strerror(errno)); exit(1); /* Only reached on error. */ } if (*psfd != -1) { close(*psfd); *psfd = -1; } skip_child: *rpid = pid; return 0; out_errno: return gensio_os_err_to_err(o, errno); } static bool pathendswith(const char *str, const char *endstr) { const char *end1 = str + strlen(str) - 1; const char *end2 = endstr + strlen(endstr) - 1; /* Ignore trailing '/' */ while (end1 != str && *end1 == '/') end1--; if (*end1 == '/') return false; /* It was all /'s */ while (end1 != str && end2 != endstr && *end1 == *end2) { end1--; end2--; } return end2 == endstr && *end1 == *end2; } static bool try_loaddir(struct gensio_os_funcs *o, const char *name, const char *path, bool check_libtool_dir) { gensiods len; char fname[PATH_MAX]; void *handle; int (*initfunc)(struct gensio_os_funcs *); int err; if (check_libtool_dir) { /* * Only allow libtool libraries, so when running from in the * build directory it will find it.) */ if (!pathendswith(path, "/lib/.libs")) return false; } len = snprintf(fname, sizeof(fname), "%s/libgensio_%s.so", path, name); if (len >= sizeof(fname)) return false; handle = dlopen(fname, RTLD_LAZY | RTLD_GLOBAL); if (!handle) return false; snprintf(fname, sizeof(fname), "gensio_init_%s", name); initfunc = (int (*)(struct gensio_os_funcs *)) dlsym(handle, fname); if (!initfunc) { dlclose(handle); return false; } err = initfunc(o); if (err) { dlclose(handle); return false; } return true; } static bool try_loaddirs(struct gensio_os_funcs *o, const char *name, const char *paths, bool check_libtool_dir) { char path[PATH_MAX]; const char *start, *end; gensiods len; start = paths; while (*start) { end = strchr(start, ':'); if (!end) { if (try_loaddir(o, name, start, check_libtool_dir)) return true; return false; } len = end - start; if (len < sizeof(path)) { memcpy(path, start, len); path[len] = '\0'; if (try_loaddir(o, name, path, check_libtool_dir)) return true; } start = end + 1; } return false; } static const char *default_libdir = PKG_LIBEXEC; bool gensio_os_loadlib(struct gensio_os_funcs *o, const char *name) { const char *paths; paths = getenv("LD_LIBRARY_PATH"); if (paths) { if (try_loaddirs(o, name, paths, true)) return true; } paths = getenv("GENSIO_LIBRARY_PATH"); if (paths) { if (try_loaddirs(o, name, paths, false)) return true; } return try_loaddirs(o, name, default_libdir, false); } #endif /* _WIN32 */ #ifdef ENABLE_INTERNAL_TRACE #define MEM_MAGIC 0xddf0983aec9320b0 #define MEM_BUFFER 32 struct mem_header { uint64_t magic; struct gensio_link link; int32_t freed; int32_t size; void *alloc_bt[4]; void* free_bt[4]; unsigned char filler[MEM_BUFFER]; }; struct gensio_memtrack { bool abort_on_err; bool check_on_all; lock_type lock; struct gensio_list alloced; struct gensio_list freed; }; static void mem_fill(unsigned char *d) { unsigned int i; for (i = 0; i < MEM_BUFFER; i++) d[i] = 0xfd; } static bool mem_check(unsigned char *d) { unsigned int i; for (i = 0; i < MEM_BUFFER; i++) { if (d[i] != 0xfd) return false; } return true; } static void print_meminfo(const char *msg, struct mem_header *h) { fprintf(stderr, "%s at %p allocated at %p %p %p %p\n", msg, ((char *) h) + sizeof(*h), h->alloc_bt[0], h->alloc_bt[1], h->alloc_bt[2], h->alloc_bt[3]); if (h->freed) fprintf(stderr, " freed at at %p %p %p %p\n", h->free_bt[0], h->free_bt[1], h->free_bt[2], h->free_bt[3]); } static bool check_mem(struct gensio_memtrack *m, struct mem_header *h, int32_t freed) { unsigned char *b = ((unsigned char *) h) + sizeof(*h); bool err = false; if (h->magic != MEM_MAGIC) { fprintf(stderr, "Magic mismatch at %p\n", h); err = true; } else if (h->freed != freed) { if (freed) print_meminfo("Free in allocated list", h); else print_meminfo("Double free", h); err = true; } else if (!mem_check(h->filler)) { print_meminfo("Memory underrun", h); err = true; } else if (!mem_check(b + h->size)) { print_meminfo("Memory overrun", h); err = true; } if (err && m->abort_on_err) { fflush(stderr); assert(false); } return err; } struct gensio_memtrack * gensio_memtrack_alloc(void) { char *s = getenv("GENSIO_MEMTRACK"); struct gensio_memtrack *m; if (!s) return NULL; m = malloc(sizeof(*m)); if (!m) return NULL; memset(m, 0, sizeof(*m)); LOCK_INIT(&m->lock); gensio_list_init(&m->alloced); gensio_list_init(&m->freed); if (strstr(s, "abort")) m->abort_on_err = true; if (strstr(s, "checkall")) m->check_on_all = true; return m; } void gensio_memtrack_cleanup(struct gensio_memtrack *m) { struct gensio_link* l; if (!m) return; gensio_list_for_each(&m->alloced, l) { struct mem_header *h = gensio_container_of(l, struct mem_header, link); print_meminfo("Lost memory", h); } if (m->abort_on_err && !gensio_list_empty(&m->alloced)) { fflush(stderr); assert(false); } LOCK_DESTROY(&m->lock); free(m); } void * gensio_i_zalloc(struct gensio_memtrack *m, unsigned int size, void *caller[], unsigned int caller_size) { unsigned char *b; if (do_errtrig()) return NULL; if (m) { struct mem_header *h; b = malloc(size + sizeof(*h) + MEM_BUFFER); if (!b) return NULL; h = (struct mem_header *) b; memset(h, 0, sizeof(*h)); gensio_list_link_init(&h->link); h->magic = MEM_MAGIC; h->freed = 0; h->size = size; if (caller) { unsigned int i; for (i = 0; i < caller_size && i < 4; i++) h->alloc_bt[i] = caller[i]; } b += sizeof(struct mem_header); mem_fill(h->filler); mem_fill(b + size); LOCK(&m->lock); gensio_list_add_tail(&m->alloced, &h->link); UNLOCK(&m->lock); } else { b = malloc(size); } if (b) memset(b, 0, size); return b; } void gensio_i_free(struct gensio_memtrack *m, void *data, void *caller[], unsigned int caller_size) { if (m) { unsigned char *b = data; struct mem_header *h = (struct mem_header*)(b - sizeof(*h)); struct gensio_link *l; bool err; if (caller) { unsigned int i; for (i = 0; i < caller_size && i < 4; i++) h->free_bt[0] = caller[i]; } #if _MSC_VER h->free_bt[0] = _ReturnAddress(); #else h->free_bt[0] = __builtin_return_address(0); #if TRACEBACK_DEPTH > 1 h->free_bt[1] = __builtin_return_address(1); #if TRACEBACK_DEPTH > 2 h->free_bt[2] = __builtin_return_address(2); #if TRACEBACK_DEPTH > 3 h->free_bt[3] = __builtin_return_address(3); #endif #endif #endif #endif err = check_mem(m, h, 0); if (!err) { LOCK(&m->lock); gensio_list_rm(&m->alloced, &h->link); if (m->check_on_all) { /* The following does more serious but costly memory checking */ gensio_list_for_each(&m->alloced, l) { struct mem_header *h2 = gensio_container_of(l, struct mem_header, link); check_mem(m, h2, 0); } gensio_list_for_each(&m->freed, l) { struct mem_header *h2 = gensio_container_of(l, struct mem_header, link); check_mem(m, h2, 1); } } gensio_list_add_tail(&m->freed, &h->link); h->freed = 1; UNLOCK(&m->lock); } } else { free(data); } } #else /* ENABLE_INTERNAL_TRACE */ struct gensio_memtrack * gensio_memtrack_alloc(void) { return NULL; } void gensio_memtrack_cleanup(struct gensio_memtrack *m) { } void * gensio_i_zalloc(struct gensio_memtrack *m, unsigned int size, void *caller[], unsigned int caller_size) { void *d = malloc(size); if (d) memset(d, 0, size); return d; } void gensio_i_free(struct gensio_memtrack *m, void *data, void *caller[], unsigned int caller_size) { free(data); } #endif /* ENABLE_INTERNAL_TRACE */ void gensio_os_funcs_set_vlog(struct gensio_os_funcs *o, gensio_vlog_func func) { o->vlog = func; } gensio_vlog_func * gensio_os_funcs_get_vlog(struct gensio_os_funcs *o) { return o->vlog; } void gensio_os_funcs_free(struct gensio_os_funcs *o) { o->free_funcs(o); } void * gensio_os_funcs_zalloc(struct gensio_os_funcs *o, gensiods size) { return o->zalloc(o, size); } void gensio_os_funcs_zfree(struct gensio_os_funcs *o, void *data) { o->free(o, data); } struct gensio_waiter * gensio_os_funcs_alloc_waiter(struct gensio_os_funcs *o) { return o->alloc_waiter(o); } void gensio_os_funcs_free_waiter(struct gensio_os_funcs *o, struct gensio_waiter *waiter) { o->free_waiter(waiter); } int gensio_os_funcs_wait(struct gensio_os_funcs *o, struct gensio_waiter *waiter, unsigned int count, gensio_time *timeout) { return o->wait(waiter, count, timeout); } int gensio_os_funcs_wait_intr(struct gensio_os_funcs *o, struct gensio_waiter *waiter, unsigned int count, gensio_time *timeout) { return o->wait_intr(waiter, count, timeout); } int gensio_os_funcs_wait_intr_sigmask(struct gensio_os_funcs *o, struct gensio_waiter *waiter, unsigned int count, gensio_time *timeout, struct gensio_os_proc_data *proc_data) { return o->wait_intr_sigmask(waiter, count, timeout, proc_data); } void gensio_os_funcs_wake(struct gensio_os_funcs *o, struct gensio_waiter *waiter) { o->wake(waiter); } struct gensio_lock * gensio_os_funcs_alloc_lock(struct gensio_os_funcs *o) { return o->alloc_lock(o); } void gensio_os_funcs_free_lock(struct gensio_os_funcs *o, struct gensio_lock *lock) { o->free_lock(lock); } void gensio_os_funcs_lock(struct gensio_os_funcs *o, struct gensio_lock *lock) { o->lock(lock); } void gensio_os_funcs_unlock(struct gensio_os_funcs *o, struct gensio_lock *lock) { o->unlock(lock); } void gensio_os_funcs_get_monotonic_time(struct gensio_os_funcs *o, gensio_time *time) { o->get_monotonic_time(o, time); } struct gensio_timer * gensio_os_funcs_alloc_timer(struct gensio_os_funcs *o, void (*handler)(struct gensio_timer *t, void *cb_data), void *cb_data) { return o->alloc_timer(o, handler, cb_data); } void gensio_os_funcs_free_timer(struct gensio_os_funcs *o, struct gensio_timer *timer) { o->free_timer(timer); } int gensio_os_funcs_start_timer(struct gensio_os_funcs *o, struct gensio_timer *timer, gensio_time *timeout) { return o->start_timer(timer, timeout); } int gensio_os_funcs_start_timer_abs(struct gensio_os_funcs *o, struct gensio_timer *timer, gensio_time *timeout) { return o->start_timer_abs(timer, timeout); } int gensio_os_funcs_stop_timer(struct gensio_os_funcs *o, struct gensio_timer *timer) { return o->stop_timer(timer); } int gensio_os_funcs_stop_timer_with_done(struct gensio_os_funcs *o, struct gensio_timer *timer, void (*done_handler)(struct gensio_timer *t, void *cb_data), void *cb_data) { return o->stop_timer_with_done(timer, done_handler, cb_data); } struct gensio_runner * gensio_os_funcs_alloc_runner(struct gensio_os_funcs *o, void (*handler)(struct gensio_runner *r, void *cb_data), void *cb_data) { return o->alloc_runner(o, handler, cb_data); } void gensio_os_funcs_free_runner(struct gensio_os_funcs *o, struct gensio_runner *runner) { o->free_runner(runner); } int gensio_os_funcs_run(struct gensio_os_funcs *o, struct gensio_runner *runner) { return o->run(runner); } int gensio_os_funcs_service(struct gensio_os_funcs *o, gensio_time *timeout) { return o->service(o, timeout); } int gensio_os_funcs_handle_fork(struct gensio_os_funcs *o) { return o->handle_fork(o); } void gensio_os_funcs_set_data(struct gensio_os_funcs *o, void *data) { o->other_data = data; } void * gensio_os_funcs_get_data(struct gensio_os_funcs *o) { return o->other_data; } /* * The once operation is a nasty piece of code. * * This basically implements a recursive lock on the once operation. * There are unfortunate places one a once calls another once and * where these can actually recurse if you don't stop them. * * once_lock protects once_next and once_owner. once_lock2 is used to * let only one once operation in at a time and to protect * once->called. You can claim once_lock if holding once_lock2, but * not the other way around. * * The called field in the once is used to tell if we have called it. * It will be 2 if it is in the once function (to detect recursive * calls) and 1 if the once operation has been completed. */ static lock_type once_lock = LOCK_INITIALIZER; static lock_type once_lock2 = LOCK_INITIALIZER; static unsigned int once_nest; static lock_thread_type once_owner; void gensio_call_once(struct gensio_os_funcs *f, struct gensio_once *once, void (*func)(void *cb_data), void *cb_data) { lock_thread_type tid; bool do_unlock = true; if (once->called == 1) /* once has been done, just return. */ return; LOCK(&once_lock); tid = LOCK_GET_THREAD_ID; if (once_nest > 0 && LOCK_THREAD_ID_EQUAL(tid, once_owner)) { /* Called recursively. */ once_nest++; UNLOCK(&once_lock); do_unlock = false; } else { /* * First time into the once for this thread, claim the that * only allows one caller. */ UNLOCK(&once_lock); LOCK(&once_lock2); LOCK(&once_lock); once_owner = tid; once_nest++; UNLOCK(&once_lock); } if (!once->called) { /* * Mark that we are in the call. This way if we recurse into * the same once, we know to not call it again. Don't set it * to 1 until we are finished processing. */ once->called = 2; func(cb_data); once->called = 1; } LOCK(&once_lock); once_nest--; UNLOCK(&once_lock); if (do_unlock) UNLOCK(&once_lock2); } gensio-3.0.0/lib/gensio_mdns.c0000664000175000017500000005676614664224267011741 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* * This code is for discovering gensio parameters via MDNS then * creating a gensio based upon those.. */ #include "config.h" #include #include #include #include #include #include "config.h" #include #include #include #include #include #include enum mdnsn_state { MDNSN_CLOSED, MDNSN_IN_OPEN_QUERY, MDNSN_IN_CHILD_OPEN, MDNSN_OPEN, MDNSN_IN_OPEN_ERR, MDNSN_IN_CLOSE, }; struct mdnsn_data { struct gensio_os_funcs *o; struct gensio_lock *lock; unsigned int refcount; enum mdnsn_state state; struct gensio *io; struct gensio *child; bool nostack; bool ignore_v6_link_local; int interface; int nettype; char *name; char *type; char *domain; char *host; bool mdns_in_free; struct gensio_mdns *mdns; struct gensio_mdns_watch *watch; bool timer_running; struct gensio_timer *timer; gensio_time timeout; char *laddr; gensiods max_read_size; bool readbuf_set; bool nodelay; bool nodelay_set; int open_err; gensio_done_err open_done; void *open_data; gensio_done close_done; void *close_data; /* * Used to run read callbacks from the selector to avoid running * it directly from user calls. */ bool deferred_op_pending; struct gensio_runner *deferred_op_runner; }; static void mdnsn_start_deferred_op(struct mdnsn_data *ndata); static void mdnsn_finish_free(struct mdnsn_data *ndata) { struct gensio_os_funcs *o = ndata->o; if (ndata->timer) o->free_timer(ndata->timer); if (ndata->io) gensio_data_free(ndata->io); if (ndata->laddr) o->free(o, ndata->laddr); if (ndata->name) o->free(o, ndata->name); if (ndata->type) o->free(o, ndata->type); if (ndata->domain) o->free(o, ndata->domain); if (ndata->host) o->free(o, ndata->host); if (ndata->deferred_op_runner) o->free_runner(ndata->deferred_op_runner); if (ndata->lock) o->free_lock(ndata->lock); o->free(o, ndata); } static void mdnsn_lock(struct mdnsn_data *ndata) { ndata->o->lock(ndata->lock); } static void mdnsn_unlock(struct mdnsn_data *ndata) { ndata->o->unlock(ndata->lock); } static void mdnsn_ref(struct mdnsn_data *ndata) { assert(ndata->refcount > 0); ndata->refcount++; } static void mdnsn_deref(struct mdnsn_data *ndata) { /* Can't be the final deref. */ assert(ndata->refcount > 1); ndata->refcount--; } static void mdnsn_deref_and_unlock(struct mdnsn_data *ndata) { assert(ndata->refcount > 0); if (ndata->refcount == 1) { mdnsn_unlock(ndata); mdnsn_finish_free(ndata); } else { ndata->refcount--; mdnsn_unlock(ndata); } } static int child_cb(struct gensio *io, void *user_data, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) { struct mdnsn_data *ndata = user_data; return gensio_cb(ndata->io, event, err, buf, buflen, auxdata); } static void mdnsn_check_close(struct mdnsn_data *ndata) { if (!ndata->child && !ndata->mdns_in_free && !ndata->timer_running) { ndata->state = MDNSN_CLOSED; mdnsn_unlock(ndata); if (ndata->close_done) ndata->close_done(ndata->io, ndata->close_data); mdnsn_lock(ndata); } } static void mdnsn_deferred_op(struct gensio_runner *runner, void *cb_data) { struct mdnsn_data *ndata = cb_data; mdnsn_lock(ndata); if (ndata->state == MDNSN_IN_CLOSE) mdnsn_check_close(ndata); ndata->deferred_op_pending = false; mdnsn_deref_and_unlock(ndata); } static void mdnsn_start_deferred_op(struct mdnsn_data *ndata) { if (!ndata->deferred_op_pending) { /* Call the read from the selector to avoid lock nesting issues. */ ndata->deferred_op_pending = true; ndata->o->run(ndata->deferred_op_runner); mdnsn_ref(ndata); } } static void i_child_open_cb(struct mdnsn_data *ndata, int err) { if (!err) ndata->state = MDNSN_OPEN; else ndata->state = MDNSN_CLOSED; mdnsn_unlock(ndata); if (ndata->open_done) ndata->open_done(ndata->io, err, ndata->open_data); mdnsn_lock(ndata); } static void child_open_cb(struct gensio *io, int err, void *cb_data) { struct mdnsn_data *ndata = cb_data; mdnsn_lock(ndata); i_child_open_cb(ndata, err); mdnsn_deref_and_unlock(ndata); } static void child_closed_cb(struct gensio *io, void *cb_data) { struct mdnsn_data *ndata = cb_data; mdnsn_lock(ndata); gensio_free(ndata->child); ndata->child = NULL; mdnsn_check_close(ndata); mdnsn_deref_and_unlock(ndata); } static void mdns_freed(struct gensio_mdns *m, void *userdata) { struct mdnsn_data *ndata = userdata; mdnsn_lock(ndata); ndata->mdns_in_free = false; if (ndata->state == MDNSN_IN_OPEN_ERR) { i_child_open_cb(ndata, ndata->open_err); } else { mdnsn_check_close(ndata); } mdnsn_deref_and_unlock(ndata); } /* Validate that the gensio stack contains only safe gensios. */ static bool gensiostack_ok(const char *s) { unsigned int i; static char *ok_gensios[] = { "telnet", "tcp", "udp", "sctp", NULL }; while (*s) { unsigned int len; for (i = 0; ok_gensios[i]; i++) { len = strlen(ok_gensios[i]); if (strncmp(s, ok_gensios[i], len) == 0) break; } if (!ok_gensios[i]) return false; s += len; if (*s != ',' && *s != '(' && *s != '\0') return false; while (*s && *s != ',') s++; if (*s == ',') s++; } return true; } static int addarg(char **args, gensiods *len, struct gensio_os_funcs *o, const char *fmt, ...) { char *s, *s2; va_list ap; int err = 0; va_start(ap, fmt); if (*args) { int extra; s2 = *args; extra = vsnprintf(s2 + *len, 0, fmt, ap); /* No -1, we are deleting the ')' from the incoming string. */ s = o->zalloc(o, *len + extra); if (!s) { err = GE_NOMEM; goto out_err; } va_end(ap); memcpy(s, s2, *len - 1); free(s2); va_start(ap, fmt); vsnprintf(s + *len - 1, extra + 1, fmt, ap); *args = s; *len += extra - 1; } else { s = gensio_alloc_vsprintf(o, fmt, ap); if (!s) { err = GE_NOMEM; } else { *s = '('; *args = s; *len = strlen(s); } } out_err: va_end(ap); return err; } static int get_mdns_gensiostack(struct mdnsn_data *ndata, const char * const *txt, const struct gensio_addr *addr, char **rstack) { struct gensio_os_funcs *o = ndata->o; unsigned int i; const char *stackstr = "gensiostack="; unsigned int stackstrlen = strlen(stackstr); const char *stack, *s; char *addrstr = NULL; gensiods addrstrlen, totallen, argslen = 0, pos; unsigned int err; bool udp = false; char *args = NULL; for (i = 0; txt[i]; i++) { if (strncmp(txt[i], stackstr, stackstrlen) == 0) break; } if (!txt[i] || !gensiostack_ok(txt[i] + stackstrlen)) { *rstack = NULL; return 0; } stack = txt[i] + stackstrlen; s = strrchr(stack, ','); if (!s) s = stack; udp = strcmp(s, "udp") == 0; if (ndata->readbuf_set) { err = addarg(&args, &argslen, o, ",readbuf=%lu)", (unsigned long) ndata->max_read_size); if (err) goto out_err; } if (ndata->nodelay_set && !udp) { err = addarg(&args, &argslen, o, ",nodelay=%d)", ndata->nodelay); if (err) goto out_err; } if (ndata->laddr) { err = addarg(&args, &argslen, o, ",laddr=%s)", ndata->laddr); if (err) goto out_err; } addrstrlen = 0; err = gensio_addr_to_str(addr, NULL, &addrstrlen, 0); if (err) goto out_err; totallen = strlen(stack) + addrstrlen + argslen + 2; addrstr = o->zalloc(o, totallen); if (!addrstr) { err = GE_NOMEM; goto out_err; } pos = snprintf(addrstr, totallen, "%s%s,", stack, args ? args : ""); err = gensio_addr_to_str(addr, addrstr, &pos, totallen); if (err) goto out_err; *rstack = addrstr; out: if (args) o->free(o, args); return err; out_err: if (addrstr) o->free(o, addrstr); goto out; } /* Must be called with lock held, releases the lock. */ static void mdns_handle_err(struct mdnsn_data *ndata) { int err; ndata->state = MDNSN_IN_OPEN_ERR; if (ndata->watch) gensio_mdns_remove_watch(ndata->watch, NULL, NULL); err = gensio_free_mdns(ndata->mdns, mdns_freed, ndata); if (!err) { ndata->mdns_in_free = true; mdnsn_unlock(ndata); } else { ndata->mdns = NULL; i_child_open_cb(ndata, ndata->open_err); mdnsn_deref_and_unlock(ndata); } } static int mdns_start_timer(struct mdnsn_data *ndata) { int err; err = ndata->o->start_timer(ndata->timer, &ndata->timeout); if (!err) { ndata->timer_running = true; mdnsn_ref(ndata); } return err; } static int mdns_stop_timer(struct mdnsn_data *ndata) { int err; err = ndata->o->stop_timer(ndata->timer); if (!err) { ndata->timer_running = false; mdnsn_deref(ndata); } return err; } static void mdns_timeout(struct gensio_timer *timer, void *cb_data) { struct mdnsn_data *ndata = cb_data; mdnsn_lock(ndata); ndata->timer_running = false; switch (ndata->state) { case MDNSN_IN_OPEN_QUERY: ndata->open_err = GE_NOTFOUND; mdns_handle_err(ndata); break; case MDNSN_IN_CLOSE: /* Maybe we should finish the close. */ mdnsn_start_deferred_op(ndata); break; default: break; } mdnsn_deref_and_unlock(ndata); } static void mdns_cb(struct gensio_mdns_watch *w, enum gensio_mdns_data_state state, int interface, int ipdomain, const char *name, const char *type, const char *domain, const char *host, const struct gensio_addr *addr, const char * const *txt, void *userdata) { struct mdnsn_data *ndata = userdata; struct gensio_os_funcs *o = ndata->o; const char **argv = NULL; char *s, *stack = NULL; int err = 0; mdnsn_lock(ndata); if (ndata->timer_running) err = mdns_stop_timer(ndata); if (ndata->state != MDNSN_IN_OPEN_QUERY) goto out_unlock; if (err) /* Timer will go off immediately. */ goto out_unlock; if (state == GENSIO_MDNS_WATCH_ALL_FOR_NOW) { /* Didn't find what we were looking for. */ err = mdns_start_timer(ndata); if (err) { /* Should never happen. */ gensio_log(o, GENSIO_LOG_ERR, "mdns: Error starting timer: %s\n", gensio_err_to_str(err)); ndata->open_err = err; goto out_err; } goto out_unlock; } if (state == GENSIO_MDNS_WATCH_NEW_DATA) { gensiods args = 0, argc = 0; char buf[200]; gensiods len = 0; if (ndata->ignore_v6_link_local) { err = gensio_addr_to_str(addr, buf, &len, sizeof(buf)); if (err) goto out_err; if (strncmp(buf, "ipv6,fe80:", 10) == 0) goto out_unlock; } if (!ndata->nostack) { ndata->open_err = get_mdns_gensiostack(ndata, txt, addr, &stack); if (ndata->open_err) goto out_err; } if (stack) { ndata->open_err = str_to_gensio(stack, ndata->o, child_cb, ndata, &ndata->child); ndata->o->free(ndata->o, stack); } else { /* Look for the trailing protocol type. */ s = strrchr(type, '.'); if (!s) goto out_unlock; s++; if (ndata->readbuf_set) { ndata->open_err = gensio_argv_sappend(ndata->o, &argv, &args, &argc, "readbuf=%lu", (unsigned long) ndata->max_read_size); if (ndata->open_err) goto out_err; } if (ndata->nodelay_set && strcmp(s, "_udp") != 0) { /* Don't add nodelay for udp. */ ndata->open_err = gensio_argv_sappend(ndata->o, &argv, &args, &argc, "nodelay=%d", ndata->nodelay); if (ndata->open_err) goto out_err; } if (ndata->laddr) { ndata->open_err = gensio_argv_sappend(ndata->o, &argv, &args, &argc, "laddr=%s", ndata->laddr); if (ndata->open_err) goto out_err; } ndata->open_err = gensio_argv_append(ndata->o, &argv, NULL, &args, &argc, false); if (ndata->open_err) goto out_err; if (strcmp(s, "_tcp") == 0) { ndata->open_err = gensio_terminal_alloc("tcp", addr, argv, ndata->o, child_cb, ndata, &ndata->child); } else if (strcmp(s, "_udp") == 0) { ndata->open_err = gensio_terminal_alloc("udp", addr, argv, ndata->o, child_cb, ndata, &ndata->child); } else { goto out_unlock; } } if (ndata->open_err) goto out_err; ndata->open_err = gensio_open(ndata->child, child_open_cb, ndata); if (ndata->open_err) { gensio_free(ndata->child); ndata->child = NULL; goto out_err; } ndata->state = MDNSN_IN_CHILD_OPEN; if (ndata->watch) gensio_mdns_remove_watch(ndata->watch, NULL, NULL); err = gensio_free_mdns(ndata->mdns, mdns_freed, ndata); if (!err) { mdnsn_ref(ndata); ndata->mdns_in_free = true; } else { ndata->mdns = NULL; } } out_unlock: mdnsn_unlock(ndata); out: if (argv) gensio_argv_free(ndata->o, argv); return; out_err: mdns_handle_err(ndata); goto out; } static int mdnsn_open(struct gensio *io, gensio_done_err open_done, void *open_data) { struct mdnsn_data *ndata = gensio_get_gensio_data(io); int err = 0; mdnsn_lock(ndata); if (ndata->state != MDNSN_CLOSED) { err = GE_NOTREADY; goto out_unlock; } err = gensio_alloc_mdns(ndata->o, &ndata->mdns); if (err) goto out_unlock; err = mdns_start_timer(ndata); assert(err == 0); err = gensio_mdns_add_watch(ndata->mdns, ndata->interface, ndata->nettype, ndata->name, ndata->type, ndata->domain, ndata->host, mdns_cb, ndata, &ndata->watch); if (err) { gensio_free_mdns(ndata->mdns, NULL, NULL); ndata->mdns = NULL; goto out_unlock; } mdnsn_ref(ndata); ndata->state = MDNSN_IN_OPEN_QUERY; ndata->open_done = open_done; ndata->open_data = open_data; mdnsn_start_deferred_op(ndata); out_unlock: mdnsn_unlock(ndata); return err; } static int mdnsn_start_close(struct mdnsn_data *ndata) { int err; if (ndata->timer_running) mdns_stop_timer(ndata); switch (ndata->state) { case MDNSN_OPEN: case MDNSN_IN_CHILD_OPEN: err = gensio_close(ndata->child, child_closed_cb, ndata); if (!err) { mdnsn_ref(ndata); } else { gensio_free(ndata->child); ndata->child = NULL; } break; case MDNSN_IN_OPEN_QUERY: if (ndata->watch) gensio_mdns_remove_watch(ndata->watch, NULL, NULL); err = gensio_free_mdns(ndata->mdns, mdns_freed, ndata); if (err) ndata->mdns = NULL; else { ndata->mdns_in_free = true; mdnsn_ref(ndata); } break; default: err = GE_NOTREADY; } return err; } static int mdnsn_close(struct gensio *io, gensio_done close_done, void *close_data) { struct mdnsn_data *ndata = gensio_get_gensio_data(io); int err = 0; mdnsn_lock(ndata); err = mdnsn_start_close(ndata); if (!err) { ndata->state = MDNSN_IN_CLOSE; ndata->close_done = close_done; ndata->close_data = close_data; } mdnsn_unlock(ndata); return err; } static void mdnsn_free(struct gensio *io) { struct mdnsn_data *ndata = gensio_get_gensio_data(io); mdnsn_lock(ndata); if (ndata->state != MDNSN_CLOSED) mdnsn_start_close(ndata); mdnsn_deref_and_unlock(ndata); } static int mdnsn_disable(struct gensio *io) { struct mdnsn_data *ndata = gensio_get_gensio_data(io); mdnsn_lock(ndata); mdns_stop_timer(ndata); gensio_disable(ndata->child); ndata->state = MDNSN_CLOSED; mdnsn_unlock(ndata); return 0; } static int gensio_mdns_func(struct gensio *io, int func, gensiods *count, const void *cbuf, gensiods buflen, void *buf, const char *const *auxdata) { struct mdnsn_data *ndata = gensio_get_gensio_data(io); switch (func) { case GENSIO_FUNC_WRITE_SG: if (!ndata->child) return GE_NOTSUP; return gensio_write_sg(ndata->child, count, cbuf, buflen, auxdata); case GENSIO_FUNC_OPEN: return mdnsn_open(io, cbuf, buf); case GENSIO_FUNC_CLOSE: return mdnsn_close(io, cbuf, buf); case GENSIO_FUNC_FREE: mdnsn_free(io); return 0; case GENSIO_FUNC_SET_READ_CALLBACK: if (ndata->child) gensio_set_read_callback_enable(ndata->child, buflen); return 0; case GENSIO_FUNC_SET_WRITE_CALLBACK: if (ndata->child) gensio_set_write_callback_enable(ndata->child, buflen); return 0; case GENSIO_FUNC_DISABLE: return mdnsn_disable(io); case GENSIO_FUNC_CONTROL: if (!ndata->child) return GE_NOTSUP; return gensio_control(ndata->child, 0, *((bool *) cbuf), buflen, buf, count); default: return GE_NOTSUP; } } static int mdns_ndata_setup(struct gensio_os_funcs *o, gensiods max_read_size, bool nodelay, int interface, int nettype, bool nostack, struct mdnsn_data **new_ndata) { struct mdnsn_data *ndata; ndata = o->zalloc(o, sizeof(*ndata)); if (!ndata) return GE_NOMEM; ndata->o = o; ndata->refcount = 1; ndata->max_read_size = max_read_size; ndata->nodelay = nodelay; ndata->interface = interface; ndata->nettype = nettype; ndata->nostack = nostack; ndata->deferred_op_runner = o->alloc_runner(o, mdnsn_deferred_op, ndata); if (!ndata->deferred_op_runner) goto out_nomem; ndata->lock = o->alloc_lock(o); if (!ndata->lock) goto out_nomem; ndata->timer = o->alloc_timer(o, mdns_timeout, ndata); if (!ndata->timer) goto out_nomem; *new_ndata = ndata; return 0; out_nomem: mdnsn_finish_free(ndata); return GE_NOMEM; } static int mdns_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { const char *mstr = gdata; int err; struct mdnsn_data *ndata = NULL; int i, interface = -1, nettype = GENSIO_NETTYPE_UNSPEC, timeoutms; gensio_time timeout; bool nostack = false; gensiods max_read_size = GENSIO_DEFAULT_BUF_SIZE; char *laddr = NULL, *name = NULL, *type = NULL; char *domain = NULL, *host = NULL, *nettype_str = NULL; bool nodelay = false, readbuf_set = false, nodelay_set = false; bool ignore_v6_link_local = false; const char *str; GENSIO_DECLARE_PPGENSIO(p, o, cb, "mdns", user_data); err = gensio_get_default(o, type, "nostack", false, GENSIO_DEFAULT_BOOL, NULL, &i); if (err) goto out_base_free; nostack = i; err = gensio_get_default(o, type, "ignore-v6-link-local", false, GENSIO_DEFAULT_BOOL, NULL, &i); if (err) goto out_base_free; ignore_v6_link_local = i; err = gensio_get_default(o, type, "interface", false, GENSIO_DEFAULT_INT, NULL, &interface); if (err) goto out_base_free; err = gensio_get_default(o, type, "nettype", false, GENSIO_DEFAULT_STR, &nettype_str, NULL); if (err) goto out_base_free; err = gensio_get_default(o, "mdns", "name", false, GENSIO_DEFAULT_STR, &name, NULL); if (err) goto out_base_free; err = gensio_get_default(o, "mdns", "type", false, GENSIO_DEFAULT_STR, &type, NULL); if (err) goto out_base_free; err = gensio_get_default(o, "mdns", "domain", false, GENSIO_DEFAULT_STR, &name, NULL); if (err) goto out_base_free; err = gensio_get_default(o, "mdns", "host", false, GENSIO_DEFAULT_STR, &type, NULL); if (err) goto out_base_free; err = gensio_get_default(o, type, "laddr", false, GENSIO_DEFAULT_STR, &laddr, NULL); if (err) goto out_base_free; err = gensio_get_default(o, type, "mdnstimeout", false, GENSIO_DEFAULT_INT, NULL, &timeoutms); if (err) goto out_base_free; gensio_msecs_to_time(&timeout, timeoutms); if (mstr) { if (name) free(name); name = gensio_strdup(o, mstr); if (!name) { err = GE_NOMEM; goto out_base_free; } } for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(&p, args[i], "readbuf", &max_read_size) > 0) { readbuf_set = true; continue; } if (gensio_pparm_bool(&p, args[i], "nodelay", &nodelay) > 0) { nodelay_set = true; continue; } if (gensio_pparm_time(&p, args[i], "timeout", 'm', &timeout) > 0) continue; if (gensio_pparm_time(&p, args[i], "mdnstimeout", 'n', &timeout) > 0) continue; if (gensio_pparm_bool(&p, args[i], "nostack", &nostack) > 0) continue; if (gensio_pparm_bool(&p, args[i], "ignore-v6-link-local", &ignore_v6_link_local) > 0) continue; if (gensio_pparm_value(&p, args[i], "laddr", &str) > 0) { if (laddr) free(laddr); laddr = gensio_strdup(o, str); if (!laddr) { err = GE_NOMEM; goto out_base_free; } continue; } if (gensio_pparm_value(&p, args[i], "name", &str) > 0) { if (name) free(name); name = gensio_strdup(o, str); if (!name) { err = GE_NOMEM; goto out_base_free; } continue; } if (gensio_pparm_value(&p, args[i], "type", &str) > 0) { if (type) free(type); type = gensio_strdup(o, str); if (!type) { err = GE_NOMEM; goto out_base_free; } continue; } if (gensio_pparm_value(&p, args[i], "domain", &str) > 0) { if (domain) free(domain); domain = gensio_strdup(o, str); if (!domain) { err = GE_NOMEM; goto out_base_free; } continue; } if (gensio_pparm_value(&p, args[i], "host", &str) > 0) { if (host) free(host); host = gensio_strdup(o, str); if (!host) { err = GE_NOMEM; goto out_base_free; } continue; } if (gensio_pparm_value(&p, args[i], "nettype", &str) > 0) { if (nettype_str) free(nettype_str); nettype_str = gensio_strdup(o, str); if (!nettype_str) { err = GE_NOMEM; goto out_base_free; } continue; } gensio_pparm_unknown_parm(&p, args[i]); err = GE_INVAL; goto out_base_free; } if (!nettype_str) { nettype = GENSIO_NETTYPE_UNSPEC; } else if (strcmp(nettype_str, "ipv4") == 0) { nettype = GENSIO_NETTYPE_IPV4; } else if (strcmp(nettype_str, "ipv6") == 0) { nettype = GENSIO_NETTYPE_IPV6; } else if (strcmp(nettype_str, "unspec") == 0) { nettype = GENSIO_NETTYPE_UNSPEC; } else { gensio_pparm_log(&p, "Unknown nettype: %s\n", nettype_str); err = GE_INVAL; goto out_base_free; } o->free(o, nettype_str); nettype_str = NULL; err = mdns_ndata_setup(o, max_read_size, nodelay, interface, nettype, nostack, &ndata); if (err) goto out_base_free; ndata->ignore_v6_link_local = ignore_v6_link_local; ndata->readbuf_set = readbuf_set; ndata->nodelay_set = nodelay_set; ndata->laddr = laddr; ndata->name = name; ndata->type = type; ndata->domain = domain; ndata->host = host; ndata->timeout = timeout; ndata->io = gensio_data_alloc(ndata->o, cb, user_data, gensio_mdns_func, NULL, "mdns", ndata); if (!ndata->io) goto out_nomem; gensio_set_is_client(ndata->io, true); gensio_set_is_reliable(ndata->io, true); *new_gensio = ndata->io; return 0; out_nomem: mdnsn_finish_free(ndata); return GE_NOMEM; out_base_free: if (laddr) o->free(o, laddr); if (name) o->free(o, name); if (type) o->free(o, type); if (domain) o->free(o, domain); if (host) o->free(o, host); if (nettype_str) o->free(o, nettype_str); return err; } static int str_to_mdns_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { return mdns_gensio_alloc(str, args, o, cb, user_data, new_gensio); } int gensio_init_mdns(struct gensio_os_funcs *o) { int rv; rv = register_gensio(o, "mdns", str_to_mdns_gensio, mdns_gensio_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/gensio_cm108gpio.c0000664000175000017500000005652414752425772012501 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include #include #include #include "config.h" #include #include #include #include #include #if HAVE_UDEV == 1 #include #include #include #include #include #include #define fdtype int #define INVALID_FD -1 static const char * my_strrstr(const char *haystack, const char *needle) { const char *n = NULL, *c = haystack; while (true) { c = strstr(c, needle); if (!c) return n; n = c; c++; } } static int find_hid_device(struct gensio_pparm_info *p, struct gensio_os_funcs *o, const char *idnum, char **devpath) { struct udev *udev; struct udev_enumerate *e = NULL; struct udev_list_entry *devices, *l; struct udev_device *d, *pd, *f = NULL, *sounddev = NULL; const char *path = NULL, *endp; char *basepath = NULL, *tmps; size_t basepath_len = 0; int err = GE_NOTFOUND; if (strlen(idnum) == 0) { gensio_pparm_slog(p, "You must provide an id or number to compare"); return GE_INVAL; } udev = udev_new(); if (!udev) { gensio_pparm_slog(p, "Error opening udev()"); return GE_NOTFOUND; } e = udev_enumerate_new(udev); udev_enumerate_add_match_subsystem(e, "sound"); udev_enumerate_scan_devices(e); devices = udev_enumerate_get_list_entry(e); udev_list_entry_foreach(l, devices) { const char *devnode; path = udev_list_entry_get_name(l); d = udev_device_new_from_syspath(udev, path); devnode = udev_device_get_devnode(d); if (!devnode) { const char *id = udev_device_get_sysattr_value(d, "id"); const char *num = udev_device_get_sysattr_value(d, "number"); #if 0 printf(" path = %s\n", path); if (id) printf(" id = %s\n", id); if (num) printf(" number = %s\n", num); #endif f = NULL; if (id && strcmp(id, idnum) == 0) f = d; else if (num && strcmp(num, idnum) == 0) f = d; continue; } if (!f) continue; pd = udev_device_get_parent_with_subsystem_devtype(d, "usb", "usb_device"); if (pd) { #if 0 const char *p; printf(" path = %s\n", path); p = udev_device_get_sysattr_value(pd, "idVendor"); if (p) printf(" idVendor = %s\n", p); p = udev_device_get_sysattr_value(pd, "idProduct"); if (p) printf(" idProduct = %s\n", p); #endif sounddev = f; break; } } if (!sounddev) { gensio_pparm_slog(p, "Unable to find matching sound device"); err = GE_IOERR; goto out_err; } endp = my_strrstr(path, "/sound/"); if (!endp) { gensio_pparm_log(p, "No /sound/ in device path: %s", path); err = GE_IOERR; goto out_err; } basepath = strndup(path, endp - path); udev_enumerate_unref(e); e = NULL; tmps = strrchr(basepath, ':'); if (!tmps) { gensio_pparm_log(p, "No valid ':' in device path: %s", basepath); err = GE_IOERR; goto out_err; } basepath_len = tmps - basepath; *tmps = '\0'; e = udev_enumerate_new(udev); udev_enumerate_add_match_subsystem(e, "hidraw"); udev_enumerate_scan_devices(e); devices = udev_enumerate_get_list_entry(e); udev_list_entry_foreach(l, devices) { path = udev_list_entry_get_name(l); #if 0 const char *devnode; d = udev_device_new_from_syspath(udev, path); devnode = udev_device_get_devnode(d); if (!devnode) { printf(" id = %s\n", udev_device_get_sysattr_value(d, "id")); printf(" number = %s\n", udev_device_get_sysattr_value(d, "number")); continue; } pd = udev_device_get_parent_with_subsystem_devtype(d, "usb", "usb_device"); if (pd) { const char *p; p = udev_device_get_sysattr_value(pd, "idVendor"); if (p) printf(" idVendor = %s\n", p); p = udev_device_get_sysattr_value(pd, "idProduct"); if (p) printf(" idProduct = %s\n", p); } #endif if (strncmp(path, basepath, basepath_len) == 0) { char *n = strrchr(path, '/'); if (!n) { gensio_pparm_log(p, "No '/'' in path: %s", path); goto out_err; } n = gensio_alloc_sprintf(o, "/dev%s", n); if (!n) { err = GE_NOMEM; goto out_err; } *devpath = n; err = 0; break; } } out_err: if (basepath) free(basepath); if (e) udev_enumerate_unref(e); udev_unref(udev); return err; } static int hid_write(struct gensio_os_funcs *o, int fd, unsigned char *io, unsigned int len) { int rv, err = 0; rv = write(fd, io, len); if (rv != len) err = gensio_os_err_to_err(o, errno); return err; } static int hid_open(struct gensio_os_funcs *o, const char *path, int *newfd) { int fd = open(path, O_WRONLY); int err = 0; if (fd == -1) err = gensio_os_err_to_err(o, errno); else *newfd = fd; return err; } static void hid_close(int fd) { close(fd); } #elif defined(_WIN32) || defined(__MSYS__) #include #include #include #include #include /* Stolen from hidclass.h. */ static const GUID my_GUID_DEVINTERFACE_HID = {0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30} }; /* * Stolen from devpropdef.h and devpkey.h. I'd use what was defined * there, but I can't find the actual implementation anywhere. */ #define MY_DEFINE_DEVPROPKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) \ static const DEVPROPKEY name = {{ l, w1, w2, {b1, b2, b3, b4, b5, b6, \ b7, b8}}, pid} MY_DEFINE_DEVPROPKEY(my_DEVPKEY_Device_MatchingDeviceId, 0xa8b865dd,0x2e3d,0x4094,0xad,0x97,0xe5,0x93,0xa7,0xc,0x75,0xd6, 8); MY_DEFINE_DEVPROPKEY(my_DEVPKEY_Device_Parent, 0x4340a6c5,0x93fa,0x4706,0x97,0x2c,0x7b,0x64,0x80,0x08,0xa5,0xa7, 8); struct win_hid_fd { struct gensio_os_funcs *o; HANDLE h; unsigned int min_write; unsigned char *write_buffer; }; #define fdtype struct win_hid_fd * #define INVALID_FD NULL /* * Search up the parent chain until we find a USB composite device. */ static int find_usb_composite_parent(HDEVINFO devinfo, const SP_DEVINFO_DATA *cdev_data, wchar_t *composite_parent, unsigned int len) { SP_DEVINFO_DATA dev_data = *cdev_data; unsigned int up_count = 3; int j; while (up_count > 0) { DEVPROPTYPE proptype = DEVPROP_TYPE_STRING; wchar_t id[100]; if (SetupDiGetDevicePropertyW(devinfo, &dev_data, &my_DEVPKEY_Device_MatchingDeviceId, &proptype, (PBYTE) id, sizeof(id), NULL, 0)) { if (wcscmp(id, L"USB\\COMPOSITE") == 0) return 0; } /* That wasn't a USB composite device, go to the parent. */ if (!SetupDiGetDevicePropertyW(devinfo, &dev_data, &my_DEVPKEY_Device_Parent, &proptype, (PBYTE)composite_parent, len, NULL, 0)) return GE_NOTFOUND; /* * Windows seems to use different cases for the same device in * different instances. Sigh. */ for (j = 0; j < len - 1 && composite_parent[j]; j++) composite_parent[j] = towupper(composite_parent[j]); composite_parent[j] = 0; if (!SetupDiOpenDeviceInfoW(devinfo, composite_parent, NULL, 0, &dev_data)) return GE_NOTFOUND; up_count--; } return GE_NOTFOUND; } /* * This searches through the setup api for a media device with the * given idname as part of it, just like the search for a sound card * will work in the sound gensio. Then it gets the USB composite * device id from it. * * Once it has the USB composite device id for the sound device, it * looks through all the HID devices for the same USB composite device * id parent. If it finds a match, it tries to open it, and if it * succeeds it returns the path for the device. * * According to the Windows docs, the container id is used to identify * devices on the same hardware, but for USB devices that appears to * be the USB hub. So we go with finding the parent USB composite * device id. */ static int find_hid_device(struct gensio_pparm_info *p, struct gensio_os_funcs *o, const char *idnum, char **devpath) { HDEVINFO devinfo; unsigned int i; int devidx, err = 0; char *mypath = NULL; wchar_t sounddev_composite_parent[256]; DWORD size; SP_DEVINFO_DATA dev_data; SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_if_detail = NULL; devinfo = SetupDiGetClassDevsA(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE | DIGCF_ALLCLASSES); if (devinfo == INVALID_HANDLE_VALUE) { gensio_pparm_slog(p, "Unable to get class devices"); return GE_NOTFOUND; } /* Find the sound device by friendly name. */ for (i = 0; ; i++) { char name[256], classname[256]; memset(&dev_data, 0x0, sizeof(dev_data)); dev_data.cbSize = sizeof(SP_DEVINFO_DATA); if (!SetupDiEnumDeviceInfo(devinfo, i, &dev_data)) break; if (!SetupDiGetDeviceRegistryPropertyA(devinfo, &dev_data, SPDRP_CLASS, NULL, (PBYTE)classname, sizeof(classname), NULL)) continue; /* The sound device must have class "MEDIA". */ if (strcmp(classname, "MEDIA") != 0) continue; if (!SetupDiGetDeviceRegistryPropertyA(devinfo, &dev_data, SPDRP_FRIENDLYNAME, NULL, (PBYTE)name, sizeof(name), NULL)) continue; if (!strstr(name, idnum)) continue; if (find_usb_composite_parent(devinfo, &dev_data, sounddev_composite_parent, sizeof(sounddev_composite_parent))) continue; #if 0 printf("Found %s (%ls)\n", name, sounddev_composite_parent); #endif goto foundsound; } gensio_pparm_log(p, "Unable to find media device '%s'", idnum); err = GE_NOTFOUND; goto out; foundsound: /* Find the HID device with the same USB composite parent. */ for (i = 0; ; i++) { char classname[256]; wchar_t hiddev_composite_parent[256]; memset(&dev_data, 0x0, sizeof(dev_data)); dev_data.cbSize = sizeof(SP_DEVINFO_DATA); if (!SetupDiEnumDeviceInfo(devinfo, i, &dev_data)) break; if (!SetupDiGetDeviceRegistryPropertyA(devinfo, &dev_data, SPDRP_CLASS, NULL, (PBYTE)classname, sizeof(classname), NULL)) continue; if (strcmp(classname, "HIDClass") != 0) continue; if (find_usb_composite_parent(devinfo, &dev_data, hiddev_composite_parent, sizeof(hiddev_composite_parent))) continue; if (wcscmp(sounddev_composite_parent, hiddev_composite_parent) != 0) continue; #if 0 printf("Found HID (%ls)\n", hiddev_composite_parent); #endif /* Now that we have the device, enumerate the interfaces to get the path. */ for (devidx = 0; ; devidx++) { SP_DEVICE_INTERFACE_DATA dev_if_data; dev_if_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); if (!SetupDiEnumDeviceInterfaces(devinfo, &dev_data, &my_GUID_DEVINTERFACE_HID, devidx, &dev_if_data)) break; /* * Get the device path for the device. Fetch the size first and * allocate the data. */ size = 0; SetupDiGetDeviceInterfaceDetailA(devinfo, &dev_if_data, NULL, 0, &size, NULL); if (size == 0) continue; dev_if_detail = malloc(size); if (!dev_if_detail) { err = GE_NOMEM; continue; } dev_if_detail->cbSize = sizeof(*dev_if_detail); if (SetupDiGetDeviceInterfaceDetailA(devinfo, &dev_if_data, dev_if_detail, size, NULL, NULL)) { mypath = gensio_strdup(o, dev_if_detail->DevicePath); if (!mypath) err = GE_NOMEM; free(dev_if_detail); goto out; } free(dev_if_detail); } } gensio_pparm_log(p, "Unable to find HID device associated with '%s'", idnum); err = GE_NOTFOUND; out: SetupDiDestroyDeviceInfoList(devinfo); if (!err) *devpath = mypath; return err; } static int hid_write(struct gensio_os_funcs *o, struct win_hid_fd *fd, unsigned char *io, unsigned int len) { if (len < fd->min_write) { memset(fd->write_buffer, 0, fd->min_write); memcpy(fd->write_buffer, io, len); len = fd->min_write; io = fd->write_buffer; } if (!WriteFile(fd->h, io, len, NULL, NULL)) return gensio_os_err_to_err(fd->o, GetLastError()); return 0; } static int hid_open(struct gensio_os_funcs *o, const char *path, struct win_hid_fd **newfd) { struct win_hid_fd *fd; HANDLE h; HIDP_CAPS caps; PHIDP_PREPARSED_DATA pp_data; fd = o->zalloc(o, sizeof(*fd)); if (!fd) return GE_NOMEM; h = CreateFileA(path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); if (h == INVALID_HANDLE_VALUE) { o->free(o, fd); return gensio_os_err_to_err(o, GetLastError()); } fd->o = o; fd->h = h; /* Set the Input Report buffer size to 64 reports. */ if (!HidD_SetNumInputBuffers(h, 64)) { o->free(o, fd); return gensio_os_err_to_err(o, GetLastError()); } /* Get the Input Report length for the device. */ if (!HidD_GetPreparsedData(h, &pp_data)) { o->free(o, fd); return gensio_os_err_to_err(o, GetLastError()); } if (HidP_GetCaps(pp_data, &caps) != HIDP_STATUS_SUCCESS) { HidD_FreePreparsedData(pp_data); o->free(o, fd); return gensio_os_err_to_err(o, GetLastError()); } fd->min_write = caps.OutputReportByteLength; HidD_FreePreparsedData(pp_data); if (fd->min_write > 0) { fd->write_buffer = o->zalloc(o, fd->min_write); if (!fd->write_buffer) { o->free(o, fd); return GE_NOMEM; } } *newfd = fd; return 0; } static void hid_close(struct win_hid_fd *fd) { CloseHandle(fd->h); fd->o->free(fd->o, fd); } #else #error "cm108gpio can only be compiled on Linux or Windows" #endif enum cm108gpio_state { CM108GPIO_CLOSED, CM108GPIO_IN_OPEN, CM108GPIO_OPEN, CM108GPIO_IN_OPEN_CLOSE, CM108GPIO_IN_CLOSE, }; struct cm108gpio_data { struct gensio_os_funcs *o; struct gensio_lock *lock; unsigned int refcount; enum cm108gpio_state state; struct gensio *io; char *devpath; fdtype fd; char *idnum; unsigned int bit; bool xmit_enabled; gensio_done_err open_done; void *open_data; gensio_done close_done; void *close_data; /* * Used to run read callbacks from the selector to avoid running * it directly from user calls. */ bool deferred_op_pending; struct gensio_runner *deferred_op_runner; }; static void cm108gpio_finish_free(struct cm108gpio_data *ndata) { struct gensio_os_funcs *o = ndata->o; if (ndata->io) gensio_data_free(ndata->io); if (ndata->idnum) o->free(o, ndata->idnum); if (ndata->devpath) o->free(o, ndata->devpath); if (ndata->lock) o->free_lock(ndata->lock); if (ndata->deferred_op_runner) o->free_runner(ndata->deferred_op_runner); o->free(o, ndata); } static void cm108gpio_lock(struct cm108gpio_data *ndata) { ndata->o->lock(ndata->lock); } static void cm108gpio_unlock(struct cm108gpio_data *ndata) { ndata->o->unlock(ndata->lock); } static void cm108gpio_ref(struct cm108gpio_data *ndata) { assert(ndata->refcount > 0); ndata->refcount++; } static void cm108gpio_unlock_and_deref(struct cm108gpio_data *ndata) { assert(ndata->refcount > 0); if (ndata->refcount == 1) { cm108gpio_unlock(ndata); cm108gpio_finish_free(ndata); } else { ndata->refcount--; cm108gpio_unlock(ndata); } } static void cm108gpio_deferred_op(struct gensio_runner *runner, void *cb_data) { struct cm108gpio_data *ndata = cb_data; int err = 0; cm108gpio_lock(ndata); restart: if (ndata->state == CM108GPIO_IN_OPEN || ndata->state == CM108GPIO_IN_OPEN_CLOSE) { if (ndata->state == CM108GPIO_IN_OPEN_CLOSE) { ndata->state = CM108GPIO_IN_CLOSE; err = GE_LOCALCLOSED; } else { ndata->state = CM108GPIO_OPEN; } if (ndata->open_done) { cm108gpio_unlock(ndata); ndata->open_done(ndata->io, err, ndata->open_data); cm108gpio_lock(ndata); } } while (ndata->state == CM108GPIO_OPEN && ndata->xmit_enabled) { cm108gpio_unlock(ndata); err = gensio_cb(ndata->io, GENSIO_EVENT_WRITE_READY, 0, NULL, NULL, NULL); cm108gpio_lock(ndata); if (err) break; } if (ndata->state == CM108GPIO_IN_CLOSE) { hid_close(ndata->fd); ndata->fd = INVALID_FD; ndata->state = CM108GPIO_CLOSED; if (ndata->close_done) { cm108gpio_unlock(ndata); ndata->close_done(ndata->io, ndata->close_data); cm108gpio_unlock(ndata); } if (ndata->state != CM108GPIO_CLOSED) goto restart; } ndata->deferred_op_pending = false; cm108gpio_unlock_and_deref(ndata); } static void cm108gpio_start_deferred_op(struct cm108gpio_data *ndata) { if (!ndata->deferred_op_pending) { /* Call the read from the selector to avoid lock nesting issues. */ ndata->deferred_op_pending = true; ndata->o->run(ndata->deferred_op_runner); cm108gpio_ref(ndata); } } static void cm108gpio_set_write_callback_enable(struct gensio *io, bool enabled) { struct cm108gpio_data *ndata = gensio_get_gensio_data(io); cm108gpio_lock(ndata); ndata->xmit_enabled = enabled; if (enabled && ndata->state == CM108GPIO_OPEN) cm108gpio_start_deferred_op(ndata); cm108gpio_unlock(ndata); } static int cm108gpio_hid_set(struct cm108gpio_data *ndata, int set) { unsigned char io[5]; io[0] = 0; io[1] = 0; io[2] = set << (ndata->bit - 1); io[3] = 1 << (ndata->bit - 1); io[4] = 0; return hid_write(ndata->o, ndata->fd, io, 5); } static int cm108gpio_write(struct gensio *io, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen) { struct cm108gpio_data *ndata = gensio_get_gensio_data(io); gensiods i, j, count = 0; int set = 0, err = 0; for (i = 0; i < sglen; i++) { const char *s = sg[i].buf; for (j = 0; j < sg[i].buflen; j++) { if (s[j] == '1') set = 1; else if (s[j] == '0') set = -1; count++; } } cm108gpio_lock(ndata); if (ndata->state != CM108GPIO_OPEN) { cm108gpio_unlock(ndata); return GE_NOTREADY; } if (set != 0) { if (set < 0) set = 0; err = cm108gpio_hid_set(ndata, set); } cm108gpio_unlock(ndata); if (rcount) *rcount = count; return err; } static int cm108gpio_open(struct gensio *io, gensio_done_err open_done, void *open_data) { struct cm108gpio_data *ndata = gensio_get_gensio_data(io); int err = 0; cm108gpio_lock(ndata); if (ndata->state != CM108GPIO_CLOSED) { err = GE_NOTREADY; goto out_unlock; } err = hid_open(ndata->o, ndata->devpath, &ndata->fd); if (!err) { ndata->state = CM108GPIO_IN_OPEN; ndata->open_done = open_done; ndata->open_data = open_data; cm108gpio_start_deferred_op(ndata); } out_unlock: cm108gpio_unlock(ndata); return err; } static int cm108gpio_close(struct gensio *io, gensio_done close_done, void *close_data) { struct cm108gpio_data *ndata = gensio_get_gensio_data(io); int err = 0; cm108gpio_lock(ndata); if (ndata->state != CM108GPIO_OPEN && ndata->state != CM108GPIO_IN_OPEN) { err = GE_NOTREADY; goto out_unlock; } if (ndata->state == CM108GPIO_IN_OPEN) ndata->state = CM108GPIO_IN_OPEN_CLOSE; else ndata->state = CM108GPIO_IN_CLOSE; ndata->close_done = close_done; ndata->close_data = close_data; cm108gpio_start_deferred_op(ndata); out_unlock: cm108gpio_unlock(ndata); return err; } static void cm108gpio_free(struct gensio *io) { struct cm108gpio_data *ndata = gensio_get_gensio_data(io); cm108gpio_lock(ndata); ndata->state = CM108GPIO_CLOSED; cm108gpio_unlock_and_deref(ndata); } static int cm108gpio_disable(struct gensio *io) { struct cm108gpio_data *ndata = gensio_get_gensio_data(io); cm108gpio_lock(ndata); ndata->state = CM108GPIO_CLOSED; cm108gpio_unlock(ndata); return 0; } static int cm108gpio_control(struct gensio *io, bool get, int option, char *data, gensiods *datalen) { struct cm108gpio_data *ndata = gensio_get_gensio_data(io); if (option != GENSIO_CONTROL_RADDR) return GE_NOTSUP; if (!get) return GE_NOTSUP; if (strtoul(data, NULL, 0) > 0) return GE_NOTFOUND; *datalen = gensio_pos_snprintf(data, *datalen, NULL, "cm108gpio,%s,%u", ndata->idnum, ndata->bit); return 0; } static int gensio_cm108gpio_func(struct gensio *io, int func, gensiods *count, const void *cbuf, gensiods buflen, void *buf, const char *const *auxdata) { switch (func) { case GENSIO_FUNC_WRITE_SG: return cm108gpio_write(io, count, cbuf, buflen); case GENSIO_FUNC_OPEN: return cm108gpio_open(io, (void *) cbuf, buf); case GENSIO_FUNC_CLOSE: return cm108gpio_close(io, (void *) cbuf, buf); case GENSIO_FUNC_FREE: cm108gpio_free(io); return 0; case GENSIO_FUNC_SET_READ_CALLBACK: return 0; case GENSIO_FUNC_SET_WRITE_CALLBACK: cm108gpio_set_write_callback_enable(io, buflen); return 0; case GENSIO_FUNC_DISABLE: return cm108gpio_disable(io); case GENSIO_FUNC_CONTROL: return cm108gpio_control(io, *((bool *) cbuf), buflen, buf, count); default: return GE_NOTSUP; } } static int cm108gpio_ndata_setup(struct gensio_pparm_info *p, struct gensio_os_funcs *o, const char *idnum, unsigned int bit, struct cm108gpio_data **new_ndata) { struct cm108gpio_data *ndata; int err = GE_NOMEM; ndata = o->zalloc(o, sizeof(*ndata)); if (!ndata) return GE_NOMEM; ndata->o = o; ndata->refcount = 1; ndata->fd = INVALID_FD; if (!idnum) idnum = ""; ndata->idnum = gensio_strdup(o, idnum); if (!ndata->idnum) goto out_err; ndata->bit = bit; ndata->lock = o->alloc_lock(o); if (!ndata->lock) goto out_err; ndata->deferred_op_runner = o->alloc_runner(o, cm108gpio_deferred_op, ndata); if (!ndata->deferred_op_runner) goto out_err; err = find_hid_device(p, o, idnum, &ndata->devpath); if (err) goto out_err; *new_ndata = ndata; return 0; out_err: cm108gpio_finish_free(ndata); return err; } static int cm108gpio_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct cm108gpio_data *ndata = NULL; int i; GENSIO_DECLARE_PPGENSIO(p, o, cb, "cm108gpio", user_data); unsigned int bit = 3; for (i = 0; args && args[i]; i++) { if (gensio_pparm_uint(&p, args[i], "bit", &bit) > 0) continue; gensio_pparm_unknown_parm(&p, args[i]); return GE_INVAL; } if (bit < 1 || bit > 8) { gensio_pparm_log(&p, "Bit value must be from 1-8, it was %u", bit); return GE_INVAL; } err = cm108gpio_ndata_setup(&p, o, gdata, bit, &ndata); if (err) return err; ndata->io = gensio_data_alloc(ndata->o, cb, user_data, gensio_cm108gpio_func, NULL, "cm108gpio", ndata); if (!ndata->io) goto out_nomem; *new_gensio = ndata->io; return 0; out_nomem: cm108gpio_finish_free(ndata); return GE_NOMEM; } static int str_to_cm108gpio_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { return cm108gpio_gensio_alloc(str, args, o, cb, user_data, new_gensio); } int gensio_init_cm108gpio(struct gensio_os_funcs *o) { int rv; rv = register_gensio(o, "cm108gpio", str_to_cm108gpio_gensio, cm108gpio_gensio_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/gensio_base_parms.h0000664000175000017500000000073415011177264013070 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #ifndef _GENSIO_BASEN_PARMS_H #define _GENSIO_BASEN_PARMS_H #include struct gensio_base_parms { struct gensio_os_funcs *o; int drain_timeout; }; void i_gensio_base_parms_set(struct gensio *io, const struct gensio_base_parms *parms); #endif /* _GENSIO_BASEN_PARMS_H */ gensio-3.0.0/lib/gensio_ssl.c0000664000175000017500000012304015055560534011550 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018-2025 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 /* On Windows you can use / or \. */ #define DIRSEPS "\\/" #else #define DIRSEPS "/" #endif struct gensio_ssl_filter_data { struct gensio_os_funcs *o; bool is_client; char *CAfilepath; char *keyfile; char *certfile; gensiods max_read_size; gensiods max_write_size; bool allow_authfail; bool clientauth; /* Amount of time in which the connection process must complete. */ gensio_time con_timeout; }; static void gensio_do_ssl_init(void *cb_data) { SSL_library_init(); } static struct gensio_once gensio_ssl_init_once; static void gensio_ssl_initialize(struct gensio_os_funcs *o) { o->call_once(o, &gensio_ssl_init_once, gensio_do_ssl_init, NULL); } struct ssl_filter { struct gensio_filter *filter; struct gensio_os_funcs *o; bool is_client; bool connected; bool shutdown_success; int err; struct gensio_lock *lock; SSL_CTX *ctx; SSL *ssl; BIO *ssl_bio; BIO *io_bio; X509 *remcert; X509_STORE *verify_store; bool expect_peer_cert; bool allow_authfail; /* try_connect() has been called at least once. */ bool started; /* Time to wait for the connection to complete. */ gensio_time con_timeout; /* Absolute time when the connection will time out. */ gensio_time contime_done; /* This is data from SSL_read() that is waiting to be sent to the user. */ unsigned char *read_data; gensiods read_data_pos; gensiods read_data_len; gensiods max_read_size; bool in_ul_handler; /* * This is data from the user waiting to be sent to SSL_write(). This * is required because if SSL_write() return that it needs I/O, it must * be called again with exactly the same data. */ unsigned char *write_data; gensiods max_write_size; gensiods write_data_len; /* This is data from BIO_read() waiting to be sent to the lower layer. */ unsigned char *xmit_buf; gensiods xmit_buf_pos; gensiods xmit_buf_len; gensiods max_xmit_buf; /* * SSL has asked for something. */ bool want_write; bool want_read; /* * This is not intrinsically part of the SSL protocol, but is here * so the set username control works, for convenience of the user * and consistency with certauth. */ char *username; }; #define filter_to_ssl(v) ((struct ssl_filter *) gensio_filter_get_user_data(v)) static void ssl_lock(struct ssl_filter *sfilter); static void ssl_unlock(struct ssl_filter *sfilter); /* * This function releases and reclaims the lock, so it can only be * called in places where this is ok. */ static void gssl_vlog(struct ssl_filter *f, enum gensio_log_levels l, bool do_ssl_err, char *fmt, va_list ap) { ssl_unlock(f); if (do_ssl_err) { char buf[256], buf2[200]; unsigned long ssl_err = ERR_get_error(); if (!ssl_err) goto no_ssl_err; ERR_error_string_n(ssl_err, buf2, sizeof(buf2)); snprintf(buf, sizeof(buf), "ssl: %s: %s", fmt, buf2); gensio_filter_vlog(f->filter, l, buf, ap); } else { no_ssl_err: gensio_filter_vlog(f->filter, l, fmt, ap); } ssl_lock(f); } static void gssl_log_info(struct ssl_filter *f, char *fmt, ...) { va_list ap; va_start(ap, fmt); gssl_vlog(f, GENSIO_LOG_INFO, false, fmt, ap); va_end(ap); } static void gssl_log_err(struct ssl_filter *f, char *fmt, ...) { va_list ap; va_start(ap, fmt); gssl_vlog(f, GENSIO_LOG_ERR, false, fmt, ap); va_end(ap); } static void gssl_logs_info(struct ssl_filter *f, char *fmt, ...) { va_list ap; va_start(ap, fmt); gssl_vlog(f, GENSIO_LOG_INFO, true, fmt, ap); va_end(ap); } static void gssl_logs_err(struct ssl_filter *f, char *fmt, ...) { va_list ap; va_start(ap, fmt); gssl_vlog(f, GENSIO_LOG_ERR, true, fmt, ap); va_end(ap); } static void ssl_lock(struct ssl_filter *sfilter) { sfilter->o->lock(sfilter->lock); } static void ssl_unlock(struct ssl_filter *sfilter) { sfilter->o->unlock(sfilter->lock); } static void ssl_set_callbacks(struct gensio_filter *filter, gensio_filter_cb cb, void *cb_data) { /* We don't currently use callbacks. */ } static bool ssl_ul_read_pending(struct gensio_filter *filter) { struct ssl_filter *sfilter = filter_to_ssl(filter); char buf[1]; bool rv; ssl_lock(sfilter); rv = sfilter->read_data_len || SSL_peek(sfilter->ssl, buf, 1) > 0; ssl_unlock(sfilter); return rv; } static bool ssl_ll_write_pending(struct gensio_filter *filter) { struct ssl_filter *sfilter = filter_to_ssl(filter); bool rv; ssl_lock(sfilter); rv = BIO_pending(sfilter->io_bio) || sfilter->write_data_len || sfilter->xmit_buf_len || sfilter->want_write; ssl_unlock(sfilter); return rv; } static bool ssl_ll_read_needed(struct gensio_filter *filter) { struct ssl_filter *sfilter = filter_to_ssl(filter); bool rv; ssl_lock(sfilter); rv = BIO_should_read(sfilter->io_bio) || sfilter->want_read; ssl_unlock(sfilter); return rv; } static bool ssl_ul_can_write(struct gensio_filter *filter, bool *val) { struct ssl_filter *sfilter = filter_to_ssl(filter); ssl_lock(sfilter); *val = sfilter->write_data_len == 0 && sfilter->xmit_buf_len == 0; ssl_unlock(sfilter); return 0; } static int ssl_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) { /* Always succeed, check the result in ssl_check_open_done(). */ return 1; } static int ssl_check_open_done(struct gensio_filter *filter, struct gensio *io) { struct ssl_filter *sfilter = filter_to_ssl(filter); long verify_err; int rv = 0; const char *auxdata[] = { NULL, NULL }; ssl_lock(sfilter); if (sfilter->expect_peer_cert) { sfilter->remcert = SSL_get_peer_certificate(sfilter->ssl); if (!sfilter->remcert) { gssl_log_info(sfilter, "Remote peer offered no certificate"); rv = GE_NOCERT; goto out_unlock; } verify_err = SSL_get_verify_result(sfilter->ssl); if (verify_err == X509_V_OK) gensio_set_is_authenticated(io, true); else if (verify_err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY || verify_err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) rv = GE_CERTNOTFOUND; else if (verify_err == X509_V_ERR_CERT_REVOKED) rv = GE_CERTREVOKED; else if (verify_err == X509_V_ERR_CERT_HAS_EXPIRED || verify_err == X509_V_ERR_CRL_HAS_EXPIRED) rv = GE_CERTEXPIRED; else rv = GE_CERTINVALID; ssl_unlock(sfilter); if (rv) auxdata[0] = X509_verify_cert_error_string(verify_err); rv = gensio_cb(io, GENSIO_EVENT_POSTCERT_VERIFY, rv, NULL, NULL, auxdata); ssl_lock(sfilter); if (rv == GE_NOTSUP) { if (verify_err != X509_V_OK) { gssl_logs_info(sfilter, "Remote peer certificate verify failed"); X509_free(sfilter->remcert); sfilter->remcert = NULL; rv = GE_CERTINVALID; } else { rv = 0; } } } out_unlock: if (rv && sfilter->allow_authfail) rv = 0; ssl_unlock(sfilter); return rv; } static void ssl_start_con_timeout(struct ssl_filter *sfilter) { struct gensio_os_funcs *o = sfilter->o; o->get_monotonic_time(o, &sfilter->contime_done); gensio_time_add(&sfilter->contime_done, &sfilter->con_timeout); } static int ssl_try_connect(struct gensio_filter *filter, gensio_time *timeout, bool was_timeout) { struct ssl_filter *sfilter = filter_to_ssl(filter); int rv, success, err; int64_t timeout_ns; gensio_time time_now; ssl_lock(sfilter); if (!sfilter->started) { ssl_start_con_timeout(sfilter); sfilter->started = true; } if (was_timeout) { gssl_log_err(sfilter, "Timed out waiting for connection to complete"); rv = GE_TIMEDOUT; goto out; } sfilter->want_read = false; sfilter->want_write = false; if (sfilter->is_client) success = SSL_connect(sfilter->ssl); else success = SSL_accept(sfilter->ssl); if (!success) { err = SSL_get_error(sfilter->ssl, success); goto err_rpt; } else if (success == 1) { sfilter->connected = true; rv = 0; } else { err = SSL_get_error(sfilter->ssl, success); switch (err) { case SSL_ERROR_WANT_READ: sfilter->want_read = true; rv = GE_INPROGRESS; break; case SSL_ERROR_WANT_WRITE: sfilter->want_write = true; rv = GE_INPROGRESS; break; case SSL_ERROR_SSL: gssl_logs_err(sfilter, "Failed SSL startup"); rv = GE_PROTOERR; break; case SSL_ERROR_ZERO_RETURN: rv = GE_REMCLOSE; break; default: err_rpt: gssl_log_err(sfilter, "Failed SSL startup: 0x%8.8x", err); rv = GE_COMMERR; } } if (rv == GE_INPROGRESS) { sfilter->o->get_monotonic_time(sfilter->o, &time_now); timeout_ns = gensio_time_diff_nsecs(&sfilter->contime_done, &time_now); if (timeout_ns < 0) timeout_ns = 0; timeout->secs = timeout_ns / GENSIO_NSECS_IN_SEC; timeout->nsecs = timeout_ns % GENSIO_NSECS_IN_SEC; rv = GE_RETRY; } out: ssl_unlock(sfilter); return rv; } static int ssl_try_disconnect(struct gensio_filter *filter, gensio_time *timeout) { struct ssl_filter *sfilter = filter_to_ssl(filter); int success, rv = GE_INPROGRESS, shutdown, err; ssl_lock(sfilter); sfilter->connected = false; shutdown = SSL_get_shutdown(sfilter->ssl); shutdown &= SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN; if (shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN)) { /* Shutdown is complete. */ rv = 0; goto out_unlock; } sfilter->want_read = false; sfilter->want_write = false; if (!sfilter->shutdown_success) { success = SSL_shutdown(sfilter->ssl); if (success >= 0) { sfilter->shutdown_success = true; if (success == 1) rv = 0; else sfilter->want_read = true; goto out_unlock; } err = SSL_get_error(sfilter->ssl, success); switch (err) { case SSL_ERROR_WANT_READ: sfilter->want_read = true; break; case SSL_ERROR_WANT_WRITE: sfilter->want_write = true; break; case SSL_ERROR_SSL: gssl_logs_err(sfilter, "Failed SSL shutdown"); rv = GE_PROTOERR; break; default: gssl_log_err(sfilter, "Failed SSL shutdown"); rv = GE_COMMERR; } } else { /* Waiting to receive the shutdown from the other end. */ sfilter->want_read = true; } out_unlock: if (!rv) sfilter->err = GE_LOCALCLOSED; ssl_unlock(sfilter); return rv; } static int ssl_ul_write(struct gensio_filter *filter, gensio_ul_filter_data_handler handler, void *cb_data, gensiods *rcount, const struct gensio_sg *isg, gensiods sglen, const char *const *auxdata) { struct ssl_filter *sfilter = filter_to_ssl(filter); int err = 0; gensiods i; ssl_lock(sfilter); if (sfilter->err) { if (rcount) { *rcount = 0; for (i = 0; i < sglen; i++) *rcount += isg[i].buflen; } err = sfilter->err; goto out_unlock; } if (!sfilter->connected) { /* No new data after a close. */ if (rcount) { *rcount = 0; for (i = 0; i < sglen; i++) *rcount += isg[i].buflen; } } else if (sfilter->write_data_len) { /* Ignore any incoming data if we already have some. */ if (rcount) *rcount = 0; } else { for (i = 0; i < sglen; i++) { gensiods buflen = isg[i].buflen; if (buflen > sfilter->max_write_size - sfilter->write_data_len) buflen = sfilter->max_write_size - sfilter->write_data_len; memcpy(sfilter->write_data + sfilter->write_data_len, isg[i].buf, buflen); sfilter->write_data_len += buflen; } if (rcount) *rcount = sfilter->write_data_len; } restart: if (sfilter->xmit_buf_len) { gensiods written; struct gensio_sg sg = { sfilter->xmit_buf + sfilter->xmit_buf_pos, sfilter->xmit_buf_len - sfilter->xmit_buf_pos }; err = handler(cb_data, &written, &sg, 1, NULL); if (err) { sfilter->xmit_buf_len = 0; sfilter->write_data_len = 0; } else { sfilter->xmit_buf_pos += written; if (sfilter->xmit_buf_pos >= sfilter->xmit_buf_len) sfilter->xmit_buf_len = 0; } } if (!err && sfilter->xmit_buf_len == 0 && sfilter->write_data_len > 0) { sfilter->want_read = false; sfilter->want_write = false; err = SSL_write(sfilter->ssl, sfilter->write_data, sfilter->write_data_len); if (err <= 0) { err = SSL_get_error(sfilter->ssl, err); switch (err) { case SSL_ERROR_WANT_READ: sfilter->want_read = true; err = 0; break; case SSL_ERROR_WANT_WRITE: sfilter->want_write = true; err = 0; break; case SSL_ERROR_SSL: gssl_logs_err(sfilter, "Failed SSL write"); err = GE_PROTOERR; sfilter->write_data_len = 0; break; case SSL_ERROR_ZERO_RETURN: err = GE_REMCLOSE; sfilter->write_data_len = 0; break; default: gssl_log_err(sfilter, "Failed SSL write: %d", err); err = GE_COMMERR; sfilter->write_data_len = 0; } } else { assert((gensiods) err == sfilter->write_data_len); sfilter->write_data_len = 0; err = 0; } } if (!err && sfilter->xmit_buf_len == 0) { int rdlen = BIO_read(sfilter->io_bio, sfilter->xmit_buf, sfilter->max_xmit_buf); if (rdlen <= 0) { if (!BIO_should_retry(sfilter->io_bio)) { gssl_log_err(sfilter, "Failed BIO read"); err = GE_COMMERR; } } else { sfilter->xmit_buf_len = rdlen; sfilter->xmit_buf_pos = 0; goto restart; } } if (err) sfilter->err = err; out_unlock: ssl_unlock(sfilter); return err; } static int ssl_ll_write(struct gensio_filter *filter, gensio_ll_filter_data_handler handler, void *cb_data, gensiods *rcount, unsigned char *buf, gensiods buflen, const char *const *auxdata) { struct ssl_filter *sfilter = filter_to_ssl(filter); int err = 0; if (gensio_str_in_auxdata(auxdata, "oob")) { /* Ignore oob data. */ if (rcount) *rcount = buflen; return 0; } ssl_lock(sfilter); if (sfilter->err) { if (rcount) *rcount = buflen; err = sfilter->err; goto out_unlock; } if (buflen > 0) { int wrlen = BIO_write(sfilter->io_bio, buf, buflen); if (wrlen <= 0) { if (!BIO_should_retry(sfilter->io_bio)) { gssl_log_err(sfilter, "Failed BIO write"); err = GE_COMMERR; wrlen = buflen; } else { wrlen = 0; } } if (rcount) *rcount = wrlen; } process_more: if (!sfilter->read_data_len) { int rlen; sfilter->want_read = false; sfilter->want_write = false; rlen = SSL_read(sfilter->ssl, sfilter->read_data, sfilter->max_read_size); if (rlen <= 0) { err = SSL_get_error(sfilter->ssl, rlen); switch (err) { case SSL_ERROR_WANT_READ: sfilter->want_read = true; err = 0; break; case SSL_ERROR_WANT_WRITE: sfilter->want_write = true; err = 0; break; case SSL_ERROR_SSL: gssl_logs_err(sfilter, "Failed SSL read"); #ifdef ENABLE_INTERNAL_TRACE /* * Report these as REMCLOSE when testing. These can * happen, I think, when data gets cut off to the SSL * code. It's a protocol error, but that can fail * some tests, and we want protocol errors elsewhere * to actually fail the tests. */ err = GE_REMCLOSE; #else err = GE_PROTOERR; #endif break; case SSL_ERROR_ZERO_RETURN: err = GE_REMCLOSE; break; default: gssl_log_err(sfilter, "Failed SSL read: %d", err); err = GE_COMMERR; } } else { sfilter->read_data_len = rlen; } sfilter->read_data_pos = 0; } if (!err && sfilter->read_data_len) { gensiods count = 0; assert(!sfilter->in_ul_handler); sfilter->in_ul_handler = true; ssl_unlock(sfilter); err = handler(cb_data, &count, sfilter->read_data + sfilter->read_data_pos, sfilter->read_data_len, NULL); ssl_lock(sfilter); sfilter->in_ul_handler = false; if (!err) { if (count >= sfilter->read_data_len) { sfilter->read_data_len = 0; sfilter->read_data_pos = 0; if (!sfilter->err && sfilter->connected) goto process_more; } else { sfilter->read_data_len -= count; sfilter->read_data_pos += count; } } } if (err && !sfilter->err) sfilter->err = err; out_unlock: ssl_unlock(sfilter); return err; } static int ssl_setup(struct gensio_filter *filter, struct gensio *io) { struct ssl_filter *sfilter = filter_to_ssl(filter); int success; gensiods bio_size = sfilter->max_read_size * 2; sfilter->ssl = SSL_new(sfilter->ctx); if (!sfilter->ssl) return GE_NOMEM; /* The BIO has to be large enough to hold a full SSL key transaction. */ if (bio_size < 4096) bio_size = 4096; success = BIO_new_bio_pair(&sfilter->ssl_bio, bio_size, &sfilter->io_bio, bio_size); if (!success) { SSL_free(sfilter->ssl); sfilter->ssl = NULL; return GE_NOMEM; } SSL_set_bio(sfilter->ssl, sfilter->ssl_bio, sfilter->ssl_bio); if (sfilter->is_client) SSL_set_connect_state(sfilter->ssl); else SSL_set_accept_state(sfilter->ssl); return 0; } static void ssl_cleanup(struct gensio_filter *filter) { struct ssl_filter *sfilter = filter_to_ssl(filter); if (sfilter->verify_store) X509_STORE_free(sfilter->verify_store); sfilter->verify_store = NULL; if (sfilter->remcert) X509_free(sfilter->remcert); sfilter->remcert = NULL; if (sfilter->ssl) SSL_free(sfilter->ssl); sfilter->ssl = NULL; if (sfilter->io_bio) /* Just free one BIO to free both parts of the pair. */ BIO_free(sfilter->io_bio); sfilter->ssl_bio = NULL; sfilter->io_bio = NULL; sfilter->err = 0; sfilter->read_data_len = 0; sfilter->read_data_pos = 0; sfilter->xmit_buf_len = 0; sfilter->xmit_buf_pos = 0; sfilter->write_data_len = 0; sfilter->connected = false; sfilter->shutdown_success = false; } static void sfilter_free(struct ssl_filter *sfilter) { if (sfilter->verify_store) X509_STORE_free(sfilter->verify_store); if (sfilter->remcert) X509_free(sfilter->remcert); if (sfilter->ssl) SSL_free(sfilter->ssl); if (sfilter->io_bio) /* Just free one BIO to free both parts of the pair. */ BIO_free(sfilter->io_bio); if (sfilter->ctx) SSL_CTX_free(sfilter->ctx); if (sfilter->lock) sfilter->o->free_lock(sfilter->lock); if (sfilter->read_data) { memset(sfilter->read_data, 0, sfilter->max_read_size); sfilter->o->free(sfilter->o, sfilter->read_data); } if (sfilter->xmit_buf) sfilter->o->free(sfilter->o, sfilter->xmit_buf); if (sfilter->write_data) sfilter->o->free(sfilter->o, sfilter->write_data); if (sfilter->filter) gensio_filter_free_data(sfilter->filter); sfilter->o->free(sfilter->o, sfilter); } static void ssl_free(struct gensio_filter *filter) { struct ssl_filter *sfilter = filter_to_ssl(filter); return sfilter_free(sfilter); } /* Also in gensio_filter_certauth.c. */ static int gensio_cert_get_name(X509 *cert, char *data, gensiods *datalen) { char *nidstr = NULL, *end; int index = -1, len, tlen, nid; int datasize; X509_NAME *nm; X509_NAME_ENTRY *e; ASN1_STRING *as; unsigned char *strobj; int strobjlen; ASN1_OBJECT *obj; if (!cert) return GE_NOCERT; datasize = *datalen; index = strtol(data, &end, 0); if (*end == ',') nidstr = end + 1; else if (*end) return GE_CERTINVALID; nm = X509_get_subject_name(cert); if (nidstr) { nid = OBJ_sn2nid(nidstr); if (nid == NID_undef) { nid = OBJ_ln2nid(data); if (nid == NID_undef) return GE_CERTINVALID; } index = X509_NAME_get_index_by_NID(nm, nid, index); if (index < 0) return GE_NOTFOUND; } e = X509_NAME_get_entry(nm, index); if (!e) return GE_NOTFOUND; obj = X509_NAME_ENTRY_get_object(e); nid = OBJ_obj2nid(obj); len = snprintf(data, datasize, "%d,%s,", index, OBJ_nid2sn(nid)); as = X509_NAME_ENTRY_get_data(e); strobjlen = ASN1_STRING_to_UTF8(&strobj, as); if (strobjlen < 0) return GE_NOMEM; tlen = strobjlen; if (len + 1 < datasize) { if (strobjlen > datasize - len - 1) strobjlen = datasize - len - 1; memcpy(data + len, strobj, strobjlen); data[strobjlen + len] = '\0'; } len += tlen; OPENSSL_free(strobj); *datalen = len; return 0; } /* Also in gensio_filter_certauth.c. */ static int gensio_cert_to_buf(X509 *cert, char *buf, gensiods *buflen) { BIO *mbio; BUF_MEM *bptr; gensiods len = *buflen, copylen; mbio = BIO_new(BIO_s_mem()); if (!mbio) return GE_NOMEM; if (PEM_write_bio_X509(mbio, cert) == 0) { BIO_free(mbio); return GE_IOERR; } BIO_get_mem_ptr(mbio, &bptr); *buflen = bptr->length; copylen = len; if (copylen > bptr->length) copylen = bptr->length; memcpy(buf, bptr->data, copylen); if (len > copylen) buf[copylen] = '\0'; BIO_free(mbio); return 0; } /* Also in gensio_filter_certauth.c. */ static int gensio_cert_fingerprint(X509 *cert, char *buf, gensiods *buflen) { gensiods len = *buflen, clen; unsigned int i, n, l; unsigned char md[EVP_MAX_MD_SIZE]; if (X509_digest(cert, EVP_sha1(), md, &n) == 0) return GE_NOMEM; clen = snprintf(buf, len, "%2.2X", md[0]); for (i = 1; i < n; i++) { if (clen >= len) l = 0; else l = len - clen; clen += snprintf(buf + clen, l, ":%2.2X", md[i]); } *buflen = clen; return 0; } static int ssl_filter_control(struct gensio_filter *filter, bool get, int op, char *data, gensiods *datalen) { struct ssl_filter *sfilter = filter_to_ssl(filter); X509_STORE *store; char *CApath = NULL, *CAfile = NULL; switch (op) { case GENSIO_CONTROL_GET_PEER_CERT_NAME: if (!get) return GE_NOTSUP; return gensio_cert_get_name(sfilter->remcert, data, datalen); case GENSIO_CONTROL_CERT_AUTH: if (get) return GE_NOTSUP; store = X509_STORE_new(); if (!store) return GE_NOMEM; if (strchr(DIRSEPS, data[strlen(data) - 1])) CApath = data; else CAfile = data; if (!X509_STORE_load_locations(store, CAfile, CApath)) { X509_STORE_free(store); return GE_CERTNOTFOUND; } ssl_lock(sfilter); if (sfilter->verify_store) X509_STORE_free(sfilter->verify_store); sfilter->verify_store = store; ssl_unlock(sfilter); return 0; case GENSIO_CONTROL_CERT: if (!get) return GE_NOTSUP; if (!sfilter->remcert) return GE_NOTFOUND; return gensio_cert_to_buf(sfilter->remcert, data, datalen); case GENSIO_CONTROL_CERT_FINGERPRINT: if (!get) return GE_NOTSUP; if (!sfilter->remcert) return GE_NOTFOUND; return gensio_cert_fingerprint(sfilter->remcert, data, datalen); case GENSIO_CONTROL_USERNAME: { int rv = 0; ssl_lock(sfilter); if (get) { if (!sfilter->username) { rv = GE_DATAMISSING; goto out_username; } *datalen = snprintf(data, *datalen, "%s", sfilter->username); } else { char *newusername = NULL; if (data) { newusername = gensio_strdup(sfilter->o, data); if (!newusername) { rv = GE_NOMEM; goto out_username; } } if (sfilter->username) sfilter->o->free(sfilter->o, sfilter->username); sfilter->username = data; } out_username: ssl_unlock(sfilter); return rv; } case GENSIO_CONTROL_MAX_WRITE_PACKET: if (!get) return GE_NOTSUP; *datalen = snprintf(data, *datalen, "%lu", (unsigned long) sfilter->max_write_size); return 0; default: return GE_NOTSUP; } } static int gensio_ssl_filter_func(struct gensio_filter *filter, int op, void *func, void *data, gensiods *count, void *buf, const void *cbuf, gensiods buflen, const char *const *auxdata) { switch (op) { case GENSIO_FILTER_FUNC_SET_CALLBACK: ssl_set_callbacks(filter, func, data); return 0; case GENSIO_FILTER_FUNC_UL_READ_PENDING: return ssl_ul_read_pending(filter); case GENSIO_FILTER_FUNC_LL_WRITE_PENDING: return ssl_ll_write_pending(filter); case GENSIO_FILTER_FUNC_LL_READ_NEEDED: return ssl_ll_read_needed(filter); case GENSIO_FILTER_FUNC_UL_CAN_WRITE: return ssl_ul_can_write(filter, data); case GENSIO_FILTER_FUNC_CHECK_OPEN_DONE: return ssl_check_open_done(filter, data); case GENSIO_FILTER_FUNC_TRY_CONNECT: return ssl_try_connect(filter, data, buflen); case GENSIO_FILTER_FUNC_TRY_DISCONNECT: return ssl_try_disconnect(filter, data); case GENSIO_FILTER_FUNC_UL_WRITE_SG: return ssl_ul_write(filter, func, data, count, cbuf, buflen, buf); case GENSIO_FILTER_FUNC_LL_WRITE: return ssl_ll_write(filter, func, data, count, buf, buflen, NULL); case GENSIO_FILTER_FUNC_SETUP: return ssl_setup(filter, data); case GENSIO_FILTER_FUNC_CLEANUP: ssl_cleanup(filter); return 0; case GENSIO_FILTER_FUNC_FREE: ssl_free(filter); return 0; case GENSIO_FILTER_FUNC_CONTROL: return ssl_filter_control(filter, *((bool *) cbuf), buflen, data, count); case GENSIO_FILTER_FUNC_TIMEOUT: default: return GE_NOTSUP; } } #if OPENSSL_VERSION_NUMBER < 0x10100000L #define X509_STORE_CTX_get0_cert(ctx) ((ctx)->cert) #define X509_STORE_CTX_get0_chain(ctx) ((ctx)->chain) #endif static int gensio_ssl_cert_verify(X509_STORE_CTX *ctx, void *cb_data) { struct ssl_filter *sfilter = cb_data; X509_STORE_CTX *nctx = NULL; X509 *cert = X509_STORE_CTX_get0_cert(ctx); int rv; sfilter->remcert = cert; /* * This should only occur from the BIO_write() into OpenSSL, so it * should be ok to unlock here. */ ssl_unlock(sfilter); rv = gensio_filter_do_event(sfilter->filter, GENSIO_EVENT_PRECERT_VERIFY, 0, NULL, NULL, NULL); ssl_lock(sfilter); if (rv && rv != GE_NOTSUP) return 0; if (sfilter->verify_store) { STACK_OF(X509) *cert_chain = X509_STORE_CTX_get0_chain(ctx); int ssl_ex_idx = SSL_get_ex_data_X509_STORE_CTX_idx(); SSL *s = X509_STORE_CTX_get_ex_data(ctx, ssl_ex_idx); X509_VERIFY_PARAM *param; rv = -1; nctx = X509_STORE_CTX_new(); if (!nctx) goto out_err; if (!X509_STORE_CTX_init(nctx, sfilter->verify_store, cert, cert_chain)) goto out_err; param = X509_VERIFY_PARAM_new(); if (!param) goto out_err; if (!X509_VERIFY_PARAM_set1(param, X509_STORE_CTX_get0_param(ctx))) { X509_VERIFY_PARAM_free(param); goto out_err; } X509_STORE_CTX_set0_param(nctx, param); X509_STORE_CTX_set_ex_data(nctx, ssl_ex_idx, s); ctx = nctx; } rv = X509_verify_cert(ctx); if (rv <= 0) gssl_log_err(sfilter, "Error verifying certificate: %s", X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx))); out: if (nctx) X509_STORE_CTX_free(nctx); return rv; out_err: gssl_log_err(sfilter, "Error initializing verify store"); goto out; } static struct gensio_filter * gensio_ssl_filter_raw_alloc(struct gensio_os_funcs *o, bool is_client, SSL_CTX *ctx, bool expect_peer_cert, bool allow_authfail, gensiods max_read_size, gensiods max_write_size, gensio_time con_timeout) { struct ssl_filter *sfilter; sfilter = o->zalloc(o, sizeof(*sfilter)); if (!sfilter) return NULL; sfilter->o = o; sfilter->is_client = is_client; sfilter->max_write_size = max_write_size; sfilter->max_read_size = max_read_size; sfilter->expect_peer_cert = expect_peer_cert; sfilter->allow_authfail = allow_authfail; sfilter->con_timeout = con_timeout; SSL_CTX_set_cert_verify_callback(ctx, gensio_ssl_cert_verify, sfilter); sfilter->lock = o->alloc_lock(o); if (!sfilter->lock) goto out_nomem; sfilter->read_data = o->zalloc(o, sfilter->max_read_size); if (!sfilter->read_data) goto out_nomem; sfilter->write_data = o->zalloc(o, sfilter->max_write_size); if (!sfilter->write_data) goto out_nomem; sfilter->max_xmit_buf = sfilter->max_write_size + 128; if (sfilter->max_xmit_buf < 1024) sfilter->max_xmit_buf = 1024; /* Enough room for the protocol. */ sfilter->xmit_buf = o->zalloc(o, sfilter->max_xmit_buf); if (!sfilter->xmit_buf) goto out_nomem; sfilter->filter = gensio_filter_alloc_data(o, gensio_ssl_filter_func, sfilter); if (!sfilter->filter) goto out_nomem; /* * Delay setting this so that it's not freed if there is a memory * allocation error. The caller passed it in, they should free it. */ sfilter->ctx = ctx; return sfilter->filter; out_nomem: sfilter_free(sfilter); return NULL; } static int gensio_ssl_filter_config(struct gensio_pparm_info *p, struct gensio_os_funcs *o, const char * const args[], bool default_is_client, struct gensio_base_parms *parms, struct gensio_ssl_filter_data **rdata) { unsigned int i; struct gensio_ssl_filter_data *data = o->zalloc(o, sizeof(*data)); int rv = GE_NOMEM, ival; char *str; const char *cstr; if (!data) return GE_NOMEM; data->o = o; data->is_client = default_is_client; data->max_write_size = SSL3_RT_MAX_PLAIN_LENGTH; data->max_read_size = SSL3_RT_MAX_PLAIN_LENGTH; rv = gensio_get_default(o, "ssl", "allow-authfail", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (rv) return rv; data->allow_authfail = ival; rv = gensio_get_default(o, "ssl", "clientauth", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (rv) return rv; data->clientauth = ival; rv = gensio_get_default(o, "ssl", "mode", false, GENSIO_DEFAULT_STR, &str, NULL); if (rv) { gensio_log(o, GENSIO_LOG_ERR, "Failed getting ssl mode: %s", gensio_err_to_str(rv)); return rv; } if (str) { if (strcasecmp(str, "client") == 0) data->is_client = true; else if (strcasecmp(str, "server") == 0) data->is_client = false; else { gensio_log(o, GENSIO_LOG_ERR, "Unknown default ssl mode (%s), ignoring", str); } o->free(o, str); } rv = gensio_get_default(o, "ssl", "con-timeout", false, GENSIO_DEFAULT_INT, NULL, &ival); if (rv) return rv; data->con_timeout.secs = ival; data->con_timeout.nsecs = 0; rv = GE_NOMEM; for (i = 0; args && args[i]; i++) { if (gensio_pparm_value(p, args[i], "CA", &cstr)) { data->CAfilepath = gensio_strdup(o, cstr); if (!data->CAfilepath) goto out_err; continue; } if (gensio_pparm_value(p, args[i], "key", &cstr)) { data->keyfile = gensio_strdup(o, cstr); if (!data->keyfile) goto out_err; continue; } if (gensio_pparm_value(p, args[i], "cert", &cstr)) { data->certfile = gensio_strdup(o, cstr); if (!data->certfile) goto out_err; continue; } if (gensio_pparm_ds(p, args[i], "readbuf", &data->max_read_size) > 0) continue; if (gensio_pparm_ds(p, args[i], "writebuf", &data->max_write_size) > 0) continue; if (gensio_pparm_boolv(p, args[i], "mode", "client", "server", &data->is_client) > 0) continue; if (gensio_pparm_bool(p, args[i], "allow-authfail", &data->allow_authfail) > 0) continue; if (gensio_pparm_bool(p, args[i], "clientauth", &data->clientauth) > 0) continue; if (gensio_pparm_time(p, args[i], "con-timeout", 's', &data->con_timeout) > 0) continue; if (gensio_base_parm(parms, p, args[i]) > 0) continue; gensio_pparm_unknown_parm(p, args[i]); rv = GE_INVAL; goto out_err; } if (!data->keyfile) { rv = gensio_get_default(o, "ssl", "key", false, GENSIO_DEFAULT_STR, &data->keyfile, NULL); if (rv) goto out_err; } if (!data->certfile) { rv = gensio_get_default(o, "ssl", "cert", false, GENSIO_DEFAULT_STR, &data->certfile, NULL); if (rv) goto out_err; } if (!data->CAfilepath) { rv = gensio_get_default(o, "ssl", "CA", false, GENSIO_DEFAULT_STR, &data->CAfilepath, NULL); if (rv) goto out_err; } if (!data->is_client) { if (!data->keyfile) { gensio_pparm_slog(p, "key must be specified for clients"); rv = GE_KEYNOTFOUND; goto out_err; } } if (data->keyfile && !data->certfile) { data->certfile = gensio_strdup(o, data->keyfile); if (!data->certfile) { rv = GE_NOMEM; goto out_err; } } *rdata = data; return 0; out_err: if (data->CAfilepath) o->free(o, data->CAfilepath); if (data->keyfile) o->free(o, data->keyfile); if (data->certfile) o->free(o, data->certfile); o->free(o, data); return rv; } static void gensio_ssl_filter_config_free(struct gensio_ssl_filter_data *data) { struct gensio_os_funcs *o; if (!data) return; o = data->o; if (data->CAfilepath) o->free(o, data->CAfilepath); if (data->keyfile) o->free(o, data->keyfile); if (data->certfile) o->free(o, data->certfile); o->free(o, data); } static int gensio_ssl_filter_alloc(struct gensio_ssl_filter_data *data, struct gensio_filter **rfilter) { struct gensio_os_funcs *o = data->o; SSL_CTX *ctx = NULL; struct gensio_filter *filter; bool expect_peer_cert; int rv = GE_INVAL; gensio_ssl_initialize(o); if (data->is_client) { expect_peer_cert = true; ctx = SSL_CTX_new(SSLv23_client_method()); } else { expect_peer_cert = data->clientauth; ctx = SSL_CTX_new(SSLv23_server_method()); } if (!ctx) return GE_NOMEM; if (!data->is_client && expect_peer_cert) /* * In server mode, the certificate will not be requested unless * mode is SSL_VERIFY_PEER. But in that mode, it terminates * the connection if there is no certificate in the default * verify callback. So use the below so that the server mode * works like client mode, request a certificate, but don't * terminate the connection automatically if it is not there * or fails. We will do that in the check open call. */ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, ssl_verify_cb); if (data->CAfilepath && data->CAfilepath[0]) { char *CAfile = NULL, *CApath = NULL; if (strchr(DIRSEPS, data->CAfilepath[strlen(data->CAfilepath) - 1])) CApath = data->CAfilepath; else CAfile = data->CAfilepath; if (!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) { rv = GE_CERTNOTFOUND; goto err; } } else { if (!SSL_CTX_set_default_verify_paths(ctx)) goto err; } if (data->certfile && data->certfile[0]) { if (!SSL_CTX_use_certificate_chain_file(ctx, data->certfile)) { rv = GE_CERTNOTFOUND; goto err; } if (!SSL_CTX_use_PrivateKey_file(ctx, data->keyfile, SSL_FILETYPE_PEM)) { rv = GE_KEYNOTFOUND; goto err; } if (!SSL_CTX_check_private_key(ctx)) { rv = GE_KEYINVALID; goto err; } } filter = gensio_ssl_filter_raw_alloc(o, data->is_client, ctx, expect_peer_cert, data->allow_authfail, data->max_read_size, data->max_write_size, data->con_timeout); if (!filter) { rv = GE_NOMEM; goto err; } *rfilter = filter; return 0; err: SSL_CTX_free(ctx); return rv; } static int ssl_gensio_alloc2(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio_base_parms *parms, struct gensio **net) { int err; struct gensio_filter *filter; struct gensio_ll *ll; struct gensio *io; struct gensio_ssl_filter_data *data; GENSIO_DECLARE_PPGENSIO(p, o, cb, "ssl", user_data); if (!gensio_is_reliable(child)) /* Cowardly refusing to run SSL over an unreliable connection. */ return GE_NOTSUP; if (!parms) { err = gensio_base_parms_alloc(o, true, "ssl", &parms); if (err) goto out_err; } err = gensio_ssl_filter_config(&p, o, args, true, parms, &data); if (err) goto out_err; err = gensio_ssl_filter_alloc(data, &filter); gensio_ssl_filter_config_free(data); if (err) goto out_err; ll = gensio_gensio_ll_alloc(o, child); if (!ll) { gensio_filter_free(filter); goto out_nomem; } gensio_ref(child); /* So gensio_ll_free doesn't free the child if fail */ io = base_gensio_alloc(o, ll, filter, child, "ssl", cb, user_data); if (!io) { gensio_ll_free(ll); gensio_filter_free(filter); goto out_nomem; } err = gensio_base_parms_set(io, &parms); if (err) { gensio_free(io); goto out_err; } gensio_set_is_packet(io, true); gensio_set_is_reliable(io, true); gensio_set_is_encrypted(io, true); gensio_free(child); /* Lose the ref we acquired. */ *net = io; return 0; out_nomem: err = GE_NOMEM; out_err: if (parms) gensio_base_parms_free(&parms); return err; } static int ssl_gensio_alloc(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **net) { return ssl_gensio_alloc2(child, args, o, cb, user_data, NULL, net); } static int str_to_ssl_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct gensio *io2; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio(str, o, cb, user_data, &io2); if (err) return err; err = ssl_gensio_alloc(io2, args, o, cb, user_data, new_gensio); if (err) gensio_free(io2); return err; } struct sslna_data { struct gensio_accepter *acc; struct gensio_ssl_filter_data *data; struct gensio_os_funcs *o; }; static void sslna_free(void *acc_data) { struct sslna_data *nadata = acc_data; gensio_ssl_filter_config_free(nadata->data); nadata->o->free(nadata->o, nadata); } static int sslna_alloc_gensio(void *acc_data, const char * const *iargs, struct gensio *child, struct gensio **rio) { struct sslna_data *nadata = acc_data; struct gensio_base_parms *parms = NULL; parms = gensio_acc_base_parms_dup(nadata->acc); if (!parms) return GE_NOMEM; return ssl_gensio_alloc2(child, iargs, nadata->o, NULL, NULL, parms, rio); } static int sslna_new_child(void *acc_data, void **finish_data, struct gensio_filter **filter) { struct sslna_data *nadata = acc_data; return gensio_ssl_filter_alloc(nadata->data, filter); } static int sslna_gensio_event(struct gensio *io, void *user_data, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) { struct sslna_data *nadata = user_data; if (event == GENSIO_EVENT_LOG) { struct gensio_log_data *d = (struct gensio_log_data *) buf; gensio_acc_vlog(nadata->acc, d->level, d->log, d->args); return 0; } if (event != GENSIO_EVENT_PRECERT_VERIFY) return GE_NOTSUP; return gensio_acc_cb(nadata->acc, GENSIO_ACC_EVENT_PRECERT_VERIFY, io); } static int sslna_finish_parent(void *acc_data, void *finish_data, struct gensio *io) { struct sslna_data *nadata = acc_data; int err; err = gensio_acc_base_parms_apply(nadata->acc, io); if (err) return err; gensio_set_callback(io, sslna_gensio_event, acc_data); gensio_set_is_packet(io, true); gensio_set_is_reliable(io, true); return 0; } static int gensio_gensio_acc_ssl_cb(void *acc_data, int op, void *data1, void *data2, void *data3, const void *data4) { switch (op) { case GENSIO_GENSIO_ACC_ALLOC_GENSIO: return sslna_alloc_gensio(acc_data, data4, data1, data2); case GENSIO_GENSIO_ACC_NEW_CHILD: return sslna_new_child(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FINISH_PARENT: return sslna_finish_parent(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FREE: sslna_free(acc_data); return 0; default: return GE_NOTSUP; } } static int ssl_gensio_accepter_alloc(struct gensio_accepter *child, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { struct sslna_data *nadata = NULL; int err; struct gensio_base_parms *parms = NULL; GENSIO_DECLARE_PPACCEPTER(p, o, cb, "ssl", user_data); if (!gensio_acc_is_reliable(child)) /* Cowardly refusing to run SSL over an unreliable connection. */ return GE_NOTSUP; err = gensio_base_parms_alloc(o, true, "ssl", &parms); if (err) goto out_err; nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) goto out_nomem; err = gensio_ssl_filter_config(&p, o, args, false, parms, &nadata->data); if (err) { o->free(o, nadata); nadata = NULL; goto out_err; } nadata->o = o; err = gensio_gensio_accepter_alloc(child, o, "ssl", cb, user_data, gensio_gensio_acc_ssl_cb, nadata, &nadata->acc); if (err) goto out_err; err = gensio_acc_base_parms_set(nadata->acc, &parms); if (err) goto out_err; gensio_acc_set_is_packet(nadata->acc, true); gensio_acc_set_is_reliable(nadata->acc, true); *accepter = nadata->acc; return 0; out_nomem: err = GE_NOMEM; out_err: if (nadata) { if (nadata->acc) gensio_acc_free(nadata->acc); else sslna_free(nadata); } if (parms) gensio_base_parms_free(&parms); return err; } static int str_to_ssl_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { int err; struct gensio_accepter *acc2 = NULL; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio_accepter(str, o, cb, user_data, &acc2); if (!err) { err = ssl_gensio_accepter_alloc(acc2, args, o, cb, user_data, acc); if (err) gensio_acc_free(acc2); } return err; } int gensio_init_ssl(struct gensio_os_funcs *o) { int rv; rv = register_filter_gensio(o, "ssl", str_to_ssl_gensio, ssl_gensio_alloc); if (rv) return rv; rv = register_filter_gensio_accepter(o, "ssl", str_to_ssl_gensio_accepter, ssl_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/telnet.c0000664000175000017500000001775014664224267010715 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include "telnet.h" static struct telnet_cmd * find_cmd(struct telnet_cmd *array, unsigned char option) { int i; for (i = 0; array[i].option != TELNET_CMD_END_OPTION; i++) { if (array[i].option == option) return &array[i]; } return NULL; } void telnet_cmd_send(telnet_data_t *td, const unsigned char *cmd, unsigned int len) { if (gensio_buffer_output(&td->out_telnet_cmd, cmd, len) < len) { /* Out of data, abort the connection. This really shouldn't happen.*/ td->error = 1; return; } td->output_ready(td->cb_data); } static void send_i(telnet_data_t *td, unsigned char type, unsigned char option) { unsigned char i[3]; i[0] = TN_IAC; i[1] = type; i[2] = option; telnet_cmd_send(td, i, 3); } static void handle_telnet_cmd(telnet_data_t *td, unsigned int size) { unsigned char *cmd_str = td->telnet_cmd; struct telnet_cmd *cmd; int rv; unsigned char option; if (size < 2) return; if (cmd_str[1] < TN_SB) { /* A one-byte command. */ td->cmd_handler(td->cb_data, cmd_str[1]); return; } /* Everything else is at least 3 bytes. */ if (size < 3) return; if (cmd_str[1] == TN_SB) { /* Option */ cmd = find_cmd(td->cmds, cmd_str[2]); if (!cmd || !cmd->option_handler) return; cmd->option_handler(td->cb_data, cmd_str + 2, size - 2); } else if (cmd_str[1] == TN_WILL) { option = cmd_str[2]; cmd = find_cmd(td->cmds, option); if (!cmd) { send_i(td, TN_DONT, option); } else { rv = cmd->i_do; if (!rv && cmd->will_do_handler) { rv = cmd->will_do_handler(td->cb_data, TN_WILL); cmd->i_do = rv; } if (!rv || !cmd->sent_do) { send_i(td, rv ? TN_DO : TN_DONT, option); cmd->sent_do = 1; } cmd->rem_will = rv; } } else if (cmd_str[1] == TN_WONT) { option = cmd_str[2]; cmd = find_cmd(td->cmds, option); if (cmd) { if (cmd->will_do_handler) cmd->will_do_handler(td->cb_data, TN_WONT); if (cmd->rem_will || !cmd->sent_do) { send_i(td, TN_DONT, option); cmd->sent_do = 1; } cmd->rem_will = 0; } } else if (cmd_str[1] == TN_DO) { option = cmd_str[2]; cmd = find_cmd(td->cmds, option); if (!cmd) { send_i(td, TN_WONT, option); } else { rv = cmd->i_will; if (cmd->will_do_handler) { rv = cmd->will_do_handler(td->cb_data, TN_DO); cmd->i_will = rv; } if (!rv || !cmd->sent_will) { send_i(td, rv ? TN_WILL : TN_WONT, option); cmd->sent_will = 1; } cmd->rem_do = rv; } } else if (cmd_str[1] == TN_DONT) { option = cmd_str[2]; cmd = find_cmd(td->cmds, option); if (cmd) { if (cmd->will_do_handler) cmd->will_do_handler(td->cb_data, TN_DONT); if (cmd->rem_do || !cmd->sent_will) { send_i(td, TN_WONT, option); cmd->sent_will = 1; } cmd->rem_do = 0; } } } void telnet_send_option(telnet_data_t *td, const unsigned char *option, unsigned int len) { unsigned int real_len; unsigned int i; /* Make sure to account for any duplicate 255s. */ for (real_len = 0, i = 0; i < len; i++, real_len++) { if (option[i] == TN_IAC) real_len++; } real_len += 4; /* Add the initial and end markers. */ if (real_len > gensio_buffer_left(&td->out_telnet_cmd)) { /* Out of data, abort the connection. This really shouldn't happen.*/ td->error = 1; return; } gensio_buffer_outchar(&td->out_telnet_cmd, TN_IAC); gensio_buffer_outchar(&td->out_telnet_cmd, TN_SB); for (i = 0; i < len; i++) { gensio_buffer_outchar(&td->out_telnet_cmd, option[i]); if (option[i] == TN_IAC) gensio_buffer_outchar(&td->out_telnet_cmd, option[i]); } gensio_buffer_outchar(&td->out_telnet_cmd, TN_IAC); gensio_buffer_outchar(&td->out_telnet_cmd, TN_SE); td->output_ready(td->cb_data); } unsigned int process_telnet_data(unsigned char *outdata, unsigned int outlen, unsigned char **r_indata, unsigned int *inlen, telnet_data_t *td) { unsigned int i, j; unsigned char *indata = *r_indata; /* * We use this to process commands one at a time and return. This * is important: after each command the user may want to turn off * the lower-level reader and not accept commands. If you don't * do this, you may process commands that the user is not ready * to process. */ int done = 0; /* If it's a telnet port, get the commands out of the stream. */ for (i = 0, j = 0; !done && i < *inlen && j < outlen; i++) { if (td->telnet_cmd_pos != 0) { unsigned char tn_byte; tn_byte = indata[i]; if ((td->telnet_cmd_pos == 1) && (tn_byte == TN_IAC)) { /* Two IACs in a row causes one IAC to be sent, so just let this one go through. */ outdata[j++] = tn_byte; td->telnet_cmd_pos = 0; continue; } if (td->telnet_cmd_pos == 1) { /* These are two byte commands, so we have everything we need to handle the command. */ td->telnet_cmd[td->telnet_cmd_pos++] = tn_byte; if (tn_byte < TN_SB) { handle_telnet_cmd(td, td->telnet_cmd_pos); td->telnet_cmd_pos = 0; done = 1; } } else if (td->telnet_cmd_pos == 2) { td->telnet_cmd[td->telnet_cmd_pos++] = tn_byte; if (td->telnet_cmd[1] == TN_SE) { /* SE is never valid except after an SE. */ td->telnet_cmd_pos = 0; continue; } if (td->telnet_cmd[1] != TN_SB) { /* It's a will/won't/do/don't */ handle_telnet_cmd(td, td->telnet_cmd_pos); td->telnet_cmd_pos = 0; done = 1; } } else { /* It's in a suboption, look for the end and IACs. */ if (td->suboption_iac) { if (tn_byte == TN_SE) { /* Remove the IAC 240 from the end. */ td->telnet_cmd_pos--; handle_telnet_cmd(td, td->telnet_cmd_pos); td->telnet_cmd_pos = 0; done = 1; } else if (tn_byte == TN_IAC) { /* Don't do anything, a double 255 means we leave on 255 in. */ } else { /* If we have an IAC and an invalid character, delete them both */ td->telnet_cmd_pos--; } td->suboption_iac = 0; } else { if (td->telnet_cmd_pos > MAX_TELNET_CMD_SIZE) /* Always store the last character received in the final postition (the array is one bigger than the max size) so we can detect the end of the suboption. */ td->telnet_cmd_pos = MAX_TELNET_CMD_SIZE; td->telnet_cmd[td->telnet_cmd_pos++] = tn_byte; if (tn_byte == TN_IAC) td->suboption_iac = 1; } } } else if (indata[i] == TN_IAC) { td->telnet_cmd[td->telnet_cmd_pos++] = TN_IAC; td->suboption_iac = 0; } else { outdata[j++] = indata[i]; } } *inlen -= i; *r_indata = indata + i; return j; } unsigned int process_telnet_xmit(unsigned char *outdata, unsigned int outlen, const unsigned char **indata, size_t *r_inlen) { unsigned int i, j = 0; unsigned int inlen = *r_inlen; const unsigned char *ibuf = *indata; /* Double the IACs on a telnet transmit stream. */ for (i = 0; i < inlen; i++) { if (ibuf[i] == TN_IAC) { if (outlen < 2) break; outdata[j++] = TN_IAC; outdata[j++] = TN_IAC; outlen -= 2; } else { if (outlen < 1) break; outdata[j++] = ibuf[i]; outlen--; } } *indata = ibuf + i; *r_inlen = inlen - i; return j; } void telnet_init(telnet_data_t *td, void *cb_data, void (*output_ready)(void *cb_data), void (*cmd_handler)(void *cb_data, unsigned char cmd), struct telnet_cmd *cmds, const unsigned char *init_seq, int init_seq_len) { memset(td, 0, sizeof(*td)); gensio_buffer_init(&td->out_telnet_cmd, td->out_telnet_cmdbuf, sizeof(td->out_telnet_cmdbuf)); td->cb_data = cb_data; td->output_ready = output_ready; td->cmd_handler = cmd_handler; td->cmds = cmds; telnet_cmd_send(td, init_seq, init_seq_len); } void telnet_cleanup(telnet_data_t *td) { td->cmds = NULL; } gensio-3.0.0/lib/seriallock.c0000664000175000017500000001561014666203307011535 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include "seriallock.h" #if USE_UUCP_LOCKING #include #include #include #include #include #include #include #include #include #include #include #ifdef __linux__ #include /* For major() and minor() */ #endif #include #include static char *uucp_lck_dir = UUCP_LOCK_DIR; static char *dev_prefix = "/dev/"; static int uucp_fname_lock(struct gensio_os_funcs *o, const char *devname, char **rname) { size_t dev_prefix_len = strlen(dev_prefix), len, i; char *name; if (strncmp(dev_prefix, devname, dev_prefix_len) == 0) devname += dev_prefix_len; /* * Format is "/var/lock/LCK..". The 7 is for * the "/LCK.." and the final nil char. */ len = 7 + strlen(uucp_lck_dir) + strlen(devname); name = o->zalloc(o, len); if (!name) return GE_NOMEM; snprintf(name, len, "%s/LCK..%s", uucp_lck_dir, devname); for (i = strlen(uucp_lck_dir) + 1; name[i]; i++) { if (name[i] == '/') name[i] = '_'; } *rname = name; return 0; } static int uucp_svr4_lock(struct gensio_os_funcs *o, int fd, char **rname) { struct stat stat; size_t len; unsigned int maj, min; char *name; int err; if (fstat(fd, &stat) == -1) { err = gensio_os_err_to_err(o, errno); assert(err != 0); /* Keep scan-build happy. */ return err; } #if 0 /* Should we do this? */ if (!S_ISCHR(stat.st_mode)) return GE_INCONSISTENT; #endif maj = major(stat.st_rdev); min = minor(stat.st_rdev); if (maj > 999 || min > 999) return GE_INVAL; /* * Format is "/var/lock/LCK.mmm.iii" where mmm is the major number * and iii is the minor number. The 13 is for the "/LCK.mmm.iii" * and the final nil char. */ len = strlen(uucp_lck_dir) + 13; name = o->zalloc(o, len); if (!name) return GE_NOMEM; snprintf(name, len, "%s/LCK.%3.3d.%3.3d", uucp_lck_dir, maj, min); *rname = name; return 0; } static int alloc_lock_names(struct gensio_os_funcs *o, int fd, const char *devname, char **rname1, char **rname2) { char *name1 = NULL, *name2 = NULL; int err; err = uucp_fname_lock(o, devname, &name1); if (!err) err = uucp_svr4_lock(o, fd, &name2); if (err) { if (name1) o->free(o, name1); } else { *rname1 = name1; *rname2 = name2; } return err; } static void uucp_rm_lock(struct gensio_os_funcs *o, int fd, const char *devname) { char *lck_file1, *lck_file2; int err; if (!gensio_uucp_locking_enabled) return; err = alloc_lock_names(o, fd, devname, &lck_file1, &lck_file2); if (err) return; unlink(lck_file1); unlink(lck_file2); o->free(o, lck_file1); o->free(o, lck_file2); } static int write_full(int fd, char *data, size_t count) { ssize_t written; restart: while ((written = write(fd, data, count)) > 0) { data += written; count -= written; } if (written < 0) { if (errno == EAGAIN) goto restart; return -1; } return 0; } static int check_lock_file(const char *lck_file) { int n, fd, pid = 0; union { uint32_t ival; char str[64]; } buf; if ((fd = open(lck_file, O_RDONLY)) >= 0) { n = read(fd, &buf, sizeof(buf) - 1); close(fd); if (n == 4) /* Kermit-style lockfile. */ pid = buf.ival; else if (n > 0) { /* Ascii lockfile. */ buf.str[n] = '\0'; sscanf(buf.str, "%10d", &pid); } if (pid > 0 && kill((pid_t)pid, 0) < 0 && errno == ESRCH) { /* death lockfile - remove it */ unlink(lck_file); pid = 0; } } return pid; } static int uucp_mk_lock(struct gensio_os_funcs *o, struct gensio_ll *ll, int fd, const char *devname) { struct stat stt; int pid = -1, err; if (!gensio_uucp_locking_enabled) return 0; if (stat(uucp_lck_dir, &stt) == 0) { /* is lock file directory present? */ char *lck_file1, *lck_file2; union { uint32_t ival; char str[64]; } buf; int lockfd; err = alloc_lock_names(o, fd, devname, &lck_file1, &lck_file2); if (err) return err; pid = check_lock_file(lck_file1); if (pid == 0) pid = check_lock_file(lck_file2); if (pid == 0) { int mask; mask = umask(022); lockfd = open(lck_file1, O_WRONLY | O_CREAT | O_EXCL, 0666); umask(mask); if (lockfd >= 0) { ssize_t rv; snprintf(buf.str, sizeof(buf), "%10ld\n", (long)getpid()); rv = write_full(lockfd, buf.str, strlen(buf.str)); close(lockfd); if (rv < 0) { pid = -1; unlink(lck_file1); } else { rv = link(lck_file1, lck_file2); if (rv) { gensio_ll_log(ll, GENSIO_LOG_ERR, "Error linking %s to %s: %s", lck_file1, lck_file2, strerror(errno)); } } } else { pid = -1; } } o->free(o, lck_file1); o->free(o, lck_file2); } if (pid < 0) { gensio_ll_log(ll, GENSIO_LOG_ERR, "Error accessing locks in %s: %s", uucp_lck_dir, strerror(errno)); return GE_NOTFOUND; } else if (pid > 0) { gensio_ll_log(ll, GENSIO_LOG_ERR, "Port in use by pid %d", pid); return GE_INUSE; } return 0; } #else static void uucp_rm_lock(struct gensio_os_funcs *o, int fd, const char *devname) { } static int uucp_mk_lock(struct gensio_os_funcs *o, struct gensio_ll *ll, int fd, const char *devname) { return 0; } #endif /* USE_UUCP_LOCKING */ #if USE_FLOCK_LOCKING #include #include #include #include #include static void flock_rm_lock(struct gensio_os_funcs *o, int fd) { flock(fd, LOCK_UN); ioctl(fd, TIOCNXCL); } static int flock_mk_lock(struct gensio_os_funcs *o, int fd) { int rv; rv = flock(fd, LOCK_EX | LOCK_NB); if (rv != 0) { if (errno == EWOULDBLOCK) rv = GE_INUSE; else rv = gensio_os_err_to_err(o, errno); } if (rv == 0) { rv = ioctl(fd, TIOCEXCL); if (rv != 0) rv = gensio_os_err_to_err(o, errno); } return rv; } #else static void flock_rm_lock(struct gensio_os_funcs *o, int fd) { } static int flock_mk_lock(struct gensio_os_funcs *o, int fd) { return 0; } #endif void serial_rm_lock(struct gensio_os_funcs *o, struct gensio_ll *ll, bool do_uucp_lock, bool do_flock, int fd, const char *devname) { if (do_uucp_lock) uucp_rm_lock(o, fd, devname); if (do_flock) flock_rm_lock(o, fd); } int serial_mk_lock(struct gensio_os_funcs *o, struct gensio_ll *ll, bool do_uucp_lock, bool do_flock, int fd, const char *devname) { int err = 0; if (do_uucp_lock) err = uucp_mk_lock(o, ll, fd, devname); if (!err && do_flock) { err = flock_mk_lock(o, fd); if (err) uucp_rm_lock(o, fd, devname); } return err; } gensio-3.0.0/lib/os_win.c0000664000175000017500000034026215007164240010677 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2021 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include /* * It's impossible to include ntstatus.h without getting a ton of warnings, * and these are not defined in winnt.h, so define these here. Add safety * guards just in case. */ #ifndef STATUS_SUCCESS #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) #endif #ifndef STATUS_NOT_FOUND #define STATUS_NOT_FOUND ((NTSTATUS)0xC0000225L) #endif #include #include #include #include #include #include #include #include #include #include #include #include "errtrig.h" #if defined(_MSC_VER) && defined(ENABLE_INTERNAL_TRACE) #include #endif static void win_finish_free(struct gensio_os_funcs *o); static DWORD gensio_time_to_ms(struct gensio_time *time) { if (!time) return INFINITE; if (time->secs > 1000000) return 1000000000; /* Cap time at a million seconds. */ return (time->secs * 1000) + ((time->nsecs + 999999) / 1000000); } static ULONGLONG gensio_time_to_ms64(struct gensio_time *time) { return ((ULONGLONG)time->secs * 1000) + ((time->nsecs + 999999) / 1000000); } static void win_ms64_time_to_gensio(gensio_time *gtime, ULONGLONG ms64) { gtime->secs = ms64 / 1000; gtime->nsecs = (ms64 % 1000) * 1000000; } static void win_calc_timediff(gensio_time *timeout, ULONGLONG entry, ULONGLONG exit, DWORD mtimeout) { ULONGLONG elapsed; elapsed = exit - entry; if (elapsed > mtimeout) { timeout->secs = 0; timeout->nsecs = 0; } else { win_ms64_time_to_gensio(timeout, mtimeout - elapsed); } } struct iostat { BOOL wait; BOOL ready; void (*handler)(struct gensio_iod *iod, void *cb_data); }; struct gensio_iod_win { struct gensio_iod iod; enum gensio_iod_type type; void (*clean)(struct gensio_iod_win *); void (*wake)(struct gensio_iod_win *); void (*check)(struct gensio_iod_win *); void (*shutdown)(struct gensio_iod_win *); /* Optional. */ intptr_t fd; struct gensio_link link; struct gensio_link all_link; /* * Passed in options, see gensio_os_funcs GENSIO_OPEN_OPTION_xxx * for the device portion of this. */ int options; /* * Is the iod in raw mode? This is only set for stdin stdio iods * so they can properly handle ^Z in raw mode. */ BOOL is_raw; BOOL done; BOOL is_stdio; /* See comment in win_iod_socket_init() on this. */ BOOL always_writeable; struct iostat read; struct iostat write; struct iostat except; BOOL closed; LPTHREAD_START_ROUTINE threadfunc; DWORD werr; /* For reporting errors from the sub-thread, windows error. */ int err; /* Current error condition, gensio error */ HANDLE threadh; DWORD threadid; CRITICAL_SECTION lock; unsigned int in_handler_count; BOOL handlers_set; BOOL in_handlers_clear; void (*cleared_handler)(struct gensio_iod *iod, void *cb_data); void *cb_data; void (*set_read_handler)(struct gensio_iod_win *wiod, bool enable); void (*set_write_handler)(struct gensio_iod_win *wiod, bool enable); void (*set_except_handler)(struct gensio_iod_win *wiod, bool enable); void (*clear_fd_handlers)(struct gensio_iod_win *wiod); }; #define iod_to_win(i) gensio_container_of(i, struct gensio_iod_win, iod); enum win_timer_state { WIN_TIMER_STOPPED = 0, WIN_TIMER_IN_HEAP, WIN_TIMER_IN_QUEUE, WIN_TIMER_PENDING /* Timeout is set, waiting for the handler to return. */ }; typedef struct heap_val_s { struct gensio_iod_win wiod; void (*handler)(struct gensio_timer *t, void *cb_data); void *cb_data; void (*done)(struct gensio_timer *t, void *cb_data); void *done_cb_data; ULONGLONG end_time; enum win_timer_state state; /* Have I been freed? */ BOOL freed; /* Am I currently in a handler? */ unsigned int in_handler_count; } heap_val_t; #define wiod_to_timer(w) gensio_container_of(w, struct gensio_timer, val.wiod) static int i_win_close(struct gensio_iod **iodp, bool force); #define heap_s theap_s #define heap_node_s gensio_timer #define HEAP_EXPORT_NAME(s) theap_ ## s #define HEAP_NAMES_LOCAL static #define HEAP_OUTPUT_PRINTF "(%ld.%7.7ld)" #define HEAP_OUTPUT_DATA pos->timeout.tv_sec, pos->timeout.tv_usec static int heap_cmp_key(heap_val_t *t1, heap_val_t *t2) { if (t1->end_time < t2->end_time) return -1; if (t1->end_time > t2->end_time) return 1; return 0; } #include "heap.h" struct gensio_data { /* Used to wake me up when something is in waiting_iods. */ HANDLE waiter; BOOL freed; CRITICAL_SECTION glock; unsigned int refcount; struct gensio_list waiting_iods; struct gensio_list all_iods; CRITICAL_SECTION timer_lock; struct theap_s timer_heap; HANDLE timerth; DWORD timerthid; WSAEVENT timer_wakeev; struct gensio_os_proc_data *proc_data; struct gensio_memtrack *mtrack; int (*orig_recv)(struct gensio_iod *iod, void *buf, gensiods buflen, gensiods *rcount, int gflags); int (*orig_send)(struct gensio_iod *iod, const struct gensio_sg *sg, gensiods sglen, gensiods *rcount, int gflags); int (*orig_sendto)(struct gensio_iod *iod, const struct gensio_sg *sg, gensiods sglen, gensiods *rcount, int gflags, const struct gensio_addr *raddr); int (*orig_recvfrom)(struct gensio_iod *iod, void *buf, gensiods buflen, gensiods *rcount, int flags, struct gensio_addr *addr); int (*orig_accept)(struct gensio_iod *iod, struct gensio_addr **raddr, struct gensio_iod **newiod); int (*orig_connect)(struct gensio_iod *iod, const struct gensio_addr *addr); }; #define glock_lock(d) EnterCriticalSection(&(d)->glock) #define glock_unlock(d) LeaveCriticalSection(&(d)->glock) static void * win_zalloc(struct gensio_os_funcs *o, gensiods size) { struct gensio_data *d = o->user_data; TRACE_MEM; return gensio_i_zalloc(d->mtrack, size, TRACE_MEM_CALLERS, TRACE_MEM_CALLERS_SIZE); } static void win_free(struct gensio_os_funcs *o, void *v) { struct gensio_data *d = o->user_data; TRACE_MEM; gensio_i_free(d->mtrack, v, TRACE_MEM_CALLERS, TRACE_MEM_CALLERS_SIZE); } #if 0 static void print_err(char *name, DWORD val) { char errbuf[128]; strcpy(errbuf, "Unknown error"); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, val, 0, errbuf, sizeof(errbuf), NULL); fprintf(stderr, "%s: %ld - %s\n", name, val, errbuf); fflush(stderr); } #endif static void i_queue_iod(struct gensio_iod_win *wiod) { struct gensio_data *d = wiod->iod.f->user_data; BOOL rvb; if (!gensio_list_link_inlist(&wiod->link)) { gensio_list_add_tail(&d->waiting_iods, &wiod->link); rvb = ReleaseSemaphore(d->waiter, 1, NULL); if (!rvb) /* Too many posts is improbable, but ok. */ assert(GetLastError() == ERROR_TOO_MANY_POSTS); } } static void queue_iod(struct gensio_iod_win *wiod) { struct gensio_data *d = wiod->iod.f->user_data; glock_lock(d); i_queue_iod(wiod); glock_unlock(d); } static DWORD WINAPI timer_thread(LPVOID data) { struct gensio_os_funcs *o = data; struct gensio_data *d = o->user_data; struct gensio_timer *t; ULONGLONG now, delay; DWORD rv; EnterCriticalSection(&d->timer_lock); while (!d->freed) { now = GetTickCount64(); t = theap_get_top(&d->timer_heap); while (t && t->val.end_time <= now) { theap_remove(&d->timer_heap, t); t->val.state = WIN_TIMER_IN_QUEUE; queue_iod(&t->val.wiod); t = theap_get_top(&d->timer_heap); now = GetTickCount64(); } if (t) delay = t->val.end_time - now; else delay = 1000000; LeaveCriticalSection(&d->timer_lock); rv = WSAWaitForMultipleEvents(1, &d->timer_wakeev, FALSE, (DWORD) delay, FALSE); assert(rv != WSA_WAIT_FAILED); EnterCriticalSection(&d->timer_lock); assert(WSAResetEvent(d->timer_wakeev)); } LeaveCriticalSection(&d->timer_lock); return 0; } static int win_alloc_iod(struct gensio_os_funcs *o, unsigned int size, int fd, enum gensio_iod_type type, int options, int (*iod_init)(struct gensio_iod_win *, void *), void *cb_data, struct gensio_iod_win **rwiod) { struct gensio_data *d = o->user_data; struct gensio_iod_win *wiod; int rv = 0; wiod = o->zalloc(o, size); if (!wiod) return GE_NOMEM; InitializeCriticalSection(&wiod->lock); wiod->iod.f = o; wiod->type = type; wiod->fd = fd; wiod->options = options; if (iod_init) { rv = iod_init(wiod, cb_data); if (rv) goto out_err; } if (wiod->threadfunc) { wiod->threadh = CreateThread(NULL, 0, wiod->threadfunc, wiod, 0, &wiod->threadid); if (!wiod->threadh) { rv = gensio_os_err_to_err(o, GetLastError()); goto out_err; } } glock_lock(d); gensio_list_add_tail(&d->all_iods, &wiod->all_link); glock_unlock(d); *rwiod = wiod; return 0; out_err: wiod->done = TRUE; if (wiod->shutdown) { wiod->shutdown(wiod); } else if (wiod->threadh) { wiod->wake(wiod); WaitForSingleObject(wiod->threadh, INFINITE); } if (wiod->clean) wiod->clean(wiod); DeleteCriticalSection(&wiod->lock); o->free(o, wiod); assert(rv != 0); /* Make scan-build happy, but probably a good idea. */ return rv; } struct gensio_lock { struct gensio_os_funcs *o; CRITICAL_SECTION lock; }; static struct gensio_lock *win_alloc_lock(struct gensio_os_funcs *o) { struct gensio_lock *lock; lock = o->zalloc(o, sizeof(*lock)); if (!lock) return NULL; lock->o = o; if (!InitializeCriticalSectionAndSpinCount(&lock->lock, 0)) { o->free(o, lock); return NULL; } return lock; } static void win_free_lock(struct gensio_lock *lock) { DeleteCriticalSection(&lock->lock); lock->o->free(lock->o, lock); } static void win_lock(struct gensio_lock *lock) { EnterCriticalSection(&lock->lock); } static void win_unlock(struct gensio_lock *lock) { LeaveCriticalSection(&lock->lock); } /* Call this at the return of every iod handler. */ static void win_iod_handler_done(struct gensio_iod_win *wiod) { void (*cleared_handler)(struct gensio_iod *iod, void *cb_data) = NULL; void *cb_data; EnterCriticalSection(&wiod->lock); assert(wiod->in_handler_count > 0); wiod->in_handler_count--; if (wiod->in_handlers_clear && wiod->in_handler_count == 0) { cleared_handler = wiod->cleared_handler; cb_data = wiod->cb_data; wiod->handlers_set = FALSE; wiod->read.handler = NULL; wiod->write.handler = NULL; wiod->except.handler = NULL; wiod->cleared_handler = NULL; } LeaveCriticalSection(&wiod->lock); if (cleared_handler) cleared_handler(&wiod->iod, cb_data); } static int win_set_fd_handlers(struct gensio_iod *iod, void *cb_data, void (*read_handler)(struct gensio_iod *iod, void *cb_data), void (*write_handler)(struct gensio_iod *iod, void *cb_data), void (*except_handler)(struct gensio_iod *iod, void *cb_data), void (*cleared_handler)(struct gensio_iod *iod, void *cb_data)) { struct gensio_iod_win *wiod = iod_to_win(iod); int rv = GE_INUSE; EnterCriticalSection(&wiod->lock); if (!wiod->handlers_set) { rv = 0; wiod->handlers_set = TRUE; wiod->read.handler = read_handler; wiod->write.handler = write_handler; wiod->except.handler = except_handler; wiod->cleared_handler = cleared_handler; wiod->cb_data = cb_data; } LeaveCriticalSection(&wiod->lock); return rv; } static void win_clear_fd_handlers(struct gensio_iod *iod) { struct gensio_iod_win *wiod = iod_to_win(iod); EnterCriticalSection(&wiod->lock); if (wiod->handlers_set && !wiod->in_handlers_clear) { wiod->in_handlers_clear = TRUE; if (wiod->clear_fd_handlers) { wiod->clear_fd_handlers(wiod); goto out; } wiod->read.wait = FALSE; wiod->read.ready = FALSE; wiod->write.wait = FALSE; wiod->write.ready = FALSE; wiod->except.wait = FALSE; wiod->except.ready = FALSE; if (wiod->in_handler_count == 0) queue_iod(wiod); } out: LeaveCriticalSection(&wiod->lock); } static void win_clear_fd_handlers_norpt(struct gensio_iod *iod) { struct gensio_iod_win *wiod = iod_to_win(iod); EnterCriticalSection(&wiod->lock); if (wiod->handlers_set && !wiod->in_handlers_clear) { wiod->handlers_set = false; wiod->read.handler = NULL; wiod->write.handler = NULL; wiod->except.handler = NULL; wiod->cleared_handler = NULL; } LeaveCriticalSection(&wiod->lock); } static void win_set_read_handler(struct gensio_iod *iod, bool enable) { struct gensio_iod_win *wiod = iod_to_win(iod); EnterCriticalSection(&wiod->lock); if (wiod->read.wait != enable && !wiod->in_handlers_clear) { wiod->read.wait = enable; if (wiod->set_read_handler) { wiod->set_read_handler(wiod, enable); } else { if (enable) { if (wiod->read.ready) queue_iod(wiod); else wiod->wake(wiod); } } } LeaveCriticalSection(&wiod->lock); } static void win_set_write_handler(struct gensio_iod *iod, bool enable) { struct gensio_iod_win *wiod = iod_to_win(iod); EnterCriticalSection(&wiod->lock); if (wiod->write.wait != enable && !wiod->in_handlers_clear) { wiod->write.wait = enable; if (wiod->set_write_handler) { wiod->set_write_handler(wiod, enable); } else { if (enable) { if (wiod->write.ready) queue_iod(wiod); else wiod->wake(wiod); } } } LeaveCriticalSection(&wiod->lock); } static void win_set_except_handler(struct gensio_iod *iod, bool enable) { struct gensio_iod_win *wiod = iod_to_win(iod); EnterCriticalSection(&wiod->lock); if (wiod->except.wait != enable && !wiod->in_handlers_clear) { wiod->except.wait = enable; if (wiod->set_except_handler) { wiod->set_except_handler(wiod, enable); } else { if (enable) { if (wiod->except.ready) queue_iod(wiod); else wiod->wake(wiod); } } } LeaveCriticalSection(&wiod->lock); } static void win_timer_check(struct gensio_iod_win *wiod) { struct gensio_os_funcs *o = wiod->iod.f; struct gensio_data *d = o->user_data; struct gensio_timer *t = wiod_to_timer(wiod); t->val.in_handler_count++; glock_unlock(d); EnterCriticalSection(&d->timer_lock); if (t->val.state == WIN_TIMER_IN_QUEUE) { t->val.state = WIN_TIMER_STOPPED; LeaveCriticalSection(&d->timer_lock); t->val.handler(t, t->val.cb_data); EnterCriticalSection(&d->timer_lock); } else { assert(t->val.state == WIN_TIMER_STOPPED); } if (t->val.done && !t->val.freed) { void (*done)(struct gensio_timer *t, void *cb_data) = t->val.done; void *cb_data = t->val.done_cb_data; t->val.done = NULL; LeaveCriticalSection(&d->timer_lock); done(t, cb_data); EnterCriticalSection(&d->timer_lock); } if (t->val.freed) { LeaveCriticalSection(&d->timer_lock); o->release_iod(&t->val.wiod.iod); glock_lock(d); return; } if (t->val.state == WIN_TIMER_PENDING) { theap_add(&d->timer_heap, t); assert(WSASetEvent(d->timer_wakeev)); t->val.state = WIN_TIMER_IN_HEAP; } LeaveCriticalSection(&d->timer_lock); glock_lock(d); t->val.in_handler_count--; } static struct gensio_timer * win_alloc_timer(struct gensio_os_funcs *o, void (*handler)(struct gensio_timer *t, void *cb_data), void *cb_data) { struct gensio_timer *t = NULL; struct gensio_iod_win *wiod; int rv; rv = win_alloc_iod(o, sizeof(struct gensio_timer), -1, 0, 0, NULL, NULL, &wiod); if (!rv) { wiod->check = win_timer_check; t = wiod_to_timer(wiod); t->val.handler = handler; t->val.cb_data = cb_data; } return t; } static void win_stop_timer_now(struct gensio_timer *timer) { struct gensio_os_funcs *o = timer->val.wiod.iod.f; struct gensio_data *d = o->user_data; if (timer->val.state == WIN_TIMER_IN_QUEUE) { glock_lock(d); /* * We aren't holding glock_lock until just above, so * it;s possible it was pulled from the list but hasn't * been run. */ if (gensio_list_link_inlist(&timer->val.wiod.link)) gensio_list_rm(&d->waiting_iods, &timer->val.wiod.link); glock_unlock(d); } else if (timer->val.state == WIN_TIMER_IN_HEAP) { theap_remove(&d->timer_heap, timer); } timer->val.state = WIN_TIMER_STOPPED; } static void win_free_timer(struct gensio_timer *timer) { struct gensio_os_funcs *o = timer->val.wiod.iod.f; struct gensio_data *d = o->user_data; EnterCriticalSection(&d->timer_lock); if (!timer->val.freed) { timer->val.freed = TRUE; win_stop_timer_now(timer); if (timer->val.in_handler_count == 0) o->release_iod(&timer->val.wiod.iod); } LeaveCriticalSection(&d->timer_lock); } static int win_add_timer(struct gensio_timer *timer, ULONGLONG end_time) { struct gensio_os_funcs *o = timer->val.wiod.iod.f; struct gensio_data *d = o->user_data; int rv = 0; EnterCriticalSection(&d->timer_lock); if (timer->val.freed) { rv = GE_INVAL; goto out_unlock; } if (timer->val.state != WIN_TIMER_STOPPED || timer->val.done) { rv = GE_INUSE; goto out_unlock; } timer->val.end_time = end_time; if (timer->val.in_handler_count > 0) { /* We'll add it when the handler returns. */ timer->val.state = WIN_TIMER_PENDING; } else { theap_add(&d->timer_heap, timer); assert(WSASetEvent(d->timer_wakeev)); timer->val.state = WIN_TIMER_IN_HEAP; } out_unlock: LeaveCriticalSection(&d->timer_lock); return rv; } static int win_start_timer(struct gensio_timer *timer, gensio_time *timeout) { return win_add_timer(timer, GetTickCount64() + gensio_time_to_ms64(timeout)); } static int win_start_timer_abs(struct gensio_timer *timer, gensio_time *timeout) { return win_add_timer(timer, gensio_time_to_ms64(timeout)); } static int win_stop_timer(struct gensio_timer *timer) { struct gensio_os_funcs *o = timer->val.wiod.iod.f; struct gensio_data *d = o->user_data; int rv = 0; EnterCriticalSection(&d->timer_lock); if (timer->val.freed) { rv = GE_INVAL; goto out_unlock; } if (timer->val.state != WIN_TIMER_STOPPED) win_stop_timer_now(timer); else rv = GE_TIMEDOUT; out_unlock: LeaveCriticalSection(&d->timer_lock); return rv; } static int win_stop_timer_with_done(struct gensio_timer *timer, void (*done_handler)(struct gensio_timer *t, void *cb_data), void *cb_data) { struct gensio_os_funcs *o = timer->val.wiod.iod.f; struct gensio_data *d = o->user_data; int rv = 0; EnterCriticalSection(&d->timer_lock); if (timer->val.freed) { rv = GE_INVAL; goto out_unlock; } switch (timer->val.state) { case WIN_TIMER_STOPPED: if (timer->val.in_handler_count == 0) { rv = GE_TIMEDOUT; goto out_unlock; } if (timer->val.done) { rv = GE_INUSE; goto out_unlock; } break; case WIN_TIMER_IN_HEAP: case WIN_TIMER_IN_QUEUE: win_stop_timer_now(timer); timer->val.state = WIN_TIMER_STOPPED; queue_iod(&timer->val.wiod); break; case WIN_TIMER_PENDING: if (timer->val.done) { rv = GE_INUSE; goto out_unlock; } timer->val.state = WIN_TIMER_STOPPED; break; } timer->val.done = done_handler; timer->val.done_cb_data = cb_data; out_unlock: LeaveCriticalSection(&d->timer_lock); return rv; } struct gensio_runner { struct gensio_iod_win wiod; BOOL running; BOOL freed; BOOL in_handler_count; void (*handler)(struct gensio_runner *r, void *cb_data); void *cb_data; }; #define wiod_to_runner(w) gensio_container_of(w, struct gensio_runner, wiod) static void win_runner_check(struct gensio_iod_win *wiod) { struct gensio_os_funcs *o = wiod->iod.f; struct gensio_data *d = o->user_data; struct gensio_runner *r = wiod_to_runner(wiod); if (r->freed) goto out_free; r->running = FALSE; r->in_handler_count++; glock_unlock(d); r->handler(r, r->cb_data); glock_lock(d); r->in_handler_count--; if (r->freed) { out_free: glock_unlock(d); o->release_iod(&r->wiod.iod); glock_lock(d); } } static struct gensio_runner * win_alloc_runner(struct gensio_os_funcs *o, void (*handler)(struct gensio_runner *r, void *cb_data), void *cb_data) { struct gensio_runner *r = NULL; struct gensio_iod_win *wiod; int rv; rv = win_alloc_iod(o, sizeof(struct gensio_runner), -1, 0, 0, NULL, NULL, &wiod); if (!rv) { wiod->check = win_runner_check; r = wiod_to_runner(wiod); r->handler = handler; r->cb_data = cb_data; } return r; } static void win_free_runner(struct gensio_runner *runner) { struct gensio_os_funcs *o = runner->wiod.iod.f; struct gensio_data *d = o->user_data; glock_lock(d); if (!runner->freed) { runner->freed = TRUE; if (runner->in_handler_count == 0) { if (runner->running) { gensio_list_rm(&d->waiting_iods, &runner->wiod.link); runner->running = FALSE; } glock_unlock(d); o->release_iod(&runner->wiod.iod); return; } /* If in the handler, nothing to do, it will catch it on return. */ } glock_unlock(d); } static int win_run(struct gensio_runner *runner) { struct gensio_os_funcs *o = runner->wiod.iod.f; struct gensio_data *d = o->user_data; int rv = 0; glock_lock(d); if (runner->freed) { rv = GE_INVAL; } else if (runner->running) { rv = GE_INUSE; } else { runner->running = TRUE; i_queue_iod(&runner->wiod); } glock_unlock(d); return rv; } struct gensio_waiter { struct gensio_os_funcs *o; HANDLE wait_sem; CRITICAL_SECTION lock; unsigned int num_waiters; unsigned int count; BOOL in_free; }; static struct gensio_waiter * win_alloc_waiter(struct gensio_os_funcs *o) { struct gensio_waiter *w; w = o->zalloc(o, sizeof(*w)); if (!w) return NULL; w->o = o; w->wait_sem = CreateSemaphoreA(NULL, 0, 1000000, NULL); if (!w->wait_sem) { o->free(o, w); return NULL; } InitializeCriticalSection(&w->lock); return w; } static void win_finish_free_waiter(struct gensio_waiter *waiter) { CloseHandle(waiter->wait_sem); DeleteCriticalSection(&waiter->lock); waiter->o->free(waiter->o, waiter); } static void win_free_waiter(struct gensio_waiter *waiter) { int rv; EnterCriticalSection(&waiter->lock); if (waiter->in_free) goto out_unlock; waiter->in_free = TRUE; if (waiter->num_waiters > 0) { rv = ReleaseSemaphore(waiter, waiter->num_waiters, NULL); assert(rv != 0); goto out_unlock; } LeaveCriticalSection(&waiter->lock); win_finish_free_waiter(waiter); return; out_unlock: LeaveCriticalSection(&waiter->lock); } static void win_check_iods(struct gensio_os_funcs *o) { struct gensio_data *d = o->user_data; glock_lock(d); while (!gensio_list_empty(&d->waiting_iods)) { struct gensio_link *l = gensio_list_first(&d->waiting_iods); struct gensio_iod_win *wiod; wiod = gensio_container_of(l, struct gensio_iod_win, link); gensio_list_rm(&d->waiting_iods, l); wiod->check(wiod); } glock_unlock(d); } static int win_do_wait(struct gensio_waiter *waiter, unsigned int count, gensio_time *timeout, BOOL alerts) { struct gensio_data *d = waiter->o->user_data; int rv = 0, nrh = 0; ULONGLONG entry_time, end_time, now; DWORD rvw, mtimeout; HANDLE h[3]; entry_time = GetTickCount64(); mtimeout = gensio_time_to_ms(timeout); end_time = entry_time + mtimeout; now = entry_time; h[nrh++] = d->waiter; h[nrh++] = waiter->wait_sem; if (d->proc_data) h[nrh++] = gensio_os_proc_win_get_main_handle(d->proc_data); EnterCriticalSection(&waiter->lock); if (waiter->in_free) { LeaveCriticalSection(&waiter->lock); return GE_INVAL; } waiter->num_waiters++; while (count) { while (waiter->count == 0) { if (waiter->in_free) goto waitdone; if (now > end_time) { rv = GE_TIMEDOUT; goto waitdone; } LeaveCriticalSection(&waiter->lock); rvw = WaitForMultipleObjectsEx(nrh, h, FALSE, end_time - now, alerts); assert(rvw != WAIT_FAILED); if (rvw != WAIT_TIMEOUT) win_check_iods(waiter->o); if (d->proc_data) gensio_os_proc_check_handlers(d->proc_data); now = GetTickCount64(); EnterCriticalSection(&waiter->lock); } waiter->count--; count--; } waitdone: waiter->num_waiters--; if (waiter->in_free && waiter->num_waiters == 0) { LeaveCriticalSection(&waiter->lock); win_finish_free_waiter(waiter); } else { LeaveCriticalSection(&waiter->lock); } if (timeout) win_calc_timediff(timeout, entry_time, now, mtimeout); return rv; } static int win_wait(struct gensio_waiter *waiter, unsigned int count, gensio_time *timeout) { return win_do_wait(waiter, count, timeout, FALSE); } static int win_wait_intr(struct gensio_waiter *waiter, unsigned int count, gensio_time *timeout) { return win_do_wait(waiter, count, timeout, TRUE); } static void win_wake(struct gensio_waiter *waiter) { int rv; EnterCriticalSection(&waiter->lock); waiter->count++; LeaveCriticalSection(&waiter->lock); rv = ReleaseSemaphore(waiter->wait_sem, 1, NULL); assert(rv != 0); } static int win_service(struct gensio_os_funcs *o, gensio_time *timeout) { struct gensio_data *d = o->user_data; ULONGLONG entry_time; DWORD mtimeout, rvw; int rv = 0; entry_time = GetTickCount64(); mtimeout = gensio_time_to_ms(timeout); rvw = WaitForSingleObject(d->waiter, mtimeout); assert(rvw != WAIT_FAILED); if (rvw == WAIT_TIMEOUT) rv = GE_TIMEDOUT; else win_check_iods(o); if (timeout) win_calc_timediff(timeout, entry_time, GetTickCount64(), mtimeout); return rv; } static SRWLOCK def_win_os_funcs_lock = SRWLOCK_INIT; static struct gensio_os_funcs *def_win_os_funcs; static struct gensio_os_funcs * win_get_funcs(struct gensio_os_funcs *o) { struct gensio_data *d = o->user_data; glock_lock(d); assert(d->refcount > 0); d->refcount++; glock_unlock(d); return o; } static void win_free_funcs(struct gensio_os_funcs *o) { struct gensio_data *d = o->user_data; AcquireSRWLockExclusive(&def_win_os_funcs_lock); glock_lock(d); assert(d->refcount > 0); if (d->refcount > 1) { d->refcount--; glock_unlock(d); ReleaseSRWLockExclusive(&def_win_os_funcs_lock); return; } glock_unlock(d); if (o == def_win_os_funcs) def_win_os_funcs = NULL; ReleaseSRWLockExclusive(&def_win_os_funcs_lock); if (!d->freed) { d->freed = TRUE; if (gensio_list_empty(&d->all_iods)) { win_finish_free(o); return; } } } static void win_get_monotonic_time(struct gensio_os_funcs *o, gensio_time *time) { win_ms64_time_to_gensio(time, GetTickCount64()); } static int win_handle_fork(struct gensio_os_funcs *o) { /* FIXME */ return GE_NOTSUP; } static int win_wait_intr_sigmask(struct gensio_waiter *waiter, unsigned int count, gensio_time *timeout, struct gensio_os_proc_data *proc_data) { return win_wait_intr(waiter, count, timeout); } static void win_iod_check_handler(struct gensio_iod_win *wiod, struct iostat *stat) { EnterCriticalSection(&wiod->lock); while (stat->wait && stat->handler && (stat->ready || wiod->closed)) { void (*handler)(struct gensio_iod *iod, void *cb_data) = stat->handler; void *cb_data = wiod->cb_data; LeaveCriticalSection(&wiod->lock); handler(&wiod->iod, cb_data); EnterCriticalSection(&wiod->lock); } LeaveCriticalSection(&wiod->lock); } static void win_iod_check(struct gensio_iod_win *wiod) { struct gensio_os_funcs *o = wiod->iod.f; struct gensio_data *d = o->user_data; glock_unlock(d); EnterCriticalSection(&wiod->lock); wiod->in_handler_count++; LeaveCriticalSection(&wiod->lock); win_iod_check_handler(wiod, &wiod->read); win_iod_check_handler(wiod, &wiod->write); win_iod_check_handler(wiod, &wiod->except); win_iod_handler_done(wiod); glock_lock(d); } struct gensio_iod_win_sock { struct gensio_iod_win wiod; WSAEVENT wakeev; WSAEVENT sockev; BOOL connected; void *sockinfo; enum { CL_NOT_CALLED, CL_CALLED, CL_DONE } close_state; }; #define wiod_to_winsock(w) gensio_container_of(w, struct gensio_iod_win_sock,\ wiod) static DWORD WINAPI winsock_func(LPVOID data) { struct gensio_iod_win_sock *swiod = data; struct gensio_iod_win *wiod = &swiod->wiod; WSAEVENT waiters[2]; unsigned int i; DWORD rv; int irv; EnterCriticalSection(&wiod->lock); waiters[0] = swiod->wakeev; waiters[1] = swiod->sockev; for(;;) { WSANETWORKEVENTS revents; long events = 0; BOOL queueit = FALSE; if (!wiod->closed) { events = FD_CLOSE; if (wiod->read.wait && !wiod->read.ready) events |= FD_READ | FD_ACCEPT; if (wiod->write.wait && !wiod->write.ready) events |= FD_WRITE | FD_CONNECT; if (wiod->except.wait && !wiod->except.ready) events |= FD_OOB; } LeaveCriticalSection(&wiod->lock); i = 1; if (events) { /* FIXME - check if events changed? */ irv = WSAEventSelect(wiod->fd, swiod->sockev, events); if (irv == SOCKET_ERROR) { EnterCriticalSection(&wiod->lock); if (!wiod->werr) wiod->werr = WSAGetLastError(); wiod->closed = TRUE; queueit = TRUE; goto do_queue; } i++; } rv = WSAWaitForMultipleEvents(i, waiters, FALSE, INFINITE, FALSE); EnterCriticalSection(&wiod->lock); if (wiod->done) break; if (rv == WSA_WAIT_FAILED) { wiod->closed = TRUE; queueit = TRUE; } else if (rv == WSA_WAIT_EVENT_0) { WSAResetEvent(swiod->wakeev); } else if (rv == WSA_WAIT_EVENT_0 + 1) { irv = WSAEnumNetworkEvents(wiod->fd, swiod->sockev, &revents); if (irv == SOCKET_ERROR) { if (!wiod->werr) wiod->werr = WSAGetLastError(); wiod->closed = TRUE; queueit = TRUE; } else { if (revents.lNetworkEvents & (FD_READ | FD_ACCEPT)) { wiod->read.ready = TRUE; if (wiod->read.wait) queueit = TRUE; } if (revents.lNetworkEvents & (FD_WRITE | FD_CONNECT)) { wiod->write.ready = TRUE; if (wiod->write.wait) queueit = TRUE; } if (revents.lNetworkEvents & FD_OOB) { wiod->except.ready = TRUE; if (wiod->except.wait) queueit = TRUE; } if (revents.lNetworkEvents & FD_CLOSE) { wiod->closed = TRUE; queueit = TRUE; } } } do_queue: if (queueit) queue_iod(wiod); } LeaveCriticalSection(&wiod->lock); return 0; } static void win_iod_socket_wake(struct gensio_iod_win *wiod) { struct gensio_iod_win_sock *swiod = wiod_to_winsock(wiod); assert(WSASetEvent(swiod->wakeev)); } static void win_iod_socket_clean(struct gensio_iod_win *wiod) { struct gensio_iod_win_sock *swiod = wiod_to_winsock(wiod); if (swiod->sockev != WSA_INVALID_EVENT) WSACloseEvent(swiod->sockev); if (swiod->wakeev != WSA_INVALID_EVENT) WSACloseEvent(swiod->wakeev); if (wiod->fd != -1) { shutdown(wiod->fd, SD_BOTH); closesocket(wiod->fd); } } static int win_iod_socket_init(struct gensio_iod_win *wiod, void *cb_data) { struct gensio_iod_win_sock *swiod = wiod_to_winsock(wiod); int rv; DWORD socktype = 0; int socklen = sizeof(socktype); rv = getsockopt(wiod->fd, SOL_SOCKET, SO_TYPE, (char *) &socktype, &socklen); if (rv) return gensio_os_err_to_err(wiod->iod.f, rv); /* * It seems that UDP sockets on Windows won't report that the * socket is writable more than once, and maybe even not at all. * I didn't spend much time on it, but I verified that it was * waiting for write ready on the socket in the socket thread and * it never got it, even though it should always be writable. * Since it's always writable, though, just always allow writing. */ if (socktype == SOCK_DGRAM) { wiod->always_writeable = TRUE; wiod->write.ready = TRUE; } swiod->wakeev = WSA_INVALID_EVENT; swiod->sockev = WSA_INVALID_EVENT; swiod->wakeev = WSACreateEvent(); if (swiod->wakeev == WSA_INVALID_EVENT) goto out_err; swiod->sockev = WSACreateEvent(); if (swiod->sockev == WSA_INVALID_EVENT) goto out_err; wiod->threadfunc = winsock_func; wiod->clean = win_iod_socket_clean; wiod->wake = win_iod_socket_wake; wiod->check = win_iod_check; return 0; out_err: win_iod_socket_clean(wiod); return GE_NOMEM; } /* Used to pass data into the intitialization routines. */ struct win_init_info { HANDLE ioh; HANDLE processh; const char *name; }; struct gensio_iod_win_file { struct gensio_iod_win wiod; HANDLE ioh; BOOL readable; BOOL writeable; }; #define wiod_to_winfile(w) gensio_container_of(w, struct gensio_iod_win_file,\ wiod) static void win_dummy_wake(struct gensio_iod_win *wiod) { } static int win_iod_file_init(struct gensio_iod_win *wiod, void *cb_data) { struct gensio_iod_win_file *fwiod = wiod_to_winfile(wiod); if (cb_data) { fwiod->readable = *((BOOL *) cb_data); fwiod->writeable = !fwiod->readable; } else { fwiod->readable = TRUE; fwiod->writeable = TRUE; } fwiod->ioh = (HANDLE) wiod->fd; wiod->read.ready = fwiod->readable; wiod->write.ready = fwiod->writeable; wiod->check = win_iod_check; wiod->wake = win_dummy_wake; return 0; } static int win_file_write(struct gensio_iod_win *wiod, const struct gensio_sg *sg, gensiods sglen, gensiods *rcount) { struct gensio_iod_win_file *fwiod = wiod_to_winfile(wiod); gensiods i, count = 0; DWORD len; if (!fwiod->writeable) return GE_NOTSUP; for (i = 0; i < sglen; i++) { if (!WriteFile(fwiod->ioh, sg[i].buf, sg[i].buflen, &len, FALSE)) { if (count > 0) goto out; return gensio_os_err_to_err(wiod->iod.f, GetLastError()); } count += len; } out: *rcount = count; return 0; } static int win_file_read(struct gensio_iod_win *wiod, void *ibuf, gensiods buflen, gensiods *rcount) { struct gensio_iod_win_file *fwiod = wiod_to_winfile(wiod); DWORD len; if (!ReadFile(fwiod->ioh, ibuf, buflen, &len, FALSE)) return gensio_os_err_to_err(wiod->iod.f, GetLastError()); if (len == 0) return GE_REMCLOSE; *rcount = len; return 0; } /* * Windows stdio/pipe (unidirectional) handling * * Just about everything about Windows stdio sucks. I mean, there's * the whole "newline" situation. And ^Z for EOF? * * But for this library, the main problem with is is that there is no * feasible way to set the I/O handles non-blocking. So we have to * work around it. The same is true for anonymous pipes. A major * oversight in the design of Windows. * * The basic structure is to create a separate threads to do the I/O * with it's own buffer. The input thread normally sits waiting for * read data and putting that data into the buffer. If the buffer is * full it sits waiting on an event. The read code will send the * event when it gets some data from the buffer. * * The write code is similar. It normally sits waiting on an event. * When the write code puts some data into the buffer it sends an * event to the thread, which wakes up and writes the data until the * buffer is empty. * * The big problem is closing. There is no reliable way to wake the * thread if it is blocked on an I/O operation. You can use * CancelSynchronousIo(), but there is a race between releasing the * lock and the read/write being done where the cancel won't work. * The solution is ugly, the code sends CancelSynchronousIo() to the * thread until the thread terminates, which kind of violates the * non-blocking, but there's no way around it. * * Flushing output data is a bit of a problem. As there is no * reliable way to wake a thread that is blocked on I/O, it sets a * flag and wakes the stdout thread (except that is racy, of course, * but we hope for the best). The write operation will not allow data * to be written until the flush is completed by the thread. */ struct gensio_iod_win_oneway { struct gensio_iod_win wiod; HANDLE wakeh; HANDLE ioh; struct gensio_circbuf *buf; BOOL is_console; BOOL readable; BOOL do_flush; /* Tell out to flush it's data. */ }; #define wiod_to_win_oneway(w) gensio_container_of(w, \ struct gensio_iod_win_oneway, \ wiod) static void check_winsize(struct gensio_iod_win_oneway *owiod); static DWORD WINAPI win_oneway_in_thread(LPVOID data) { struct gensio_iod_win_oneway *owiod = data; struct gensio_iod_win *wiod = &owiod->wiod; HANDLE waiters[2] = { owiod->ioh, owiod->wakeh }; DWORD rvw; /* * This is a hack to avoid an issue with Windows raw setting. If * we let a read happen before setting the console to raw, the * console won't go into raw mode until after enter is pressed. * So don't start reading input until the user has enabled read to * allow them time to set the input as raw. */ goto start_loop; /* The below is not necessary, it's just dead code. */ /* EnterCriticalSection(&wiod->lock); */ for(;;) { BOOL rvb; if (gensio_circbuf_room_left(owiod->buf) && !wiod->werr) { gensiods readsize; void *readpos; DWORD nread; gensio_circbuf_next_write_area(owiod->buf, &readpos, &readsize); if (owiod->is_console) { LeaveCriticalSection(&wiod->lock); while (true) { rvw = WaitForMultipleObjects(2, waiters, FALSE, INFINITE); EnterCriticalSection(&wiod->lock); if (wiod->done) goto continue_loop; if (rvw == WAIT_FAILED) goto out_err; if (rvw == WAIT_OBJECT_0 + 1) { /* Maybe we were woken to handle the first winsize. */ check_winsize(owiod); } if (rvw == WAIT_OBJECT_0) { INPUT_RECORD r; LeaveCriticalSection(&wiod->lock); rvb = PeekConsoleInput(owiod->ioh, &r, 1, &nread); EnterCriticalSection(&wiod->lock); if (!rvb) goto out_err; if (r.EventType == WINDOW_BUFFER_SIZE_EVENT) { ReadConsoleInput(owiod->ioh, &r, 1, &nread); check_winsize(owiod); } else { goto leave_peek_loop; } } LeaveCriticalSection(&wiod->lock); } /* No need, can't be reached. */ /* EnterCriticalSection(&wiod->lock); */ } leave_peek_loop: if (wiod->done) goto continue_loop; LeaveCriticalSection(&wiod->lock); rvb = ReadFile(owiod->ioh, readpos, readsize, &nread, NULL); EnterCriticalSection(&wiod->lock); if (wiod->done) goto continue_loop; if (!rvb) { if (GetLastError() == ERROR_OPERATION_ABORTED) /* * We got a CancelSynchronousIo(). We are * probably being shut down, but don't handle it * as an error. */ goto continue_loop; goto out_err; } /* * We handle this here because sometimes the event is * already eaten in ReadFile and we don't see it * above where we check. */ if (owiod->is_console) check_winsize(owiod); if (nread == 0) { /* EOF (^Z) from windows. */ if (wiod->is_raw) { *((char *) readpos) = 0x1a; /* Insert the ^Z */ nread = 1; goto insert_data; } rvw = ERROR_BROKEN_PIPE; goto out_err_noconv; } else { insert_data: gensio_circbuf_data_added(owiod->buf, nread); if (!wiod->read.ready) { wiod->read.ready = TRUE; queue_iod(wiod); } } } else { LeaveCriticalSection(&wiod->lock); start_loop: rvw = WaitForSingleObject(owiod->wakeh, INFINITE); EnterCriticalSection(&wiod->lock); assert(ResetEvent(owiod->wakeh)); if (rvw == WAIT_FAILED) goto out_err; if (!wiod->done) /* Maybe we were woken to handle the first winsize. */ check_winsize(owiod); } continue_loop: if (wiod->done) break; } LeaveCriticalSection(&wiod->lock); return 0; out_err: rvw = GetLastError(); out_err_noconv: if (!wiod->werr) { wiod->read.ready = TRUE; wiod->werr = rvw; queue_iod(wiod); } LeaveCriticalSection(&wiod->lock); return 0; } static DWORD WINAPI win_oneway_out_thread(LPVOID data) { struct gensio_iod_win_oneway *owiod = data; struct gensio_iod_win *wiod = &owiod->wiod; DWORD rvw; EnterCriticalSection(&wiod->lock); for(;;) { BOOL rvb; if (gensio_circbuf_datalen(owiod->buf) > 0) { gensiods writelen; void *writepos; DWORD nwrite; gensio_circbuf_next_read_area(owiod->buf, &writepos, &writelen); LeaveCriticalSection(&wiod->lock); rvb = WriteFile(owiod->ioh, writepos, writelen, &nwrite, NULL); EnterCriticalSection(&wiod->lock); if (!rvb) { if (GetLastError() == ERROR_OPERATION_ABORTED) /* * We got a CancelSynchronousIo(). We are * probably being shut down, but don't handle it * as an error. */ goto continue_loop; goto out_err; } if (!owiod->do_flush) { gensio_circbuf_data_removed(owiod->buf, nwrite); if (!wiod->write.ready && !wiod->in_handlers_clear) { wiod->write.ready = TRUE; queue_iod(wiod); } } } else { LeaveCriticalSection(&wiod->lock); rvw = WaitForSingleObject(owiod->wakeh, INFINITE); EnterCriticalSection(&wiod->lock); assert(ResetEvent(owiod->wakeh)); if (rvw == WAIT_FAILED) goto out_err; } continue_loop: if (wiod->done) break; if (owiod->do_flush) { gensio_circbuf_reset(owiod->buf); owiod->do_flush = FALSE; } } LeaveCriticalSection(&wiod->lock); return 0; out_err: rvw = GetLastError(); if (!wiod->werr) { wiod->write.ready = TRUE; wiod->werr = rvw; queue_iod(wiod); } LeaveCriticalSection(&wiod->lock); return 0; } static int win_oneway_bufcount(struct gensio_iod_win *wiod, int whichbuf, gensiods *count) { struct gensio_iod_win_oneway *owiod = wiod_to_win_oneway(wiod); EnterCriticalSection(&wiod->lock); if (wiod->err || wiod->werr) *count = 0; else if ((wiod->fd == 0 && whichbuf == GENSIO_IN_BUF) || (wiod->fd == 1 && whichbuf == GENSIO_OUT_BUF)) *count = gensio_circbuf_datalen(owiod->buf); else *count = 0; LeaveCriticalSection(&wiod->lock); return 0; } static int win_oneway_close(struct gensio_iod_win *wiod, bool force) { int rv = 0; gensiods count; EnterCriticalSection(&wiod->lock); if (!force) { rv = win_oneway_bufcount(wiod, GENSIO_OUT_BUF, &count); if (!rv && count > 0) { rv = GE_INPROGRESS; goto out; } } wiod->closed = TRUE; if (!wiod->err) wiod->err = GE_LOCALCLOSED; out: LeaveCriticalSection(&wiod->lock); return rv; } static void win_iod_oneway_shutdown(struct gensio_iod_win *wiod) { struct gensio_iod_win_oneway *owiod = wiod_to_win_oneway(wiod); /* This sucks, see notes at beginning of oneway section. */ assert(SetEvent(owiod->wakeh)); CancelSynchronousIo(wiod->threadh); while (WaitForSingleObject(wiod->threadh, 1) == WAIT_TIMEOUT) { assert(SetEvent(owiod->wakeh)); CancelSynchronousIo(wiod->threadh); } wiod->threadh = NULL; if (owiod->ioh) { CloseHandle(owiod->ioh); owiod->ioh = NULL; } } static void win_oneway_flush(struct gensio_iod_win *wiod) { struct gensio_iod_win_oneway *owiod = wiod_to_win_oneway(wiod); if (owiod->readable) /* output only */ return; EnterCriticalSection(&wiod->lock); if (!wiod->err && !wiod->werr) { owiod->do_flush = TRUE; assert(SetEvent(owiod->wakeh)); CancelSynchronousIo(wiod->threadh); } LeaveCriticalSection(&wiod->lock); } static int win_oneway_write(struct gensio_iod_win *wiod, const struct gensio_sg *sg, gensiods sglen, gensiods *rcount) { struct gensio_iod_win_oneway *owiod = wiod_to_win_oneway(wiod); gensiods count = 0; int rv = 0; EnterCriticalSection(&wiod->lock); if (owiod->readable) { rv = GE_NOTSUP; goto out_err; } if (wiod->err || wiod->werr) { if (!wiod->err) wiod->err = gensio_os_err_to_err(wiod->iod.f, wiod->werr); rv = wiod->err; goto out_err; } if (owiod->do_flush) goto out; gensio_circbuf_sg_write(owiod->buf, sg, sglen, &count); wiod->write.ready = (gensio_circbuf_room_left(owiod->buf) > 0 || wiod->err || wiod->werr); if (count) assert(SetEvent(owiod->wakeh)); out: if (rcount) *rcount = count; out_err: LeaveCriticalSection(&wiod->lock); return rv; } static int win_oneway_read(struct gensio_iod_win *wiod, void *ibuf, gensiods buflen, gensiods *rcount) { struct gensio_iod_win_oneway *owiod = wiod_to_win_oneway(wiod); gensiods count = 0; BOOL was_full; int rv = 0; EnterCriticalSection(&wiod->lock); if (!owiod->readable) { rv = GE_NOTSUP; goto out_err; } if (gensio_circbuf_datalen(owiod->buf) == 0 && (wiod->err || wiod->werr)) { if (!wiod->err) wiod->err = gensio_os_err_to_err(wiod->iod.f, wiod->werr); rv = wiod->err; goto out_err; } was_full = gensio_circbuf_room_left(owiod->buf) == 0; gensio_circbuf_read(owiod->buf, ibuf, buflen, &count); wiod->read.ready = (gensio_circbuf_datalen(owiod->buf) > 0 || wiod->err || wiod->werr); if (was_full && count) assert(SetEvent(owiod->wakeh)); if (rcount) *rcount = count; out_err: LeaveCriticalSection(&wiod->lock); return rv; } static void win_iod_oneway_wake(struct gensio_iod_win *wiod) { struct gensio_iod_win_oneway *owiod = wiod_to_win_oneway(wiod); assert(SetEvent(owiod->wakeh)); } static void win_iod_oneway_clean(struct gensio_iod_win *wiod) { struct gensio_iod_win_oneway *owiod = wiod_to_win_oneway(wiod); if (owiod->ioh) { CloseHandle(owiod->ioh); owiod->ioh = NULL; } if (owiod->wakeh) { CloseHandle(owiod->wakeh); owiod->wakeh = NULL; } if (owiod->buf) { gensio_circbuf_free(owiod->buf); owiod->buf = NULL; } } static int win_iod_oneway_init(struct gensio_iod_win *wiod, void *cb_data) { struct gensio_iod_win_oneway *owiod = wiod_to_win_oneway(wiod); struct gensio_os_funcs* o = wiod->iod.f; owiod->buf = gensio_circbuf_alloc(o, 2048); if (!owiod->buf) return GE_NOMEM; owiod->wakeh = CreateEventA(NULL, FALSE, FALSE, NULL); if (!owiod->wakeh) { gensio_circbuf_free(owiod->buf); owiod->buf = NULL; return GE_NOMEM; } if (owiod->readable) { wiod->threadfunc = win_oneway_in_thread; } else { wiod->threadfunc = win_oneway_out_thread; wiod->write.ready = TRUE; } wiod->clean = win_iod_oneway_clean; wiod->wake = win_iod_oneway_wake; wiod->check = win_iod_check; wiod->shutdown = win_iod_oneway_shutdown; return 0; } struct gensio_iod_win_console { struct gensio_iod_win_oneway owiod; struct stdio_mode *mode; }; #define owiod_to_winconsole(ow) gensio_container_of(ow, \ struct gensio_iod_win_console, \ owiod) static int win_console_makeraw(struct gensio_iod_win *wiod) { struct gensio_iod_win_oneway *owiod = wiod_to_win_oneway(wiod); struct gensio_iod_win_console *cowiod = owiod_to_winconsole(owiod); int rv; if (owiod->readable) { rv = gensio_win_stdin_makeraw(wiod->iod.f, owiod->ioh, &cowiod->mode); if (!rv) wiod->is_raw = TRUE; } else { rv = gensio_win_stdout_makeraw(wiod->iod.f, owiod->ioh, &cowiod->mode); if (!rv) wiod->is_raw = TRUE; } return rv; } static int win_console_close(struct gensio_iod_win *wiod, bool force) { struct gensio_iod_win_oneway *owiod = wiod_to_win_oneway(wiod); struct gensio_iod_win_console *cowiod = owiod_to_winconsole(owiod); gensio_win_stdio_cleanup(wiod->iod.f, owiod->ioh, &cowiod->mode); return win_oneway_close(wiod, force); } static int win_iod_console2_init(struct gensio_iod_win *wiod, void *cb_data) { struct gensio_iod_win_oneway *owiod = wiod_to_win_oneway(wiod); BOOL readable = *((BOOL *) cb_data); owiod->readable = readable; owiod->ioh = (HANDLE) wiod->fd; owiod->is_console = true; return win_iod_oneway_init(wiod, NULL); } static int win_iod_console_init(struct gensio_iod_win *wiod, void *cb_data) { HANDLE h; BOOL readable; int rv; if (wiod->fd > 1 || wiod->fd < 0) return GE_INVAL; if (wiod->fd == 0) { /* stdin */ h = CreateFileA("CONIN$", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); readable = TRUE; } else { h = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); readable = FALSE; } if (h == INVALID_HANDLE_VALUE) return gensio_os_err_to_err(wiod->iod.f, GetLastError()); wiod->fd = (intptr_t) h; rv = win_iod_console2_init(wiod, &readable); if (rv) CloseHandle(h); return rv; } struct gensio_iod_win_pipe { struct gensio_iod_win_oneway owiod; }; #define owiod_to_winpipe(ow) gensio_container_of(ow, \ struct gensio_iod_win_pipe,\ owiod) static int win_iod_read_pipe_init(struct gensio_iod_win *wiod, void *cb_data) { struct gensio_iod_win_oneway *owiod = wiod_to_win_oneway(wiod); owiod->readable = TRUE; return win_iod_oneway_init(wiod, cb_data); } static int win_iod_write_pipe_init(struct gensio_iod_win *wiod, void *cb_data) { struct gensio_iod_win_oneway *owiod = wiod_to_win_oneway(wiod); owiod->readable = FALSE; return win_iod_oneway_init(wiod, cb_data); } static int win_iod_pipe_init(struct gensio_iod_win *wiod, void *cb_data) { struct gensio_iod_win_oneway *owiod = wiod_to_win_oneway(wiod); DWORD pflags; BOOL readable; owiod->ioh = (HANDLE) wiod->fd; if (cb_data) { readable = *((BOOL *) cb_data); } else { if (!GetNamedPipeInfo(owiod->ioh, &pflags, NULL, NULL, NULL)) return gensio_os_err_to_err(wiod->iod.f, GetLastError()); readable = pflags & PIPE_SERVER_END; } if (readable) return win_iod_read_pipe_init(wiod, cb_data); else return win_iod_write_pipe_init(wiod, cb_data); } /* * bidirectional I/O handle */ struct gensio_iod_win_twoway { struct gensio_iod_win wiod; HANDLE wakeh; HANDLE ioh; /* * An optional extra handle that will be added to the object wait. * If it is set, call extrah_func. */ HANDLE extrah; DWORD (*extrah_func)(struct gensio_iod_win_twoway *); BOOL readable; BOOL writeable; struct gensio_circbuf *inbuf; struct gensio_circbuf *flagbuf; struct gensio_circbuf *outbuf; BOOL do_flush; /* Tell thread to flush output data. */ }; #define wiod_to_win_twoway(w) gensio_container_of(w, \ struct gensio_iod_win_twoway, \ wiod) struct gensio_iod_win_dev { struct gensio_iod_win_twoway twiod; char *name; BOOL is_serial_port; /* * Events we are looking for. This may either be 0, or it may * have both EV_ERR and EV_BREAK. No other options, if more * granularity is needed the logic needs to be reworked. */ DWORD comm_mask; struct gensio_win_commport *cominfo; }; #define twiod_to_windev(tw) gensio_container_of(tw, \ struct gensio_iod_win_dev, \ twiod) static DWORD WINAPI win_twoway_thread(LPVOID data) { struct gensio_iod_win_twoway *twiod = data; struct gensio_iod_win_dev *dtwiod = twiod_to_windev(twiod); struct gensio_iod_win *wiod = &twiod->wiod; DWORD rvw, nwait; BOOL reading = FALSE, writing = FALSE, got_event = FALSE; OVERLAPPED reado, writeo, evento; DWORD event = 0; HANDLE waiters[5]; DWORD comm_mask = 0; memset(&reado, 0, sizeof(reado)); memset(&writeo, 0, sizeof(writeo)); memset(&evento, 0, sizeof(evento)); EnterCriticalSection(&wiod->lock); reado.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL); if (!reado.hEvent) goto out_err; writeo.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL); if (!writeo.hEvent) goto out_err; evento.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL); if (!evento.hEvent) goto out_err; waiters[0] = twiod->wakeh; waiters[1] = reado.hEvent; waiters[2] = writeo.hEvent; waiters[3] = evento.hEvent; nwait = 4; if (twiod->extrah) waiters[nwait++] = twiod->extrah; for(;;) { BOOL rvb; if (got_event && twiod->inbuf && gensio_circbuf_room_left(twiod->inbuf) && !wiod->werr && dtwiod->is_serial_port) { gensiods readsize; void *readpos; gensiods flagsize; void *flagpos; gensio_circbuf_next_write_area(twiod->inbuf, &readpos, &readsize); gensio_circbuf_next_write_area(twiod->flagbuf, &flagpos, &flagsize); assert(readsize == flagsize); assert(readsize > 0); *((unsigned char *) readpos) = 0; *((unsigned char *) flagpos) = 0; if (event & EV_BREAK) *((unsigned char *) flagpos) |= GENSIO_IOD_READ_FLAGS_BREAK; if (event & EV_ERR) *((unsigned char *) flagpos) |= GENSIO_IOD_READ_FLAGS_ERR; gensio_circbuf_data_added(twiod->inbuf, 1); gensio_circbuf_data_added(twiod->flagbuf, 1); got_event = false; event = 0; if (comm_mask) { if (!WaitCommEvent(twiod->ioh, &event, &evento)) { rvw = GetLastError(); if (rvw != ERROR_IO_PENDING) goto out_err; } } } else if (!reading && twiod->inbuf && gensio_circbuf_room_left(twiod->inbuf) && !wiod->werr && twiod->readable) { gensiods readsize; void *readpos; gensio_circbuf_next_write_area(twiod->inbuf, &readpos, &readsize); reading = TRUE; LeaveCriticalSection(&wiod->lock); rvb = ReadFile(twiod->ioh, readpos, readsize, NULL, &reado); EnterCriticalSection(&wiod->lock); if (!rvb) { rvw = GetLastError(); if (rvw != ERROR_IO_PENDING) goto out_err_noget; } } else if (!writing && twiod->outbuf && gensio_circbuf_datalen(twiod->outbuf) > 0 && !wiod->werr && twiod->writeable) { gensiods writelen; void *writepos; gensio_circbuf_next_read_area(twiod->outbuf, &writepos, &writelen); writing = TRUE; LeaveCriticalSection(&wiod->lock); rvb = WriteFile(twiod->ioh, writepos, writelen, NULL, &writeo); EnterCriticalSection(&wiod->lock); if (!rvb) { rvw = GetLastError(); if (rvw != ERROR_IO_PENDING) goto out_err_noget; } } else { LeaveCriticalSection(&wiod->lock); rvw = WaitForMultipleObjects(nwait, waiters, FALSE, INFINITE); EnterCriticalSection(&wiod->lock); if (rvw == WAIT_FAILED) goto out_err; if (rvw == WAIT_OBJECT_0 + 0) { assert(ResetEvent(twiod->wakeh)); if (comm_mask != dtwiod->comm_mask) { comm_mask = dtwiod->comm_mask; if (!comm_mask && !got_event) CancelIoEx(twiod->ioh, &evento); if (!SetCommMask(twiod->ioh, comm_mask)) goto out_err; if (comm_mask && !got_event) { if (!WaitCommEvent(twiod->ioh, &event, &evento)) { rvw = GetLastError(); if (rvw != ERROR_IO_PENDING) goto out_err; } } } } else if (rvw == WAIT_OBJECT_0 + 1) { DWORD nread = 0; /* Read event. */ if (!GetOverlappedResult(twiod->ioh, &reado, &nread, FALSE)) goto out_err; if (nread > 0) { gensiods flagsize; void *flagpos; gensio_circbuf_next_write_area(twiod->flagbuf, &flagpos, &flagsize); assert(flagsize >= nread); memset(flagpos, 0, nread); gensio_circbuf_data_added(twiod->inbuf, nread); gensio_circbuf_data_added(twiod->flagbuf, nread); if (!wiod->read.ready) { wiod->read.ready = TRUE; queue_iod(wiod); } } reading = FALSE; } else if (rvw == WAIT_OBJECT_0 + 2 || rvw == ERROR_OPERATION_ABORTED) { DWORD nwrite = 0; /* Write event. */ if (!GetOverlappedResult(twiod->ioh, &writeo, &nwrite, FALSE)) goto out_err; if (twiod->do_flush || nwrite > 0) { if (twiod->do_flush) { gensio_circbuf_reset(twiod->outbuf); twiod->do_flush = FALSE; } else { gensio_circbuf_data_removed(twiod->outbuf, nwrite); } if (!wiod->write.ready && !wiod->in_handlers_clear) { wiod->write.ready = TRUE; queue_iod(wiod); } } writing = FALSE; } else if (rvw == WAIT_OBJECT_0 + 3) { /* CommEvent event */ got_event = true; } else if (rvw == WAIT_OBJECT_0 + 4) { rvw = twiod->extrah_func(twiod); if (rvw) goto out_err_noget; } } if (wiod->done) break; if (twiod->do_flush) { if (writing) { CancelIoEx(twiod->ioh, &writeo); } else { gensio_circbuf_reset(twiod->outbuf); twiod->do_flush = FALSE; } } } exitth: if (reading) CancelIoEx(twiod->ioh, &reado); if (writing) CancelIoEx(twiod->ioh, &writeo); if (!got_event && comm_mask) CancelIoEx(twiod->ioh, &evento); if (reado.hEvent) CloseHandle(reado.hEvent); if (writeo.hEvent) CloseHandle(writeo.hEvent); if (evento.hEvent) CloseHandle(evento.hEvent); if (!twiod->readable) wiod->read.ready = TRUE; if (!twiod->writeable) wiod->write.ready = TRUE; queue_iod(wiod); LeaveCriticalSection(&wiod->lock); return 0; out_err: rvw = GetLastError(); out_err_noget: if (!wiod->werr) { wiod->read.ready = TRUE; wiod->write.ready = TRUE; wiod->werr = rvw; queue_iod(wiod); } goto exitth; } /* Must be called with wiod lock held. */ static int win_twoway_close(struct gensio_iod_win *wiod) { wiod->closed = TRUE; if (!wiod->err) wiod->err = GE_LOCALCLOSED; return 0; } static int win_twoway_bufcount(struct gensio_iod_win *wiod, int whichbuf, gensiods *count) { struct gensio_iod_win_twoway *twiod = wiod_to_win_twoway(wiod); EnterCriticalSection(&wiod->lock); if (wiod->err || wiod->werr) *count = 0; else if (twiod->readable && whichbuf == GENSIO_IN_BUF) *count = gensio_circbuf_datalen(twiod->inbuf); else if (twiod->writeable && whichbuf == GENSIO_OUT_BUF) *count = gensio_circbuf_datalen(twiod->outbuf); else *count = 0; LeaveCriticalSection(&wiod->lock); return 0; } static void win_twoway_flush(struct gensio_iod_win *wiod) { struct gensio_iod_win_twoway *twiod = wiod_to_win_twoway(wiod); if (wiod->fd != 1) /* stdout only */ return; EnterCriticalSection(&wiod->lock); if (!wiod->err && !wiod->werr) { twiod->do_flush = TRUE; assert(SetEvent(twiod->wakeh)); } LeaveCriticalSection(&wiod->lock); } static int win_twoway_write(struct gensio_iod_win *wiod, const struct gensio_sg *sg, gensiods sglen, gensiods *rcount) { struct gensio_iod_win_twoway *twiod = wiod_to_win_twoway(wiod); gensiods count = 0; int rv = 0; EnterCriticalSection(&wiod->lock); if (!twiod->writeable) { rv = GE_NOTSUP; goto out; } if (wiod->err || wiod->werr) { if (!wiod->err) wiod->err = gensio_os_err_to_err(wiod->iod.f, wiod->werr); rv = wiod->err; goto out; } if (twiod->do_flush) goto out; gensio_circbuf_sg_write(twiod->outbuf, sg, sglen, &count); wiod->write.ready = (gensio_circbuf_room_left(twiod->outbuf) > 0 || wiod->err || wiod->werr); if (!wiod->write.ready) wiod->wake(wiod); if (count) assert(SetEvent(twiod->wakeh)); out: LeaveCriticalSection(&wiod->lock); if (!rv && rcount) *rcount = count; return rv; } static int win_twoway_read(struct gensio_iod_win *wiod, unsigned char *ibuf, unsigned char *flags, gensiods buflen, gensiods *rcount) { struct gensio_iod_win_twoway *twiod = wiod_to_win_twoway(wiod); gensiods count = 0, flag_count = 0; BOOL was_full; int rv = 0; EnterCriticalSection(&wiod->lock); if (!twiod->readable) { rv = GE_NOTSUP; goto out_err; } if (gensio_circbuf_datalen(twiod->inbuf) == 0 && (wiod->err || wiod->werr)) { if (!wiod->err) wiod->err = gensio_os_err_to_err(wiod->iod.f, wiod->werr); rv = wiod->err; goto out_err; } was_full = gensio_circbuf_room_left(twiod->inbuf) == 0; gensio_circbuf_read(twiod->inbuf, ibuf, buflen, &count); gensio_circbuf_read(twiod->flagbuf, flags, buflen, &flag_count); assert(count == flag_count); wiod->read.ready = (gensio_circbuf_datalen(twiod->inbuf) > 0 || wiod->err || wiod->werr); if (!wiod->read.ready) wiod->wake(wiod); if (was_full && count) assert(SetEvent(twiod->wakeh)); out_err: LeaveCriticalSection(&wiod->lock); if (!rv && rcount) *rcount = count; return rv; } static void win_iod_twoway_wake(struct gensio_iod_win *wiod) { struct gensio_iod_win_twoway *twiod = wiod_to_win_twoway(wiod); assert(SetEvent(twiod->wakeh)); } static void win_iod_twoway_clean(struct gensio_iod_win *wiod) { struct gensio_iod_win_twoway *twiod = wiod_to_win_twoway(wiod); if (twiod->wakeh) CloseHandle(twiod->wakeh); if (twiod->inbuf) { gensio_circbuf_free(twiod->inbuf); twiod->inbuf = NULL; } if (twiod->flagbuf) { gensio_circbuf_free(twiod->flagbuf); twiod->flagbuf = NULL; } if (twiod->outbuf) { gensio_circbuf_free(twiod->outbuf); twiod->outbuf = NULL; } } static int win_iod_twoway_init(struct gensio_iod_win *wiod) { struct gensio_iod_win_twoway *twiod = wiod_to_win_twoway(wiod); struct gensio_os_funcs *o = wiod->iod.f; if (wiod->options & GENSIO_OPEN_OPTION_READABLE) { twiod->inbuf = gensio_circbuf_alloc(o, 2048); if (!twiod->inbuf) return GE_NOMEM; twiod->flagbuf = gensio_circbuf_alloc(o, 2048); if (!twiod->flagbuf) goto out_nomem; } if (wiod->options & GENSIO_OPEN_OPTION_WRITEABLE) { twiod->outbuf = gensio_circbuf_alloc(o, 2048); if (!twiod->outbuf) goto out_nomem; } wiod->write.ready = TRUE; twiod->wakeh = CreateEventA(NULL, FALSE, FALSE, NULL); if (!twiod->wakeh) goto out_nomem; return 0; out_nomem: win_iod_twoway_clean(wiod); return GE_NOMEM; } static int win_dev_control(struct gensio_iod_win *wiod, int op, bool get, intptr_t val) { struct gensio_iod_win_twoway *twiod = wiod_to_win_twoway(wiod); struct gensio_iod_win_dev *dtwiod = twiod_to_windev(twiod); struct gensio_os_funcs *o = wiod->iod.f; int rv = 0; if (!dtwiod->is_serial_port) return GE_NOTSUP; EnterCriticalSection(&wiod->lock); if (op == GENSIO_IOD_CONTROL_ENABLE_RECV_ERR) { if (get) { *((int *) val) = !!(dtwiod->comm_mask & (EV_BREAK | EV_ERR)); } else { DWORD old_mask = dtwiod->comm_mask; if (val) dtwiod->comm_mask = EV_BREAK | EV_ERR; else dtwiod->comm_mask = 0; if (dtwiod->comm_mask != old_mask) /* New mask is ready, tell the thread. */ assert(SetEvent(twiod->wakeh)); } } else { rv = gensio_win_commport_control(o, op, get, val, &dtwiod->cominfo, twiod->ioh); } LeaveCriticalSection(&wiod->lock); return rv; } static DWORD win_dev_break_handler(struct gensio_iod_win_twoway *twiod) { struct gensio_iod_win_dev *dtwiod = twiod_to_windev(twiod); return gensio_win_commport_break_done(twiod->wiod.iod.f, twiod->ioh, &dtwiod->cominfo); } static void win_iod_dev_clean(struct gensio_iod_win *wiod) { struct gensio_iod_win_twoway *twiod = wiod_to_win_twoway(wiod); struct gensio_iod_win_dev *dtwiod = twiod_to_windev(twiod); win_iod_twoway_clean(wiod); if (dtwiod->name) wiod->iod.f->free(wiod->iod.f, dtwiod->name); } static int win_dev_close(struct gensio_iod_win *wiod, bool force) { struct gensio_iod_win_twoway *twiod = wiod_to_win_twoway(wiod); struct gensio_iod_win_dev *dtwiod = twiod_to_windev(twiod); int rv; gensiods count; EnterCriticalSection(&wiod->lock); if (!force) { rv = win_twoway_bufcount(wiod, GENSIO_OUT_BUF, &count); if (!rv && count > 0) { rv = GE_INPROGRESS; goto out; } } rv = win_twoway_close(wiod); if (twiod->ioh) { twiod->extrah = NULL; gensio_win_cleanup_commport(wiod->iod.f, twiod->ioh, &dtwiod->cominfo); CloseHandle(twiod->ioh); } out: LeaveCriticalSection(&wiod->lock); return rv; } static int win_iod_dev_init(struct gensio_iod_win *wiod, void *cb_data) { struct gensio_iod_win_twoway *twiod = wiod_to_win_twoway(wiod); struct gensio_iod_win_dev *dtwiod = twiod_to_windev(twiod); struct gensio_os_funcs *o = wiod->iod.f; int rv; COMMPROP props; struct win_init_info *info = cb_data; DWORD openflags = 0; if (!(wiod->options & (GENSIO_OPEN_OPTION_READABLE | GENSIO_OPEN_OPTION_WRITEABLE))) /* We have to be readable or writable. */ return GE_INVAL; rv = win_iod_twoway_init(wiod); if (rv) return rv; rv = GE_NOMEM; dtwiod->name = gensio_alloc_sprintf(o, "\\\\.\\%s", info->name); if (!dtwiod->name) goto out_err; if (wiod->options & GENSIO_OPEN_OPTION_READABLE) openflags |= GENERIC_READ; if (wiod->options & GENSIO_OPEN_OPTION_WRITEABLE) openflags |= GENERIC_WRITE; twiod->ioh = CreateFileA(dtwiod->name, openflags, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (twiod->ioh == INVALID_HANDLE_VALUE) goto out_err_conv; if (GetFileType(twiod->ioh) != FILE_TYPE_CHAR) { rv = GE_NOTSUP; goto out_err; } memset(&props, 0, sizeof(props)); if (!GetCommProperties(twiod->ioh, &props)) goto out_err_conv; switch (props.dwProvSubType) { case PST_MODEM: case PST_RS232: case PST_RS422: case PST_RS423: case PST_RS449: if (wiod->options & GENSIO_OPEN_OPTION_SERIAL) dtwiod->is_serial_port = TRUE; if (wiod->options & GENSIO_OPEN_OPTION_READABLE) twiod->readable = TRUE; if (wiod->options & GENSIO_OPEN_OPTION_WRITEABLE) twiod->writeable = TRUE; break; case PST_PARALLELPORT: if (!(wiod->options & GENSIO_OPEN_OPTION_WRITEABLE)) /* Parallel ports are only writeable */ return GE_INVAL; if (wiod->options & GENSIO_OPEN_OPTION_READABLE) /* Parallel ports are only writeable */ return GE_INVAL; dtwiod->is_serial_port = FALSE; twiod->writeable = TRUE; twiod->readable = FALSE; break; default: rv = GE_NOTSUP; goto out_err; } if (dtwiod->is_serial_port) { rv = gensio_win_setup_commport(o, twiod->ioh, &dtwiod->cominfo, &twiod->extrah); if (rv) goto out_err; twiod->extrah_func = win_dev_break_handler; } wiod->threadfunc = win_twoway_thread; wiod->clean = win_iod_dev_clean; wiod->wake = win_iod_twoway_wake; wiod->check = win_iod_check; return 0; out_err_conv: rv = gensio_os_err_to_err(o, GetLastError()); out_err: win_iod_dev_clean(wiod); return rv; } /* * A pty iod doesn't work like the other ones. It doesn't use any of * the iod services. Instead, it has two pipe iods for the input and * output of the child process and this basically routes data and * event between those pipes and the user. */ struct gensio_iod_win_pty { struct gensio_iod_win wiod; struct gensio_iod_win *write; /* Data (input) sent to the child */ struct gensio_iod_win *read; /* Data (output) from the child */ HANDLE child; HPCON ptyh; HANDLE control; /* Used to control a gensio_pty_helper. */ HANDLE child_in; HANDLE child_out; HANDLE watch_thread; DWORD watch_thread_id; HANDLE watch_start; unsigned int clearcount; const char **argv; const char **env; char *start_dir; }; #define wiod_to_win_pty(w) gensio_container_of(w, \ struct gensio_iod_win_pty, \ wiod) static int win_pty_write(struct gensio_iod_win *wiod, const struct gensio_sg *sg, gensiods sglen, gensiods *rcount) { struct gensio_os_funcs *o = wiod->iod.f; struct gensio_iod_win_pty *piod = wiod_to_win_pty(wiod); int rv = 0; EnterCriticalSection(&wiod->lock); if (wiod->err || wiod->werr) { if (!wiod->err) wiod->err = gensio_os_err_to_err(wiod->iod.f, wiod->werr); rv = wiod->err; goto out_err; } rv = o->write(&piod->write->iod, sg, sglen, rcount); if (rv) wiod->err = rv; out_err: LeaveCriticalSection(&wiod->lock); return rv; } static int win_pty_read(struct gensio_iod_win *wiod, void *ibuf, gensiods buflen, gensiods *rcount) { struct gensio_os_funcs *o = wiod->iod.f; struct gensio_iod_win_pty *piod = wiod_to_win_pty(wiod); int rv = 0; EnterCriticalSection(&wiod->lock); if (wiod->err) { rv = wiod->err; goto out; } rv = o->read(&piod->read->iod, ibuf, buflen, rcount); if (rv) wiod->err = rv; out: LeaveCriticalSection(&wiod->lock); return rv; } static void win_pty_set_read_handler(struct gensio_iod_win *wiod, bool enable) { struct gensio_os_funcs *o = wiod->iod.f; struct gensio_iod_win_pty *piod = wiod_to_win_pty(wiod); EnterCriticalSection(&wiod->lock); o->set_read_handler(&piod->read->iod, enable); LeaveCriticalSection(&wiod->lock); } static void win_pty_set_write_handler(struct gensio_iod_win *wiod, bool enable) { struct gensio_os_funcs *o = wiod->iod.f; struct gensio_iod_win_pty *piod = wiod_to_win_pty(wiod); EnterCriticalSection(&wiod->lock); o->set_write_handler(&piod->write->iod, enable); LeaveCriticalSection(&wiod->lock); } static void win_pty_set_except_handler(struct gensio_iod_win *wiod, bool enable) { struct gensio_os_funcs *o = wiod->iod.f; struct gensio_iod_win_pty *piod = wiod_to_win_pty(wiod); EnterCriticalSection(&wiod->lock); o->set_except_handler(&piod->read->iod, enable); o->set_except_handler(&piod->write->iod, enable); LeaveCriticalSection(&wiod->lock); } static int win_pty_shutdown(struct gensio_iod_win_pty *piod, bool force) { struct gensio_iod_win *wiod = &piod->wiod; struct gensio_iod *iod; int rv = 0; if (wiod->closed) return 0; wiod->closed = TRUE; if (piod->write) { iod = &piod->write->iod; rv = i_win_close(&iod, force); if (rv) return rv;; piod->write = NULL; } if (piod->read) { iod = &piod->read->iod; rv = i_win_close(&iod, force); if (rv) return rv; piod->read = NULL; } return 0; } static int win_pty_close(struct gensio_iod_win *wiod, bool force) { struct gensio_iod_win_pty *piod = wiod_to_win_pty(wiod); int rv; EnterCriticalSection(&wiod->lock); rv = win_pty_shutdown(piod, force); if (rv) goto out; if (piod->child) TerminateProcess(piod->child, 0); if (piod->watch_thread) { LeaveCriticalSection(&wiod->lock); WaitForSingleObject(piod->watch_thread, INFINITE); EnterCriticalSection(&wiod->lock); CloseHandle(piod->watch_thread); piod->watch_thread = NULL; } if (piod->child) { CloseHandle(piod->child); piod->child = NULL; } out: LeaveCriticalSection(&wiod->lock); return rv; } /* * Wait for the child process to die and close the pty and files when * that happens. This is necessary because the read will not wake up * when the child dies unless the pty is closed. */ static DWORD WINAPI win_pty_watch_thread(LPVOID data) { struct gensio_iod_win_pty *piod = data; struct gensio_iod_win *wiod = &piod->wiod; WaitForSingleObject(piod->watch_start, INFINITE); EnterCriticalSection(&wiod->lock); /* If child is not set, the thread start failed, just quit. */ if (piod->child) { LeaveCriticalSection(&wiod->lock); WaitForSingleObject(piod->child, INFINITE); EnterCriticalSection(&wiod->lock); if (piod->ptyh) { ClosePseudoConsole(piod->ptyh); piod->ptyh = NULL; } if (piod->control) { CloseHandle(piod->control); piod->control = NULL; } } LeaveCriticalSection(&wiod->lock); return 0; } struct pty_helper_cmd { unsigned int cmd; unsigned int size; union { struct { int x; int y; } resize; }; }; #define PTY_RESIZE 1 static int win_pty_control(struct gensio_iod_win *wiod, int op, bool get, intptr_t val) { struct gensio_os_funcs *o = wiod->iod.f; struct gensio_iod_win_pty *piod = wiod_to_win_pty(wiod); int err = 0; const char **nargv; if (get) { if (op == GENSIO_IOD_CONTROL_PID) { if (!piod->child) return GE_NOTREADY; *((intptr_t *) val) = (intptr_t) piod->child; return 0; } return GE_NOTSUP; } switch (op) { case GENSIO_IOD_CONTROL_ARGV: err = gensio_argv_copy(o, (const char **) val, NULL, &nargv); if (err) return err; if (piod->argv) gensio_argv_free(o, piod->argv); piod->argv = nargv; return 0; case GENSIO_IOD_CONTROL_ENV: err = gensio_argv_copy(o, (const char **) val, NULL, &nargv); if (err) return err; if (piod->env) gensio_argv_free(o, piod->env); piod->env = nargv; return 0; case GENSIO_IOD_CONTROL_START: EnterCriticalSection(&wiod->lock); if (piod->child) { err = GE_INUSE; } else { piod->watch_thread = CreateThread(NULL, 0, win_pty_watch_thread, piod, 0, &piod->watch_thread_id); if (!piod->watch_thread) { err = gensio_os_err_to_err(o, GetLastError()); } else { err = gensio_win_pty_start(o, piod->ptyh, &piod->child_in, &piod->child_out, piod->argv, piod->env, piod->start_dir, &piod->child, &piod->control); assert(SetEvent(piod->watch_start)); if (err) { HANDLE wthread = piod->watch_thread; piod->watch_thread = NULL; LeaveCriticalSection(&wiod->lock); WaitForSingleObject(wthread, INFINITE); CloseHandle(wthread); return err; } } } LeaveCriticalSection(&wiod->lock); return err; case GENSIO_IOD_CONTROL_STOP: EnterCriticalSection(&wiod->lock); err = win_pty_shutdown(piod, false); LeaveCriticalSection(&wiod->lock); return err; case GENSIO_IOD_CONTROL_WIN_SIZE: { struct gensio_winsize *gwin = (struct gensio_winsize *) val; if (piod->control) { struct pty_helper_cmd cmd; DWORD len = 0, res; cmd.cmd = PTY_RESIZE; cmd.size = sizeof(cmd); cmd.resize.x = gwin->ws_col; cmd.resize.y = gwin->ws_row; res = WriteFile(piod->control, &cmd, sizeof(cmd), &len, FALSE); if (!res) err = gensio_os_err_to_err(o, GetLastError()); } else { COORD size; HRESULT hr; size.Y = gwin->ws_row; size.X = gwin->ws_col; hr = ResizePseudoConsole(piod->ptyh, size); if (hr != S_OK) { if (HRESULT_FACILITY(hr) == FACILITY_WIN32) err = gensio_os_err_to_err(o, HRESULT_CODE(hr)); else err = gensio_os_err_to_err(o, hr); /* Force an OS_ERR. */ } } return err; } case GENSIO_IOD_CONTROL_START_DIR: { char *dir = (char *) val; if (dir) { dir = gensio_strdup(o, dir); if (!dir) return GE_NOMEM; } if (piod->start_dir) o->free(o, piod->start_dir); piod->start_dir = dir; return 0; } default: return GE_NOTSUP; } } static void win_pty_read_handler(struct gensio_iod *iod, void *cb_data) { struct gensio_iod_win_pty *piod = cb_data; piod->wiod.read.handler(&piod->wiod.iod, piod->wiod.cb_data); } static void win_pty_write_handler(struct gensio_iod *iod, void *cb_data) { struct gensio_iod_win_pty *piod = cb_data; piod->wiod.write.handler(&piod->wiod.iod, piod->wiod.cb_data); } static void win_pty_except_handler(struct gensio_iod *iod, void *cb_data) { struct gensio_iod_win_pty *piod = cb_data; piod->wiod.except.handler(&piod->wiod.iod, piod->wiod.cb_data); } static void win_pty_cleared_handler(struct gensio_iod *iod, void *cb_data) { struct gensio_iod_win_pty *piod = cb_data; struct gensio_iod_win *wiod = &piod->wiod; void (*cleared)(struct gensio_iod *iod, void *cb_data) = NULL; EnterCriticalSection(&wiod->lock); assert(piod->clearcount > 0); piod->clearcount--; if (piod->clearcount == 0) { cleared = wiod->cleared_handler; wiod->in_handlers_clear = false; } LeaveCriticalSection(&wiod->lock); if (cleared) cleared(&wiod->iod, wiod->cb_data); } static void win_pty_clear_fd_handlers(struct gensio_iod_win *wiod) { struct gensio_os_funcs *o = wiod->iod.f; struct gensio_iod_win_pty *piod = wiod_to_win_pty(wiod); EnterCriticalSection(&wiod->lock); if (piod->read) { o->clear_fd_handlers(&piod->read->iod); piod->clearcount++; } if (piod->write) { o->clear_fd_handlers(&piod->write->iod); piod->clearcount++; } LeaveCriticalSection(&wiod->lock); } static void win_iod_pty_clean(struct gensio_iod_win *wiod) { struct gensio_os_funcs *o = wiod->iod.f; struct gensio_iod_win_pty *piod = wiod_to_win_pty(wiod); if (piod->ptyh) ClosePseudoConsole(piod->ptyh); if (piod->child_in) CloseHandle(piod->child_in); if (piod->child_out) CloseHandle(piod->child_out); if (piod->read) o->release_iod(&piod->read->iod); if (piod->write) o->release_iod(&piod->write->iod); if (piod->child) CloseHandle(piod->child); if (piod->control) CloseHandle(piod->control); if (piod->watch_start) CloseHandle(piod->watch_start); if (piod->argv) gensio_argv_free(o, piod->argv); if (piod->env) gensio_argv_free(o, piod->env); if (piod->start_dir) o->free(o, piod->start_dir); } static int win_iod_pty_init(struct gensio_iod_win *wiod, void *cb_data) { struct gensio_os_funcs *o = wiod->iod.f; struct gensio_iod_win_pty *piod = wiod_to_win_pty(wiod); HANDLE readh = NULL, writeh = NULL; BOOL readable; int err; wiod->clean = win_iod_pty_clean; wiod->set_read_handler = win_pty_set_read_handler; wiod->set_write_handler = win_pty_set_write_handler; wiod->set_except_handler = win_pty_set_except_handler; wiod->clear_fd_handlers = win_pty_clear_fd_handlers; piod->watch_start = CreateEventA(NULL, FALSE, FALSE, NULL); if (!piod->watch_start) { err = gensio_os_err_to_err(o, GetLastError()); goto out_err; } err = gensio_win_pty_alloc(o, &readh, &writeh, &piod->child_in, &piod->child_out, &piod->ptyh); if (err) goto out_err; readable = TRUE; err = win_alloc_iod(o, sizeof(struct gensio_iod_win_pipe), (intptr_t) readh, GENSIO_IOD_PIPE, 0, win_iod_pipe_init, &readable, &piod->read); if (err) goto out_err; readh = NULL; err = win_set_fd_handlers(&piod->read->iod, piod, win_pty_read_handler, NULL, win_pty_except_handler, win_pty_cleared_handler); if (err) goto out_err; readable = FALSE; err = win_alloc_iod(o, sizeof(struct gensio_iod_win_pipe), (intptr_t) writeh, GENSIO_IOD_PIPE, 0, win_iod_pipe_init, &readable, &piod->write); if (err) goto out_err; writeh = NULL; err = win_set_fd_handlers(&piod->write->iod, piod, NULL, win_pty_write_handler, win_pty_except_handler, win_pty_cleared_handler); if (err) goto out_err; return 0; out_err: if (readh) CloseHandle(readh); if (writeh) CloseHandle(writeh); if (piod->watch_start) { CloseHandle(piod->watch_start); piod->watch_start = NULL; } return err; } static unsigned int win_iod_sizes[NR_GENSIO_IOD_TYPES] = { [GENSIO_IOD_SOCKET] = sizeof(struct gensio_iod_win_sock), [GENSIO_IOD_CONSOLE] = sizeof(struct gensio_iod_win_console), [GENSIO_IOD_FILE] = sizeof(struct gensio_iod_win_file), [GENSIO_IOD_PTY] = sizeof(struct gensio_iod_win_pty), [GENSIO_IOD_PIPE] = sizeof(struct gensio_iod_win_pipe), }; typedef int (*win_iod_initfunc)(struct gensio_iod_win *, void *); static win_iod_initfunc win_iod_init[NR_GENSIO_IOD_TYPES] = { [GENSIO_IOD_SOCKET] = win_iod_socket_init, [GENSIO_IOD_CONSOLE] = win_iod_console_init, [GENSIO_IOD_FILE] = win_iod_file_init, [GENSIO_IOD_PTY] = win_iod_pty_init, [GENSIO_IOD_PIPE] = win_iod_pipe_init, }; static int win_stdio_init(struct gensio_os_funcs *o, intptr_t fd, struct gensio_iod **riod) { int rv; struct gensio_iod_win *wiod; HANDLE h; BOOL readable; if (fd > 1 || fd < 0) return GE_INVAL; if (fd == 0) { /* stdin */ h = GetStdHandle(STD_INPUT_HANDLE); readable = TRUE; } else { h = GetStdHandle(STD_OUTPUT_HANDLE); readable = FALSE; } if (h == INVALID_HANDLE_VALUE) return gensio_os_err_to_err(o, GetLastError()); /* * GetStdHandle always returns the same handle, so create a duplicate so * we can close it. */ if (!DuplicateHandle(GetCurrentProcess(), h, GetCurrentProcess(), &h, 0, FALSE, DUPLICATE_SAME_ACCESS)) return gensio_os_err_to_err(o, GetLastError()); switch (GetFileType(h)) { case FILE_TYPE_CHAR: rv = win_alloc_iod(o, sizeof(struct gensio_iod_win_console), (intptr_t) h, GENSIO_IOD_CONSOLE, 0, win_iod_console2_init, &readable, &wiod); break; case FILE_TYPE_DISK: rv = win_alloc_iod(o, sizeof(struct gensio_iod_win_file), (intptr_t) h, GENSIO_IOD_FILE, 0, win_iod_file_init, &readable, &wiod); break; case FILE_TYPE_PIPE: rv = win_alloc_iod(o, sizeof(struct gensio_iod_win_pipe), (intptr_t) h, GENSIO_IOD_PIPE, 0, win_iod_pipe_init, &readable, &wiod); break; default: rv = GE_INVAL; } if (rv) CloseHandle(h); else *riod = &wiod->iod; return rv; } static int win_add_iod(struct gensio_os_funcs *o, enum gensio_iod_type type, intptr_t fd, struct gensio_iod **riod, ...) { int rv; struct gensio_iod_win *wiod; int readable; void *info = NULL; if (type == GENSIO_IOD_STDIO) return win_stdio_init(o, fd, riod); if (type >= NR_GENSIO_IOD_TYPES || type < 0 || win_iod_sizes[type] == 0) return GE_NOTSUP; if (type == GENSIO_IOD_PIPE) { va_list ap; va_start(ap, riod); readable = va_arg(ap, int); va_end(ap); info = &readable; } rv = win_alloc_iod(o, win_iod_sizes[type], fd, type, 0, win_iod_init[type], info, &wiod); if (!rv) *riod = &wiod->iod; return rv; } static void win_release_iod(struct gensio_iod *iod) { struct gensio_os_funcs *o = iod->f; struct gensio_data *d = o->user_data; struct gensio_iod_win *wiod = iod_to_win(iod); BOOL do_free = FALSE; EnterCriticalSection(&wiod->lock); wiod->done = TRUE; if (wiod->shutdown) { LeaveCriticalSection(&wiod->lock); wiod->shutdown(wiod); } else if (wiod->threadh) { wiod->wake(wiod); LeaveCriticalSection(&wiod->lock); WaitForSingleObject(wiod->threadh, INFINITE); } else { LeaveCriticalSection(&wiod->lock); } glock_lock(d); if (gensio_list_link_inlist(&wiod->link)) gensio_list_rm(&d->waiting_iods, &wiod->link); gensio_list_rm(&d->all_iods, &wiod->all_link); do_free = d->freed && gensio_list_empty(&d->all_iods); glock_unlock(d); if (wiod->clean) wiod->clean(wiod); DeleteCriticalSection(&wiod->lock); o->free(o, wiod); if (do_free) win_finish_free(o); } static int win_iod_get_type(struct gensio_iod *iod) { struct gensio_iod_win *wiod = iod_to_win(iod); return wiod->type; } static int win_iod_get_fd(struct gensio_iod *iod) { struct gensio_iod_win *wiod = iod_to_win(iod); return wiod->fd; } static int win_iod_control(struct gensio_iod *iod, int op, bool get, intptr_t val) { struct gensio_iod_win *wiod = iod_to_win(iod); if (wiod->type == GENSIO_IOD_SOCKET) { struct gensio_iod_win_sock *siod = wiod_to_winsock(wiod); if (op == GENSIO_IOD_CONTROL_IS_CLOSED) { if (!get) return GE_NOTSUP; *((bool *) val) = wiod->closed; return 0; } if (op != GENSIO_IOD_CONTROL_SOCKINFO) return GE_NOTSUP; if (get) *((void **) val) = siod->sockinfo; else siod->sockinfo = (void *) val; return 0; } if (wiod->type == GENSIO_IOD_DEV) return win_dev_control(wiod, op, get, val); if (wiod->type == GENSIO_IOD_PTY) return win_pty_control(wiod, op, get, val); return GE_NOTSUP; } static int win_recv(struct gensio_iod *iod, void *buf, gensiods buflen, gensiods *rcount, int gflags) { struct gensio_os_funcs *o = iod->f; struct gensio_iod_win *wiod = iod_to_win(iod); struct gensio_data *d = o->user_data; int rv; if (wiod->type != GENSIO_IOD_SOCKET) return GE_INVAL; EnterCriticalSection(&wiod->lock); if (wiod->err || wiod->werr) { if (!wiod->err) wiod->err = gensio_os_err_to_err(wiod->iod.f, wiod->werr); rv = wiod->err; goto out; } wiod->read.ready = FALSE; wiod->except.ready = FALSE; rv = d->orig_recv(iod, buf, buflen, rcount, gflags); wiod->wake(wiod); out: LeaveCriticalSection(&wiod->lock); return rv; } static int win_send(struct gensio_iod *iod, const struct gensio_sg *sg, gensiods sglen, gensiods *rcount, int gflags) { struct gensio_os_funcs *o = iod->f; struct gensio_iod_win *wiod = iod_to_win(iod); struct gensio_data *d = o->user_data; int rv; if (wiod->type != GENSIO_IOD_SOCKET) return GE_INVAL; EnterCriticalSection(&wiod->lock); if (wiod->err || wiod->werr) { if (!wiod->err) wiod->err = gensio_os_err_to_err(wiod->iod.f, wiod->werr); rv = wiod->err; goto out; } /* See comment in win_iod_socket_init() on this. */ if (!wiod->always_writeable) wiod->write.ready = FALSE; rv = d->orig_send(iod, sg, sglen, rcount, gflags); wiod->wake(wiod); out: LeaveCriticalSection(&wiod->lock); return rv; } static int win_sendto(struct gensio_iod *iod, const struct gensio_sg *sg, gensiods sglen, gensiods *rcount, int gflags, const struct gensio_addr *raddr) { struct gensio_os_funcs *o = iod->f; struct gensio_iod_win *wiod = iod_to_win(iod); struct gensio_data *d = o->user_data; int rv; if (wiod->type != GENSIO_IOD_SOCKET) return GE_INVAL; EnterCriticalSection(&wiod->lock); if (wiod->err || wiod->werr) { if (!wiod->err) wiod->err = gensio_os_err_to_err(wiod->iod.f, wiod->werr); rv = wiod->err; goto out; } /* See comment in win_iod_socket_init() on this. */ if (!wiod->always_writeable) wiod->write.ready = FALSE; rv = d->orig_sendto(iod, sg, sglen, rcount, gflags, raddr); wiod->wake(wiod); out: LeaveCriticalSection(&wiod->lock); return rv; } static int win_recvfrom(struct gensio_iod *iod, void *buf, gensiods buflen, gensiods *rcount, int flags, struct gensio_addr *addr) { struct gensio_os_funcs *o = iod->f; struct gensio_iod_win *wiod = iod_to_win(iod); struct gensio_data *d = o->user_data; int rv; if (wiod->type != GENSIO_IOD_SOCKET) return GE_INVAL; EnterCriticalSection(&wiod->lock); if (wiod->err || wiod->werr) { if (!wiod->err) wiod->err = gensio_os_err_to_err(wiod->iod.f, wiod->werr); rv = wiod->err; goto out; } wiod->read.ready = FALSE; wiod->except.ready = FALSE; rv = d->orig_recvfrom(iod, buf, buflen, rcount, flags, addr); wiod->wake(wiod); out: LeaveCriticalSection(&wiod->lock); return rv; } static int win_accept(struct gensio_iod *iod, struct gensio_addr **raddr, struct gensio_iod **newiod) { struct gensio_os_funcs *o = iod->f; struct gensio_iod_win *wiod = iod_to_win(iod); struct gensio_data *d = o->user_data; int rv; if (wiod->type != GENSIO_IOD_SOCKET) return GE_INVAL; EnterCriticalSection(&wiod->lock); if (wiod->err || wiod->werr) { if (!wiod->err) wiod->err = gensio_os_err_to_err(wiod->iod.f, wiod->werr); rv = wiod->err; goto out; } rv = d->orig_accept(iod, raddr, newiod); wiod->read.ready = FALSE; wiod->wake(wiod); out: LeaveCriticalSection(&wiod->lock); return rv; } static int win_connect(struct gensio_iod *iod, const struct gensio_addr *addr) { struct gensio_os_funcs *o = iod->f; struct gensio_iod_win *wiod = iod_to_win(iod); struct gensio_iod_win_sock *siod = wiod_to_winsock(wiod); struct gensio_data *d = o->user_data; int rv; if (wiod->type != GENSIO_IOD_SOCKET) return GE_INVAL; EnterCriticalSection(&wiod->lock); if (wiod->err || wiod->werr) { if (!wiod->err) wiod->err = gensio_os_err_to_err(wiod->iod.f, wiod->werr); rv = wiod->err; goto out; } rv = d->orig_connect(iod, addr); if (rv == 0) siod->connected = TRUE; wiod->wake(wiod); out: LeaveCriticalSection(&wiod->lock); return rv; } static int i_win_close(struct gensio_iod **iodp, bool force) { struct gensio_iod *iod = *iodp; struct gensio_iod_win *wiod = iod_to_win(iod); struct gensio_os_funcs *o = iod->f; int err = 0; /* Don't do errtrig on close, it can fail and not cause any issues. */ if (wiod->type == GENSIO_IOD_SOCKET) { struct gensio_iod_win_sock *siod = wiod_to_winsock(wiod); EnterCriticalSection(&wiod->lock); if (siod->close_state == CL_DONE) { err = 0; } else { err = o->close_socket(iod, siod->close_state == CL_CALLED, force); if (err == GE_INPROGRESS) { siod->close_state = CL_CALLED; } else { wiod->fd = -1; siod->close_state = CL_DONE; } } LeaveCriticalSection(&wiod->lock); } else if (wiod->type == GENSIO_IOD_CONSOLE) { err = win_console_close(wiod, force); } else if (wiod->type == GENSIO_IOD_FILE) { struct gensio_iod_win_file *fiod = wiod_to_winfile(wiod); CloseHandle(fiod->ioh); wiod->read.ready = FALSE; wiod->write.ready = FALSE; } else if (wiod->type == GENSIO_IOD_PIPE) { err = win_oneway_close(wiod, force); } else if (wiod->type == GENSIO_IOD_DEV) { err = win_dev_close(wiod, force); } else if (wiod->type == GENSIO_IOD_PTY) { err = win_pty_close(wiod, force); } else { err = GE_NOTSUP; } if (!err) { win_release_iod(iod); *iodp = NULL; } return err; } static int win_close(struct gensio_iod **iodp) { return i_win_close(iodp, true); } static int win_graceful_close(struct gensio_iod **iodp) { return i_win_close(iodp, false); } static int win_set_non_blocking(struct gensio_iod *iod) { struct gensio_iod_win *wiod = iod_to_win(iod); struct gensio_os_funcs *o = iod->f; unsigned long flags = 1; int rv = 0; if (do_errtrig()) return GE_NOMEM; if (wiod->type == GENSIO_IOD_SOCKET) { rv = ioctlsocket(wiod->fd, FIONBIO, &flags); } else if (wiod->type == GENSIO_IOD_CONSOLE) { /* Nothing to do, already non-blocking. */ } else if (wiod->type == GENSIO_IOD_DEV) { /* Nothing to do, already non-blocking. */ } else if (wiod->type == GENSIO_IOD_PIPE) { /* Nothing to do, already non-blocking. */ } else if (wiod->type == GENSIO_IOD_FILE) { /* Nothing to do, already non-blocking. */ } else if (wiod->type == GENSIO_IOD_PIPE) { /* Nothing to do, already non-blocking. */ } else if (wiod->type == GENSIO_IOD_PTY) { /* Nothing to do, already non-blocking. */ } else { return GE_NOTSUP; } if (rv) return gensio_os_err_to_err(o, errno); return 0; } static int win_write(struct gensio_iod *iod, const struct gensio_sg *sg, gensiods sglen, gensiods *rcount) { struct gensio_iod_win *wiod = iod_to_win(iod); struct gensio_os_funcs *o = iod->f; if (wiod->type == GENSIO_IOD_SOCKET) { return o->send(iod, sg, sglen, rcount, 0); } else if (wiod->type == GENSIO_IOD_FILE) { return win_file_write(wiod, sg, sglen, rcount); } else if (wiod->type == GENSIO_IOD_CONSOLE || wiod->type == GENSIO_IOD_PIPE) { return win_oneway_write(wiod, sg, sglen, rcount); } else if (wiod->type == GENSIO_IOD_DEV) { return win_twoway_write(wiod, sg, sglen, rcount); } else if (wiod->type == GENSIO_IOD_PTY) { return win_pty_write(wiod, sg, sglen, rcount); } return GE_NOTSUP; } static int win_read(struct gensio_iod *iod, void *ibuf, gensiods buflen, gensiods *rcount) { struct gensio_iod_win *wiod = iod_to_win(iod); struct gensio_os_funcs *o = iod->f; if (wiod->type == GENSIO_IOD_SOCKET) { return o->recv(iod, ibuf, buflen, rcount, 0); } else if (wiod->type == GENSIO_IOD_FILE) { return win_file_read(wiod, ibuf, buflen, rcount); } else if (wiod->type == GENSIO_IOD_CONSOLE || wiod->type == GENSIO_IOD_PIPE) { return win_oneway_read(wiod, ibuf, buflen, rcount); } else if (wiod->type == GENSIO_IOD_DEV) { return win_twoway_read(wiod, ibuf, NULL, buflen, rcount); } else if (wiod->type == GENSIO_IOD_PTY) { return win_pty_read(wiod, ibuf, buflen, rcount); } return GE_NOTSUP; } static int win_read_flags(struct gensio_iod *iod, unsigned char *buf, unsigned char *flags, gensiods buflen, gensiods *rcount) { struct gensio_iod_win *wiod = iod_to_win(iod); gensiods count; int rv; if (wiod->type == GENSIO_IOD_DEV) return win_twoway_read(wiod, buf, flags, buflen, rcount); rv = win_read(iod, buf, buflen, &count); if (!rv) { memset(flags, 0, count); if (rcount) *rcount = count; } return rv; } static bool win_is_regfile(struct gensio_os_funcs *o, intptr_t fd) { switch (fd) { case 0: return GetFileType(GetStdHandle(STD_INPUT_HANDLE)) == FILE_TYPE_DISK; case 1: return GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) == FILE_TYPE_DISK; case 2: return GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == FILE_TYPE_DISK; } return GetFileType((HANDLE) fd) == FILE_TYPE_DISK; } static int win_bufcount(struct gensio_iod *iod, int whichbuf, gensiods *count) { struct gensio_iod_win *wiod = iod_to_win(iod); int rv; if (wiod->type == GENSIO_IOD_CONSOLE || wiod->type == GENSIO_IOD_PIPE) return win_oneway_bufcount(wiod, whichbuf, count); if (wiod->type == GENSIO_IOD_DEV) return win_twoway_bufcount(wiod, whichbuf, count); if (wiod->type == GENSIO_IOD_SOCKET) { TCP_INFO_v0 info; rv = ioctlsocket(wiod->fd, SIO_TCP_INFO, (u_long *) &info); if (rv) return gensio_os_err_to_err(wiod->iod.f, WSAGetLastError()); if (whichbuf == GENSIO_IN_BUF) *count = info.RcvBuf; else if (whichbuf == GENSIO_OUT_BUF) *count = info.BytesInFlight; else return GE_NOTSUP; return 0; } return GE_NOTSUP; } static void win_flush(struct gensio_iod *iod, int whichbuf) { struct gensio_iod_win *wiod = iod_to_win(iod); if (wiod->type == GENSIO_IOD_CONSOLE || wiod->type == GENSIO_IOD_PIPE) win_oneway_flush(wiod); else if (wiod->type == GENSIO_IOD_DEV) win_twoway_flush(wiod); } static int win_makeraw(struct gensio_iod *iod) { struct gensio_iod_win *wiod = iod_to_win(iod); int rv = GE_NOTSUP; if (do_errtrig()) return GE_NOMEM; if (wiod->type == GENSIO_IOD_CONSOLE) rv = win_console_makeraw(wiod); if (wiod->type == GENSIO_IOD_DEV) rv = 0; /* Nothing to do. */ if (wiod->type == GENSIO_IOD_PIPE) rv = 0; /* Nothing to do. */ if (wiod->type == GENSIO_IOD_FILE) rv = 0; /* Nothing to do. */ return rv; } static int win_open_dev(struct gensio_os_funcs *o, const char *iname, int options, struct gensio_iod **riod) { struct gensio_iod_win *wiod; struct win_init_info info; int rv; info.name = iname; rv = win_alloc_iod(o, sizeof(struct gensio_iod_win_dev), -1, GENSIO_IOD_DEV, options, win_iod_dev_init, &info, &wiod); if (!rv) *riod = &wiod->iod; return rv; } /* * FIXME - This currently doesn't handle running the subprogram as a * different user like it should (and the selector code does). */ static int win_exec_subprog(struct gensio_os_funcs *o, const char *argv[], const char **env, const char *start_dir, unsigned int flags, intptr_t *rpid, struct gensio_iod **rstdin, struct gensio_iod **rstdout, struct gensio_iod **rstderr) { int rv = 0; HANDLE phandle = NULL; HANDLE stdin_m = NULL; HANDLE stdout_m = NULL; HANDLE stderr_m = NULL; struct gensio_iod_win *stdin_iod = NULL; struct gensio_iod_win *stdout_iod = NULL; struct gensio_iod_win *stderr_iod = NULL; BOOL readable = FALSE; rv = gensio_win_do_exec(o, argv, env, start_dir, flags, &phandle, &stdin_m, &stdout_m, rstderr ? &stderr_m : NULL); if (rv) return rv; rv = win_alloc_iod(o, sizeof(struct gensio_iod_win_pipe), (intptr_t) stdin_m, GENSIO_IOD_PIPE, 0, win_iod_pipe_init, &readable, &stdin_iod); if (rv) goto out_err; readable = TRUE; rv = win_alloc_iod(o, sizeof(struct gensio_iod_win_pipe), (intptr_t) stdout_m, GENSIO_IOD_PIPE, 0, win_iod_pipe_init, &readable, &stdout_iod); if (rv) goto out_err; if (stderr_m) { rv = win_alloc_iod(o, sizeof(struct gensio_iod_win_pipe), (intptr_t) stderr_m, GENSIO_IOD_PIPE, 0, win_iod_pipe_init, &readable, &stderr_iod); if (rv) goto out_err; } *rpid = (intptr_t) phandle; *rstdin = &stdin_iod->iod; *rstdout = &stdout_iod->iod; if (rstderr) *rstderr = &stderr_iod->iod; return 0; out_err: if (stdin_iod) { struct gensio_iod *iod = &stdin_iod->iod; o->close(&iod); } else if (stdin_m) CloseHandle(stdin_m); if (stdout_iod) { struct gensio_iod *iod = &stdout_iod->iod; o->close(&iod); } else if (stdout_m) CloseHandle(stdout_m); if (stderr_iod) { struct gensio_iod *iod = &stderr_iod->iod; o->close(&iod); } else if (stderr_m) CloseHandle(stderr_m); return rv; } static int win_wait_subprog(struct gensio_os_funcs *o, intptr_t pid, int *retcode) { HANDLE processh = (HANDLE) pid; DWORD exit_code; if (GetExitCodeProcess(processh, &exit_code)) { if (exit_code == STILL_ACTIVE) return GE_INPROGRESS; *retcode = exit_code; CloseHandle(processh); return 0; } return gensio_os_err_to_err(o, GetLastError()); } static int win_kill_subprog(struct gensio_os_funcs *o, intptr_t pid, bool force) { HANDLE processh = (HANDLE) pid; if (!force) /* Window's doesn't have a non-forceful kill. */ return 0; if (!TerminateProcess(processh, 1)) return gensio_os_err_to_err(o, GetLastError()); return 0; } static int win_get_random(struct gensio_os_funcs *o, void *data, unsigned int len) { NTSTATUS rv; BCRYPT_ALG_HANDLE alg; int err = 0; rv = BCryptOpenAlgorithmProvider(&alg, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); if (rv != STATUS_SUCCESS) return gensio_os_err_to_err(o, rv); rv = BCryptGenRandom(alg, data, len, 0); if (rv != STATUS_SUCCESS) err = gensio_os_err_to_err(o, rv); BCryptCloseAlgorithmProvider(alg, 0); return err; } static void win_finish_free(struct gensio_os_funcs *o) { struct gensio_data *d = o->user_data; gensio_memtrack_cleanup(d->mtrack); if (d->timerth) { assert(WSASetEvent(d->timer_wakeev)); WaitForSingleObject(d->timerth, INFINITE); } if (d->waiter) CloseHandle(d->waiter); if (d->timer_wakeev) WSACloseEvent(d->timer_wakeev); gensio_stdsock_cleanup(o); DeleteCriticalSection(&d->glock); DeleteCriticalSection(&d->timer_lock); free(d); free(o); } static int gensio_win_control(struct gensio_os_funcs *o, int func, void *data, gensiods *datalen) { struct gensio_data *d = o->user_data; switch (func) { case GENSIO_CONTROL_SET_PROC_DATA: d->proc_data = data; return 0; default: return GE_NOTSUP; } } static int i_gensio_win_funcs_alloc(unsigned int flags, struct gensio_os_funcs **ro) { struct gensio_data *d; struct gensio_os_funcs *o; int err = GE_NOMEM; if (flags) return GE_NOTSUP; o = malloc(sizeof(*o)); if (!o) return GE_NOMEM; memset(o, 0, sizeof(*o)); d = malloc(sizeof(*d)); if (!d) { free(o); return GE_NOMEM; } memset(d, 0, sizeof(*d)); d->refcount = 1; InitializeCriticalSection(&d->glock); InitializeCriticalSection(&d->timer_lock); gensio_list_init(&d->waiting_iods); gensio_list_init(&d->all_iods); theap_init(&d->timer_heap); d->mtrack = gensio_memtrack_alloc(); o->user_data = d; d->waiter = CreateSemaphoreA(NULL, 0, 1000000, NULL); if (!d->waiter) { err = gensio_os_err_to_err(o, GetLastError()); goto out_err; } d->timer_wakeev = WSACreateEvent(); if (d->timer_wakeev == WSA_INVALID_EVENT) { err = gensio_os_err_to_err(o, GetLastError()); goto out_err; } d->timerth = CreateThread(NULL, 0, timer_thread, o, 0, &d->timerthid); if (!d->timerth) { err = gensio_os_err_to_err(o, GetLastError()); goto out_err; } o->zalloc = win_zalloc; o->free = win_free; o->alloc_lock = win_alloc_lock; o->free_lock = win_free_lock; o->lock = win_lock; o->unlock = win_unlock; o->set_fd_handlers = win_set_fd_handlers; o->clear_fd_handlers = win_clear_fd_handlers; o->clear_fd_handlers_norpt = win_clear_fd_handlers_norpt; o->set_read_handler = win_set_read_handler; o->set_write_handler = win_set_write_handler; o->set_except_handler = win_set_except_handler; o->alloc_timer = win_alloc_timer; o->free_timer = win_free_timer; o->start_timer = win_start_timer; o->start_timer_abs = win_start_timer_abs; o->stop_timer = win_stop_timer; o->stop_timer_with_done = win_stop_timer_with_done; o->alloc_runner = win_alloc_runner; o->free_runner = win_free_runner; o->run = win_run; o->alloc_waiter = win_alloc_waiter; o->free_waiter = win_free_waiter; o->wait = win_wait; o->wait_intr = win_wait_intr; o->wake = win_wake; o->service = win_service; o->free_funcs = win_free_funcs; o->get_funcs = win_get_funcs; o->call_once = gensio_call_once; o->get_monotonic_time = win_get_monotonic_time; o->handle_fork = win_handle_fork; o->wait_intr_sigmask = win_wait_intr_sigmask; o->add_iod = win_add_iod; o->release_iod = win_release_iod; o->iod_get_type = win_iod_get_type; o->iod_get_fd = win_iod_get_fd; o->iod_control = win_iod_control; o->set_non_blocking = win_set_non_blocking; o->close = win_close; o->graceful_close = win_graceful_close; o->write = win_write; o->read = win_read; o->is_regfile = win_is_regfile; o->bufcount = win_bufcount; o->flush = win_flush; o->makeraw = win_makeraw; o->open_dev = win_open_dev; o->exec_subprog = win_exec_subprog; o->kill_subprog = win_kill_subprog; o->wait_subprog = win_wait_subprog; o->get_random = win_get_random; o->control = gensio_win_control; o->read_flags = win_read_flags; gensio_addr_addrinfo_set_os_funcs(o); err = gensio_stdsock_set_os_funcs(o); if (err) goto out_err; /* We have to catch these to reset status. */ d->orig_recv = o->recv; d->orig_send = o->send; d->orig_sendto = o->sendto; d->orig_recvfrom = o->recvfrom; d->orig_accept = o->accept; d->orig_connect = o->connect; o->recv = win_recv; o->send = win_send; o->sendto = win_sendto; o->recvfrom = win_recvfrom; o->accept = win_accept; o->connect = win_connect; *ro = o; return 0; out_err: win_finish_free(o); return err; } int gensio_win_funcs_alloc(struct gensio_os_funcs **ro) { return i_gensio_win_funcs_alloc(0, ro); } struct gensio_os_proc_data { struct gensio_os_funcs *o; lock_type lock; BOOL term_handler_set; BOOL got_term_sig; void (*term_handler)(void *handler_data); void *term_handler_data; BOOL winsize_handler_set; HANDLE outcon; int x_chrs; int y_chrs; int x_bits; int y_bits; BOOL got_winsize_sig; void (*winsize_handler)(int x_chrs, int y_chrs, int x_bits, int y_bits, void *handler_data); void *winsize_handler_data; HANDLE global_waiter; struct gensio_os_cleanup_handler *cleanup_handlers; }; static struct gensio_os_proc_data proc_data; bool proc_setup; /* * Code so CoInitialize() gets called for each thread and cleaned up * when the thread is complete. */ static SRWLOCK threadinfo_idx_lock = SRWLOCK_INIT; static DWORD threadinfo_idx; static bool threadinfo_setup; static void __attribute__((stdcall)) threadinfo_cb(PVOID lpFlsData) { if (!lpFlsData) return; CoUninitialize(); } static void gensio_os_thread_cleanup(void) { FlsSetValue(threadinfo_idx, NULL); CoUninitialize(); } int gensio_os_thread_setup(struct gensio_os_funcs *o) { int rv = 0; HRESULT res; void *threadval; if (!threadinfo_setup) { AcquireSRWLockExclusive(&threadinfo_idx_lock); if (!threadinfo_setup) { threadinfo_idx = FlsAlloc(threadinfo_cb); if (threadinfo_idx == FLS_OUT_OF_INDEXES) { ReleaseSRWLockExclusive(&threadinfo_idx_lock); return GE_INUSE; } threadinfo_setup = true; } ReleaseSRWLockExclusive(&threadinfo_idx_lock); } threadval = FlsGetValue(threadinfo_idx); if (threadval) return 0; /* Already initialized. */ res = CoInitializeEx(NULL, COINIT_MULTITHREADED); switch (res) { case S_OK: case S_FALSE: break; case RPC_E_CHANGED_MODE: rv = GE_INCONSISTENT; break; case E_INVALIDARG: rv = GE_INVAL; break; case E_OUTOFMEMORY: rv = GE_NOMEM; break; case E_UNEXPECTED: default: rv = GE_OSERR; break; } if (!rv) { if (!FlsSetValue(threadinfo_idx, (void *)(intptr_t) 1)) { gensio_os_thread_cleanup(); rv = GE_OSERR; } } return rv; } int gensio_os_proc_setup(struct gensio_os_funcs *o, struct gensio_os_proc_data **data) { int rv = GE_INUSE; AcquireSRWLockExclusive(&def_win_os_funcs_lock); if (proc_setup) goto out; rv = gensio_os_thread_setup(o); if (rv) goto out; proc_data.global_waiter = CreateSemaphoreA(NULL, 0, 1000000, NULL); if (!proc_data.global_waiter) { gensio_os_thread_cleanup(); rv = GE_NOMEM; goto out; } rv = o->control(o, GENSIO_CONTROL_SET_PROC_DATA, &proc_data, NULL); if (rv) { CloseHandle(proc_data.global_waiter); gensio_os_thread_cleanup(); proc_data.global_waiter = NULL; goto out; } LOCK_INIT(&proc_data.lock); proc_data.o = o; *data = &proc_data; out: ReleaseSRWLockExclusive(&def_win_os_funcs_lock); return rv; } static void proc_release_sem(struct gensio_os_proc_data *data) { BOOL rvb; rvb = ReleaseSemaphore(proc_data.global_waiter, 1, NULL); if (!rvb) /* Too many posts is improbable, but ok. */ assert(GetLastError() == ERROR_TOO_MANY_POSTS); } static BOOL WINAPI ConCtrlHandler(DWORD dwCtrlType) { switch (dwCtrlType) { case CTRL_C_EVENT: case CTRL_CLOSE_EVENT: case CTRL_SHUTDOWN_EVENT: proc_data.got_term_sig = true; proc_release_sem(&proc_data); return TRUE; default: return FALSE; } } void check_winsize(struct gensio_iod_win_oneway *owiod) { struct gensio_iod_win *wiod = &owiod->wiod; struct gensio_iod *iod = &wiod->iod; struct gensio_os_funcs *o = iod->f; struct gensio_data *d = o->user_data; struct gensio_os_proc_data *data = d->proc_data; CONSOLE_SCREEN_BUFFER_INFOEX sbi; int x_chrs, y_chrs; if (!data) return; LOCK(&data->lock); if (!data->winsize_handler_set) goto out_unlock; if (!data->outcon) { data->outcon = CreateFileA("CONOUT$", GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (data->outcon == INVALID_HANDLE_VALUE) { data->outcon = NULL; goto out_unlock; } } memset(&sbi, 0, sizeof(sbi)); sbi.cbSize = sizeof(sbi); if (!GetConsoleScreenBufferInfoEx(data->outcon, &sbi)) goto out_unlock; x_chrs = sbi.dwSize.X; y_chrs = sbi.srWindow.Bottom - sbi.srWindow.Top + 1; if (x_chrs != data->x_chrs || y_chrs != data->y_chrs) { data->x_chrs = x_chrs; data->y_chrs = y_chrs; data->got_winsize_sig = TRUE; proc_release_sem(data); } out_unlock: UNLOCK(&data->lock); } void gensio_register_os_cleanup_handler(struct gensio_os_funcs *o, struct gensio_os_cleanup_handler *h) { struct gensio_data *d = o->user_data; struct gensio_os_proc_data *data = d->proc_data; LOCK(&data->lock); h->next = data->cleanup_handlers; data->cleanup_handlers = h; UNLOCK(&data->lock); } void gensio_os_proc_cleanup(struct gensio_os_proc_data *data) { AcquireSRWLockExclusive(&def_win_os_funcs_lock); if (!proc_setup) goto out; proc_setup = false; /* We should be single-threaded here. */ while (data->cleanup_handlers) { struct gensio_os_cleanup_handler *h = data->cleanup_handlers; data->cleanup_handlers = h->next; h->cleanup(h); } if (data->term_handler_set) { SetConsoleCtrlHandler(ConCtrlHandler, false); data->term_handler_set = false; } if (data->outcon) { CloseHandle(data->outcon); data->outcon = NULL; } if (data->global_waiter) { CloseHandle(data->global_waiter); data->global_waiter = NULL; } LOCK_DESTROY(&proc_data.lock); out: ReleaseSRWLockExclusive(&def_win_os_funcs_lock); } HANDLE gensio_os_proc_win_get_main_handle(struct gensio_os_proc_data *data) { return data->global_waiter; } void gensio_os_proc_check_handlers(struct gensio_os_proc_data *data) { LOCK(&data->lock); if (data->got_term_sig) { data->got_term_sig = FALSE; if (data->term_handler) data->term_handler(data->term_handler_data); } if (data->got_winsize_sig) { data->got_winsize_sig = FALSE; if (data->winsize_handler) data->winsize_handler(data->x_chrs, data->y_chrs, data->x_bits, data->y_bits, data->winsize_handler_data); } UNLOCK(&data->lock); } int gensio_os_proc_register_term_handler(struct gensio_os_proc_data *data, void (*handler)(void *handler_data), void *handler_data) { int err = 0; LOCK(&data->lock); if (SetConsoleCtrlHandler(ConCtrlHandler, TRUE) == 0) { err = gensio_os_err_to_err(data->o, GetLastError()); } else { data->term_handler = handler; data->term_handler_data = handler_data; data->term_handler_set = true; } UNLOCK(&data->lock); return err; } int gensio_os_proc_register_reload_handler(struct gensio_os_proc_data *data, void (*handler)(void *handler_data), void *handler_data) { return GE_NOTSUP; } int gensio_os_proc_register_winsize_handler(struct gensio_os_proc_data *data, struct gensio_iod *console_iod, void (*handler)(int x_chrs, int y_chrs, int x_bits, int y_bits, void *handler_data), void *handler_data) { struct gensio_iod_win *wiod = iod_to_win(console_iod); int err = 0; LOCK(&data->lock); if (!wiod || !handler) { data->got_winsize_sig = false; data->winsize_handler_set = false; goto out_unlock; } if (wiod->type != GENSIO_IOD_CONSOLE) { err = GE_INVAL; goto out_unlock; } data->winsize_handler = handler; data->winsize_handler_data = handler_data; data->winsize_handler_set = true; /* Wake the input handler to do the winch handling. */ SetEvent(wiod_to_win_oneway(wiod)->wakeh); proc_release_sem(data); out_unlock: UNLOCK(&data->lock); return err; } struct gensio_thread { struct gensio_os_funcs *o; HANDLE handle; DWORD tid; void (*start_func)(void *data); void *data; }; static DWORD WINAPI gensio_os_thread_func(LPVOID info) { struct gensio_thread *tid = info; gensio_os_thread_setup(tid->o); /* Shouldn't be able to fail. */ tid->start_func(tid->data); return 0; } int gensio_os_new_thread(struct gensio_os_funcs *o, void (*start_func)(void *data), void *data, struct gensio_thread **thread_id) { struct gensio_thread *tid; int rv; tid = o->zalloc(o, sizeof(*tid)); if (!tid) return GE_NOMEM; tid->o = o; tid->start_func = start_func; tid->data = data; tid->handle = CreateThread(NULL, 0, gensio_os_thread_func, tid, 0, &tid->tid); if (!tid->handle) { rv = gensio_os_err_to_err(o, GetLastError()); o->free(o, tid); return rv; } *thread_id = tid; return 0; } int gensio_os_wait_thread(struct gensio_thread *tid) { WaitForSingleObject(tid->handle, INFINITE); tid->o->free(tid->o, tid); return 0; } int gensio_i_os_err_to_err(struct gensio_os_funcs *o, int oserr, const char *caller, const char *file, unsigned int lineno) { int err; if (oserr == 0) return 0; switch(oserr) { case WSAEINVAL: err = GE_INVAL; break; case WSAEINPROGRESS: err = GE_INPROGRESS; break; case WSAETIMEDOUT: err = GE_TIMEDOUT; break; case WSAECONNRESET: err = GE_REMCLOSE; break; case WSAECONNABORTED: err = GE_REMCLOSE; break; case WSAEHOSTUNREACH: err = GE_HOSTDOWN; break; case WSAECONNREFUSED: err = GE_CONNREFUSE; break; case WSAEADDRINUSE: err = GE_ADDRINUSE; break; case WSAEINTR: err = GE_INTERRUPTED; break; case WSAESHUTDOWN: err = GE_SHUTDOWN; break; case WSAEMSGSIZE: err = GE_TOOBIG; break; case WSAEACCES: err = GE_PERM; break; case WSAEWOULDBLOCK: err = GE_INPROGRESS; break; case STATUS_NOT_FOUND: err = GE_NOTFOUND; break; case STATUS_INVALID_PARAMETER: err = GE_INVAL; break; case STATUS_NO_MEMORY: err = GE_NOMEM; break; case ERROR_NOT_ENOUGH_MEMORY: err = GE_NOMEM; break; case ERROR_BROKEN_PIPE: err = GE_REMCLOSE; break; case ERROR_NO_DATA: err = GE_REMCLOSE; break; case ERROR_FILE_NOT_FOUND: err = GE_NOTFOUND; break; case ERROR_NOT_FOUND: err = GE_NOTFOUND; break; case ERROR_ACCESS_DENIED: err = GE_PERM; break; default: err = GE_OSERR; } if (err == GE_OSERR) { char errbuf[128]; errbuf[0] = '\0'; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, oserr, 0, errbuf, sizeof(errbuf), NULL); gensio_log(o, GENSIO_LOG_INFO, "Unhandled OS error in %s:%d: %s (%d)", caller, lineno, errbuf, oserr); } return err; } int gensio_default_os_hnd(int wake_sig, struct gensio_os_funcs **o) { int err = 0; AcquireSRWLockExclusive(&def_win_os_funcs_lock); if (!def_win_os_funcs) err = i_gensio_win_funcs_alloc(0, &def_win_os_funcs); else win_get_funcs(def_win_os_funcs); ReleaseSRWLockExclusive(&def_win_os_funcs_lock); if (!err) *o = def_win_os_funcs; return 0; } int gensio_valloc_os_funcs(int wake_sig, struct gensio_os_funcs **o, unsigned int flags, va_list va) { return i_gensio_win_funcs_alloc(flags, o); } int gensio_alloc_os_funcs(int wake_sig, struct gensio_os_funcs **o, unsigned int flags, ...) { return i_gensio_win_funcs_alloc(flags, o); } void gensio_osfunc_exit(int rv) { exit(rv); } gensio-3.0.0/lib/gensio_xlt.c0000664000175000017500000003407015055560720011557 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018-2025 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include struct xlt_config { unsigned char inxlt[256]; unsigned char outxlt[256]; }; struct xlt_filter { struct gensio_filter *filter; struct gensio_lock *lock; struct gensio_os_funcs *o; struct xlt_config config; unsigned char inbuf[256]; gensiods inlen; unsigned char outbuf[256]; gensiods outlen; }; #define filter_to_xlt(v) ((struct xlt_filter *) \ gensio_filter_get_user_data(v)) static void xlt_lock(struct xlt_filter *tfilter) { tfilter->o->lock(tfilter->lock); } static void xlt_unlock(struct xlt_filter *tfilter) { tfilter->o->unlock(tfilter->lock); } static bool xlt_ul_read_pending(struct gensio_filter *filter) { struct xlt_filter *tfilter = filter_to_xlt(filter); return tfilter->inlen > 0; } static bool xlt_ll_write_pending(struct gensio_filter *filter) { struct xlt_filter *tfilter = filter_to_xlt(filter); return tfilter->outlen > 0; } static bool xlt_ll_read_needed(struct gensio_filter *filter) { return false; } static int xlt_check_open_done(struct gensio_filter *filter, struct gensio *io) { return 0; } static int xlt_try_connect(struct gensio_filter *filter, gensio_time *timeout) { return 0; } static int xlt_try_disconnect(struct gensio_filter *filter, gensio_time *timeout) { return 0; } static int xlt_ul_write(struct gensio_filter *filter, gensio_ul_filter_data_handler handler, void *cb_data, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { struct xlt_filter *tfilter = filter_to_xlt(filter); int err = 0; gensiods i, j, pos = tfilter->outlen; gensiods count = 0; xlt_lock(tfilter); for (i = 0; pos < sizeof(tfilter->outbuf) && i < sglen; i++) { const unsigned char *buf = sg[i].buf; for (j = 0; pos < sizeof(tfilter->outbuf) && j < sg[i].buflen; j++) tfilter->outbuf[pos++] = tfilter->config.outxlt[buf[j]]; } tfilter->outlen = pos; if (tfilter->outlen > 0) { struct gensio_sg osg; osg.buf = tfilter->outbuf; osg.buflen = tfilter->outlen; err = handler(cb_data, &count, &osg, 1, auxdata); if (!err) { if (count >= tfilter->outlen) { tfilter->outlen = 0; } else { tfilter->outlen -= count; memmove(tfilter->outbuf, tfilter->outbuf + count, tfilter->outlen); } } } xlt_unlock(tfilter); if (!err && rcount) *rcount = pos; return err; } static int xlt_ll_write(struct gensio_filter *filter, gensio_ll_filter_data_handler handler, void *cb_data, gensiods *rcount, unsigned char *buf, gensiods buflen, const char *const *auxdata) { struct xlt_filter *tfilter = filter_to_xlt(filter); int err = 0; gensiods i, pos = tfilter->inlen; gensiods count = 0; xlt_lock(tfilter); for (i = 0; pos < sizeof(tfilter->inbuf) && i < buflen; i++) tfilter->inbuf[pos++] = tfilter->config.inxlt[buf[i]]; tfilter->inlen = pos; if (tfilter->inlen > 0) { err = handler(cb_data, &count, tfilter->inbuf, tfilter->inlen, auxdata); if (!err) { if (count >= tfilter->inlen) { tfilter->inlen = 0; } else { tfilter->inlen -= count; memmove(tfilter->inbuf, tfilter->inbuf + count, tfilter->inlen); } } } xlt_unlock(tfilter); if (!err && rcount) *rcount = pos; return err; } static int xlt_setup(struct gensio_filter *filter) { return 0; } static void xlt_filter_cleanup(struct gensio_filter *filter) { } static void tfilter_free(struct xlt_filter *tfilter) { if (tfilter->lock) tfilter->o->free_lock(tfilter->lock); if (tfilter->filter) gensio_filter_free_data(tfilter->filter); tfilter->o->free(tfilter->o, tfilter); } static void xlt_free(struct gensio_filter *filter) { struct xlt_filter *tfilter = filter_to_xlt(filter); tfilter_free(tfilter); } static int gensio_xlt_filter_func(struct gensio_filter *filter, int op, void *func, void *data, gensiods *count, void *buf, const void *cbuf, gensiods buflen, const char *const *auxdata) { switch (op) { case GENSIO_FILTER_FUNC_UL_READ_PENDING: return xlt_ul_read_pending(filter); case GENSIO_FILTER_FUNC_LL_WRITE_PENDING: return xlt_ll_write_pending(filter); case GENSIO_FILTER_FUNC_LL_READ_NEEDED: return xlt_ll_read_needed(filter); case GENSIO_FILTER_FUNC_CHECK_OPEN_DONE: return xlt_check_open_done(filter, data); case GENSIO_FILTER_FUNC_TRY_CONNECT: return xlt_try_connect(filter, data); case GENSIO_FILTER_FUNC_TRY_DISCONNECT: return xlt_try_disconnect(filter, data); case GENSIO_FILTER_FUNC_UL_WRITE_SG: return xlt_ul_write(filter, func, data, count, cbuf, buflen, auxdata); case GENSIO_FILTER_FUNC_LL_WRITE: return xlt_ll_write(filter, func, data, count, buf, buflen, auxdata); case GENSIO_FILTER_FUNC_SETUP: return xlt_setup(filter); case GENSIO_FILTER_FUNC_CLEANUP: xlt_filter_cleanup(filter); return 0; case GENSIO_FILTER_FUNC_FREE: xlt_free(filter); return 0; case GENSIO_FILTER_FUNC_CONTROL: return GE_NOTSUP; default: return GE_NOTSUP; } } static int process_xlt(unsigned char table[256], const char *str) { char *end; unsigned long v1, v2; v1 = strtoul(str, &end, 0); if (end == str || *end != ':' || v1 >= 256) return GE_INVAL; str = end + 1; v2 = strtoul(str, &end, 0); if (end == str || *end != '\0' || v1 >= 256) return GE_INVAL; table[v1] = v2; return 0; } static int gensio_xlt_config(struct gensio_pparm_info *p, struct gensio_os_funcs *o, const char * const args[], struct gensio_base_parms *parms, struct xlt_config *config) { int rv; const char *str; bool bval; unsigned int i; for (i = 0; i < 256; i++) { config->inxlt[i] = i; config->outxlt[i] = i; } for (i = 0; args && args[i]; i++) { if (gensio_pparm_value(p, args[i], "in", &str) > 0) { rv = process_xlt(config->inxlt, str); if (rv) return rv; continue; } if (gensio_pparm_value(p, args[i], "out", &str) > 0) { rv = process_xlt(config->outxlt, str); if (rv) return rv; continue; } if (gensio_pparm_bool(p, args[i], "crlf", &bval) > 0) { config->inxlt['\r'] = '\n'; config->outxlt['\n'] = '\r'; continue; } if (gensio_pparm_bool(p, args[i], "lfcr", &bval) > 0) { config->outxlt['\r'] = '\n'; config->inxlt['\n'] = '\r'; continue; } if (gensio_pparm_bool(p, args[i], "crnl", &bval) > 0) { config->inxlt['\r'] = '\n'; config->outxlt['\n'] = '\r'; continue; } if (gensio_pparm_bool(p, args[i], "nlcr", &bval) > 0) { config->outxlt['\r'] = '\n'; config->inxlt['\n'] = '\r'; continue; } if (gensio_base_parm(parms, p, args[i]) > 0) continue; gensio_pparm_unknown_parm(p, args[i]); return GE_INVAL; } return 0; } static int gensio_xlt_filter_alloc(struct gensio_os_funcs *o, struct xlt_config *config, struct gensio_filter **rfilter) { int rv = GE_INVAL; struct xlt_filter *tfilter; tfilter = o->zalloc(o, sizeof(*tfilter)); if (!tfilter) return GE_NOMEM; tfilter->o = o; tfilter->config = *config; tfilter->lock = o->alloc_lock(o); if (!tfilter->lock) { rv = GE_NOMEM; goto out_err; } tfilter->filter = gensio_filter_alloc_data(o, gensio_xlt_filter_func, tfilter); if (!tfilter->filter) { rv = GE_NOMEM; goto out_err; } *rfilter = tfilter->filter; return 0; out_err: tfilter_free(tfilter); return rv; } static int xlt_gensio_alloc2(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio_base_parms **parms, struct gensio **net) { int err; struct gensio_filter *filter; struct gensio_ll *ll; struct gensio *io; struct xlt_config config; GENSIO_DECLARE_PPGENSIO(p, o, cb, "xlt", user_data); memset(&config, 0, sizeof(config)); err = gensio_xlt_config(&p, 0, args, *parms, &config); if (err) return err; err = gensio_xlt_filter_alloc(o, &config, &filter); if (err) return err; ll = gensio_gensio_ll_alloc(o, child); if (!ll) { gensio_filter_free(filter); return GE_NOMEM; } gensio_ref(child); /* So gensio_ll_free doesn't free the child if fail */ io = base_gensio_alloc(o, ll, filter, child, "xlt", cb, user_data); if (!io) { gensio_ll_free(ll); gensio_filter_free(filter); return GE_NOMEM; } gensio_free(child); /* Lose the ref we acquired. */ err = gensio_base_parms_set(io, parms); if (err) { gensio_free(io); return err; } gensio_set_attr_from_child(io, child); *net = io; return 0; } static int xlt_gensio_alloc(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **net) { struct gensio_base_parms *parms; int err; err = gensio_base_parms_alloc(o, true, "xlt", &parms); if (err) return err; err = xlt_gensio_alloc2(child, args, o, cb, user_data, &parms, net); if (parms) gensio_base_parms_free(&parms); return err; } static int str_to_xlt_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct gensio *io2; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio(str, o, cb, user_data, &io2); if (err) return err; err = xlt_gensio_alloc(io2, args, o, cb, user_data, new_gensio); if (err) gensio_free(io2); return err; } struct xltna_data { struct gensio_accepter *acc; struct xlt_config config; struct gensio_os_funcs *o; gensio_accepter_event cb; void *user_data; }; static void xltna_free(void *acc_data) { struct xltna_data *nadata = acc_data; nadata->o->free(nadata->o, nadata); } static int xltna_alloc_gensio(void *acc_data, const char * const *iargs, struct gensio *child, struct gensio **rio) { struct xltna_data *nadata = acc_data; struct gensio_base_parms *parms = NULL; int err; parms = gensio_acc_base_parms_dup(nadata->acc); if (!parms) return GE_NOMEM; err = xlt_gensio_alloc2(child, iargs, nadata->o, NULL, NULL, &parms, rio); if (parms) gensio_base_parms_free(&parms); return err; } static int xltna_new_child(void *acc_data, void **finish_data, struct gensio_filter **filter) { struct xltna_data *nadata = acc_data; return gensio_xlt_filter_alloc(nadata->o, &nadata->config, filter); } static int xltna_finish_parent(void *acc_data, void *finish_data, struct gensio *io) { struct xltna_data *nadata = acc_data; int err; err = gensio_acc_base_parms_apply(nadata->acc, io); if (err) return err; gensio_set_attr_from_child(io, gensio_get_child(io, 0)); return 0; } static int gensio_gensio_acc_xlt_cb(void *acc_data, int op, void *data1, void *data2, void *data3, const void *data4) { switch (op) { case GENSIO_GENSIO_ACC_ALLOC_GENSIO: return xltna_alloc_gensio(acc_data, data4, data1, data2); case GENSIO_GENSIO_ACC_NEW_CHILD: return xltna_new_child(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FINISH_PARENT: return xltna_finish_parent(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FREE: xltna_free(acc_data); return 0; default: return GE_NOTSUP; } } static int xlt_gensio_accepter_alloc(struct gensio_accepter *child, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { struct xltna_data *nadata = NULL; int err; struct gensio_base_parms *parms = NULL; GENSIO_DECLARE_PPACCEPTER(p, o, cb, "xlt", user_data); err = gensio_base_parms_alloc(o, true, "xlt", &parms); if (err) goto out_err; nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) goto out_nomem; err = gensio_xlt_config(&p, o, args, parms, &nadata->config); if (err) goto out_err; nadata->o = o; nadata->cb = cb; nadata->user_data = user_data; err = gensio_gensio_accepter_alloc(child, o, "xlt", cb, user_data, gensio_gensio_acc_xlt_cb, nadata, &nadata->acc); if (err) goto out_err; err = gensio_acc_base_parms_set(nadata->acc, &parms); if (err) goto out_err; gensio_acc_set_is_reliable(nadata->acc, gensio_acc_is_reliable(child)); gensio_acc_set_is_packet(nadata->acc, gensio_acc_is_packet(child)); gensio_acc_set_is_message(nadata->acc, gensio_acc_is_message(child)); *accepter = nadata->acc; return 0; out_nomem: err = GE_NOMEM; out_err: if (nadata) { if (nadata->acc) gensio_acc_free(nadata->acc); else xltna_free(nadata); } if (parms) gensio_base_parms_free(&parms); return err; } static int str_to_xlt_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { int err; struct gensio_accepter *acc2 = NULL; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio_accepter(str, o, cb, user_data, &acc2); if (!err) { err = xlt_gensio_accepter_alloc(acc2, args, o, cb, user_data, acc); if (err) gensio_acc_free(acc2); } return err; } int gensio_init_xlt(struct gensio_os_funcs *o) { int rv; rv = register_filter_gensio(o, "xlt", str_to_xlt_gensio, xlt_gensio_alloc); if (rv) return rv; rv = register_filter_gensio_accepter(o, "xlt", str_to_xlt_gensio_accepter, xlt_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/sergensio_serialdev.c0000664000175000017500000013735315060652050013442 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include #include #include "seriallock.h" #include "utils.h" static int speedstr_to_speed(struct gensio_pparm_info *p, bool logerr, const char *speed, const char **rest) { const char *end = speed; unsigned int len; int rv; while (*end && isdigit(*end)) end++; len = end - speed; if (len < 1) { if (logerr) gensio_pparm_log(p, "Invalid serial speed: %s", speed); return -1; } rv = strtoul(speed, NULL, 10); *rest = end; return rv; } struct penum_val { char *str; int val; }; static struct penum_val parity_enums[] = { { "NONE", GENSIO_SER_PARITY_NONE }, { "EVEN", GENSIO_SER_PARITY_EVEN }, { "ODD", GENSIO_SER_PARITY_ODD }, { "MARK", GENSIO_SER_PARITY_MARK }, { "SPACE", GENSIO_SER_PARITY_SPACE }, { NULL } }; static int lookup_parity_str(const char *str) { unsigned int i; for (i = 0; parity_enums[i].str; i++) { if (strcmp(parity_enums[i].str, str) == 0) return parity_enums[i].val; } return -1; } static const char * parity_to_str(int val) { unsigned int i; for (i = 0; parity_enums[i].str; i++) { if (parity_enums[i].val == val) return parity_enums[i].str; } return "?"; } struct sterm_data; struct termio_xlat_str { const char *sval; int ival; }; struct termio_op_q { int op; int (*xlat)(struct sterm_data *, bool get, int *oval, int val); gensio_control_done cdone; void *cb_data; const struct termio_xlat_str *xlatstr; struct termio_op_q *next; }; struct modemstate_cb { struct modemstate_cb *next; gensio_control_done cdone; void *cb_data; }; struct sterm_data { struct gensio *io; struct gensio_os_funcs *o; struct gensio_lock *lock; struct gensio_timer *timer; bool timer_stopped; bool open; int drain_time; int char_drain_wait; int close_timeouts_left; int char_timeouts_left; gensiods last_close_outq_count; char *devname; char *parms; struct gensio_iod *iod; struct gensio_ll *ll; /* * Unfortunately, at least on Linux, ptys return EIO errors when * the remote end closes, instead of something sensible like * EPIPE, like all other IPC does. So we have to have special * handling to detect ptys. We still want to return GE_IOERR * on IO errors for real devices. */ bool is_pty; bool write_only; /* No read. */ bool read_only; /* No write. */ bool set_tty; /* No serial settings. */ bool uucp_lock; bool flock_lock; void *default_sercfg; int def_baud; int def_parity; int def_datasize; int def_stopbits; int def_xonxoff; int def_rtscts; int def_local; int def_hupcl; char *rs485; bool rts_first; /* Set RTS before DTR? */ bool rts_set; bool rts_val; bool dtr_set; bool dtr_val; bool deferred_op_pending; struct gensio_runner *deferred_op_runner; struct termio_op_q *termio_q; bool break_set; bool disablebreak; unsigned int last_modemstate; unsigned int modemstate_mask; bool handling_modemstate; bool sent_first_modemstate; struct modemstate_cb *modemstate_cbs; unsigned int linestate_mask; }; static int set_serdef_from_speed(struct gensio_pparm_info *p, struct sterm_data *sdata, int speed, const char *others) { sdata->def_baud = speed; if (*others) { switch (*others) { case 'N': case 'n': sdata->def_parity = GENSIO_SER_PARITY_NONE; break; case 'E': case 'e': sdata->def_parity = GENSIO_SER_PARITY_EVEN; break; case 'O': case 'o': sdata->def_parity = GENSIO_SER_PARITY_ODD; break; case 'M': case 'm': sdata->def_parity = GENSIO_SER_PARITY_MARK; break; case 'S': case 's': sdata->def_parity = GENSIO_SER_PARITY_SPACE; break; break; default: gensio_pparm_log(p, "Unknown parity: %s", others); return GE_INVAL; } others++; } if (*others) { switch (*others) { case '5': sdata->def_datasize = 5; break; case '6': sdata->def_datasize = 6; break; case '7': sdata->def_datasize = 7; break; case '8': sdata->def_datasize = 8; break; default: gensio_pparm_log(p, "Unknown number of bits: %s", others); return GE_INVAL; } others++; } if (*others) { switch (*others) { case '1': sdata->def_stopbits = 1; break; case '2': sdata->def_stopbits = 2; break; default: gensio_pparm_log(p, "Unknown number of stopbits: %s", others); return GE_INVAL; } others++; } if (*others) { gensio_pparm_log(p, "Extra data in serial spec: %s", others); return GE_INVAL; } return 0; } static void serconf_process(struct sterm_data *sdata); static void sterm_lock(struct sterm_data *sdata) { sdata->o->lock(sdata->lock); } static void sterm_unlock(struct sterm_data *sdata) { sdata->o->unlock(sdata->lock); } static void sterm_deferred_op(struct gensio_runner *runner, void *cbdata) { struct sterm_data *sdata = cbdata; sterm_lock(sdata); restart: serconf_process(sdata); if (sdata->termio_q) /* Something was added, process it. */ goto restart; sdata->deferred_op_pending = false; sterm_unlock(sdata); } static void sterm_start_deferred_op(struct sterm_data *sdata) { if (!sdata->deferred_op_pending) { sdata->deferred_op_pending = true; sdata->o->run(sdata->deferred_op_runner); } } static void serconf_call_cdone(struct sterm_data *sdata, struct termio_op_q *qe, int err, int val) { unsigned int i; const char *sval = NULL; char str[20]; if (!err) { if (qe->xlatstr) { for (i = 0; qe->xlatstr[i].sval; i++) { if (val == qe->xlatstr[i].ival) { sval = qe->xlatstr[i].sval; break; } } } if (!sval) { snprintf(str, sizeof(str), "%d", val); sval = str; } } qe->cdone(sdata->io, err, sval, sval ? strlen(sval): 0, qe->cb_data); } static void serconf_process(struct sterm_data *sdata) { while (sdata->termio_q) { struct termio_op_q *qe = sdata->termio_q; int val = 0, err; sdata->termio_q = qe->next; err = sdata->o->iod_control(sdata->iod, qe->op, true, (intptr_t) &val); if (!err && qe->xlat) err = qe->xlat(sdata, true, &val, val); sterm_unlock(sdata); if (qe->cdone) serconf_call_cdone(sdata, qe, err, val); sdata->o->free(sdata->o, qe); sterm_lock(sdata); } } static void serconf_clear_q(struct sterm_data *sdata) { while (sdata->termio_q) { struct termio_op_q *qe = sdata->termio_q; sdata->termio_q = qe->next; sdata->o->free(sdata->o, qe); } } static int serconf_set_get(struct sterm_data *sdata, int op, int val, const char *sval, int (*xlat)(struct sterm_data *sdata, bool get, int *oval, int val), gensio_control_done cdone, const struct termio_xlat_str *xlatstr, void *cb_data, void (*finish)(struct sterm_data *sdata, int val)) { struct termio_op_q *qe = NULL; int err = 0; if (!sdata->set_tty) return GE_NOTSUP; if (sval) { if (xlatstr) { unsigned int i; for (i = 0; xlatstr[i].sval; i++) { if (strcmp(sval, xlatstr[i].sval) == 0) { val = xlatstr[i].ival; goto found; } } return GE_INVAL; } else { val = strtol(sval, NULL, 0); } } found: if (cdone) { qe = sdata->o->zalloc(sdata->o, sizeof(*qe)); if (!qe) return GE_NOMEM; qe->xlat = xlat; qe->cdone = cdone; qe->xlatstr = xlatstr; qe->cb_data = cb_data; qe->op = op; qe->next = NULL; } sterm_lock(sdata); if (!sdata->open) { err = GE_NOTREADY; goto out_unlock; } if (val) { if (xlat) err = xlat(sdata, false, &val, val); if (err) goto out_unlock; err = sdata->o->iod_control(sdata->iod, op, false, val); if (err) goto out_unlock; err = sdata->o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_APPLY, false, 0); if (err) goto out_unlock; if (finish) finish(sdata, val); } if (qe) { if (!sdata->termio_q) { sdata->termio_q = qe; sterm_start_deferred_op(sdata); } else { struct termio_op_q *curr = sdata->termio_q; while (curr->next) curr = curr->next; curr->next = qe; } } out_unlock: if (err && qe) sdata->o->free(sdata->o, qe); sterm_unlock(sdata); return err; } static int sterm_baud(struct sterm_data *sdata, int baud, const char *sbaud, gensio_control_done cdone, void *cb_data) { return serconf_set_get(sdata, GENSIO_IOD_CONTROL_BAUD, baud, sbaud, NULL, cdone, NULL, cb_data, NULL); } static int sterm_datasize(struct sterm_data *sdata, int datasize, const char *sdatasize, gensio_control_done cdone, void *cb_data) { return serconf_set_get(sdata, GENSIO_IOD_CONTROL_DATASIZE, datasize, sdatasize, NULL, cdone, NULL, cb_data, NULL); } static const struct termio_xlat_str sterm_parity_xlatstr[] = { { "0", 0 }, { "", 0 }, { "none", GENSIO_SER_PARITY_NONE }, { "odd", GENSIO_SER_PARITY_ODD }, { "even", GENSIO_SER_PARITY_EVEN }, { "mark", GENSIO_SER_PARITY_MARK }, { "space", GENSIO_SER_PARITY_SPACE }, {} }; static int sterm_parity(struct sterm_data *sdata, int parity, const char *sparity, gensio_control_done cdone, void *cb_data) { return serconf_set_get(sdata, GENSIO_IOD_CONTROL_PARITY, parity, sparity, NULL, cdone, sterm_parity_xlatstr, cb_data, NULL); } static int sterm_stopbits(struct sterm_data *sdata, int stopbits, const char *sstopbits, gensio_control_done cdone, void *cb_data) { return serconf_set_get(sdata, GENSIO_IOD_CONTROL_STOPBITS, stopbits, sstopbits, NULL, cdone, NULL, cb_data, NULL); } static int serconf_xlat_flowcontrol(struct sterm_data *sdata, bool get, int *oval, int val) { int err; if (get) { if (val) { *oval = GENSIO_SER_FLOWCONTROL_RTS_CTS; } else { err = sdata->o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_XONXOFF, true, (intptr_t) &val); if (err) return err; if (val) *oval = GENSIO_SER_FLOWCONTROL_XON_XOFF; else *oval = GENSIO_SER_FLOWCONTROL_NONE; } } else { switch (val) { case GENSIO_SER_FLOWCONTROL_NONE: err = sdata->o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_XONXOFF, false, 0); if (err) return err; err = sdata->o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_IXONXOFF, false, 0); if (err) return err; *oval = 0; break; case GENSIO_SER_FLOWCONTROL_XON_XOFF: err = sdata->o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_XONXOFF, false, 1); if (err) return err; err = sdata->o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_IXONXOFF, false, 1); if (err) return err; *oval = 0; break; case GENSIO_SER_FLOWCONTROL_RTS_CTS: err = sdata->o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_XONXOFF, false, 0); if (err) return err; err = sdata->o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_IXONXOFF, false, 0); if (err) return err; *oval = 1; break; default: return GE_INVAL; } } return 0; } static const struct termio_xlat_str sterm_flow_xlatstr[] = { { "0", 0 }, { "", 0 }, { "none", GENSIO_SER_FLOWCONTROL_NONE }, { "xonxoff", GENSIO_SER_FLOWCONTROL_XON_XOFF }, { "rtscts", GENSIO_SER_FLOWCONTROL_RTS_CTS }, {} }; static int sterm_flowcontrol(struct sterm_data *sdata, int flowcontrol, const char *sflowcontrol, gensio_control_done cdone, void *cb_data) { const struct termio_xlat_str *xlatstr = sterm_flow_xlatstr; if (sflowcontrol) { unsigned int i; for (i = 0; xlatstr[i].sval; i++) { if (strcmp(sflowcontrol, xlatstr[i].sval) == 0) { flowcontrol = xlatstr[i].ival; goto found; } } return GE_INVAL; } found: switch (flowcontrol) { case GENSIO_SER_FLOWCONTROL_NONE: case GENSIO_SER_FLOWCONTROL_RTS_CTS: case GENSIO_SER_FLOWCONTROL_XON_XOFF: break; case 0: default: /* We only fetch in any other case. */ flowcontrol = 0; } return serconf_set_get(sdata, GENSIO_IOD_CONTROL_RTSCTS, flowcontrol, NULL, serconf_xlat_flowcontrol, cdone, xlatstr, cb_data, NULL); } static const struct termio_xlat_str sterm_iflow_xlatstr[] = { { "0", 0 }, { "", 0 }, { "none", GENSIO_SER_FLOWCONTROL_NONE }, { "dcd", GENSIO_SER_FLOWCONTROL_DCD }, { "dtr", GENSIO_SER_FLOWCONTROL_DTR }, { "dsr", GENSIO_SER_FLOWCONTROL_DSR }, {} }; static int sterm_iflowcontrol(struct sterm_data *sdata, int iflowcontrol, const char *siflowcontrol, gensio_control_done cdone, void *cb_data) { /* Input flow control is not independently settable. */ return serconf_set_get(sdata, GENSIO_IOD_CONTROL_XONXOFF, 0, siflowcontrol, serconf_xlat_flowcontrol, cdone, sterm_iflow_xlatstr, cb_data, NULL); } static const struct termio_xlat_str sterm_on_off_xlatstr[] = { { "0", 0 }, { "", 0 }, { "on", GENSIO_SER_ON }, { "off", GENSIO_SER_OFF }, {} }; static int sterm_xlat_sbreak(struct sterm_data *sdata, bool get, int *oval, int val) { if (get) { if (val) *oval = GENSIO_SER_ON; else *oval = GENSIO_SER_OFF; } else { switch (val) { case GENSIO_SER_OFF: *oval = 0; break; case GENSIO_SER_ON: *oval = 1; break; default: return GE_INVAL; } } return 0; } static int sterm_sbreak(struct sterm_data *sdata, int breakv, const char *sbreakv, gensio_control_done cdone, void *cb_data) { return serconf_set_get(sdata, GENSIO_IOD_CONTROL_SET_BREAK, breakv, sbreakv, sterm_xlat_sbreak, cdone, sterm_on_off_xlatstr, cb_data, NULL); } static int serconf_xlat_dtr(struct sterm_data *sdata, bool get, int *oval, int val) { if (get) { if (val) *oval = GENSIO_SER_ON; else *oval = GENSIO_SER_OFF; } else { switch (val) { case GENSIO_SER_OFF: *oval = 0; break; case GENSIO_SER_ON: *oval = 1; break; default: return GE_INVAL; } } return 0; } static int sterm_dtr(struct sterm_data *sdata, int dtr, const char *sdtr, gensio_control_done cdone, void *cb_data) { return serconf_set_get(sdata, GENSIO_IOD_CONTROL_DTR, dtr, sdtr, serconf_xlat_dtr, cdone, sterm_on_off_xlatstr, cb_data, NULL); } static int serconf_xlat_rts(struct sterm_data *sdata, bool get, int *oval, int val) { if (get) { if (val) *oval = GENSIO_SER_ON; else *oval = GENSIO_SER_OFF; } else { if (val == GENSIO_SER_ON) *oval = 1; else if (val == GENSIO_SER_OFF) *oval = 0; else return GE_INVAL; } return 0; } static int sterm_rts(struct sterm_data *sdata, int rts, const char *srts, gensio_control_done cdone, void *cb_data) { return serconf_set_get(sdata, GENSIO_IOD_CONTROL_RTS, rts, srts, serconf_xlat_rts, cdone, sterm_on_off_xlatstr, cb_data, NULL); } static void serialdev_timeout(struct gensio_timer *t, void *cb_data) { struct sterm_data *sdata = cb_data; int modemstate = 0, rv; bool force_send; struct modemstate_cb *c, *n; sterm_lock(sdata); if (sdata->handling_modemstate || !sdata->open) { sterm_unlock(sdata); return; } sdata->handling_modemstate = true; sterm_unlock(sdata); rv = sdata->o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_MODEMSTATE, true, (intptr_t) &modemstate); if (rv) goto out_restart; sterm_lock(sdata); /* Bits for things that changed. */ modemstate |= (modemstate ^ sdata->last_modemstate) >> 4; sdata->last_modemstate = modemstate & sdata->modemstate_mask; force_send = !sdata->sent_first_modemstate; sdata->sent_first_modemstate = true; c = sdata->modemstate_cbs; sdata->modemstate_cbs = NULL; sterm_unlock(sdata); /* Call any modemstate callback operations. */ while (c) { n = c->next; c->cdone(sdata->io, 0, NULL, 0, c->cb_data); sdata->o->free(sdata->o, c); c = n; } /* * The bottom 4 buts of modemstate is the "changed" bits, only * report this if someing changed that was in the mask. */ if ((force_send || modemstate & 0xf)) { gensiods vlen = sizeof(modemstate); gensio_cb(sdata->io, GENSIO_EVENT_SER_MODEMSTATE, 0, (unsigned char *) &modemstate, &vlen, NULL); } out_restart: if (sdata->modemstate_mask) { gensio_time timeout = {1, 0}; sdata->o->start_timer(sdata->timer, &timeout); } sterm_lock(sdata); sdata->handling_modemstate = false; sterm_unlock(sdata); } static int sterm_modemstate_mask(struct sterm_data *sdata, unsigned int val, const char *sval, gensio_control_done cdone, void *cb_data) { gensio_time timeout = {0, 0}; struct modemstate_cb *c, *n; if (sval) val = strtol(sval, NULL, 0); if (cdone) { n = sdata->o->zalloc(sdata->o, sizeof(*n)); if (!n) return GE_NOMEM; n->cdone = cdone; n->cb_data = cb_data; } sterm_lock(sdata); sdata->modemstate_mask = val; sdata->sent_first_modemstate = false; if (cdone) { if (!sdata->modemstate_cbs) { sdata->modemstate_cbs = n; } else { for (c = sdata->modemstate_cbs; c->next != NULL; c = c->next) ; c->next = n; } } sterm_unlock(sdata); /* Cause an immediate send of the modemstate. */ sdata->o->stop_timer(sdata->timer); sdata->o->start_timer(sdata->timer, &timeout); return 0; } static void sterm_finish_linestate(struct sterm_data *sdata, int val) { sdata->linestate_mask = val; } static int sterm_linestate_mask(struct sterm_data *sdata, unsigned int val, const char *sval, gensio_control_done cdone, void *cb_data) { if (sval) val = strtol(sval, NULL, 0); val &= GENSIO_SER_LINESTATE_PARITY_ERR | GENSIO_SER_LINESTATE_BREAK; return serconf_set_get(sdata, GENSIO_IOD_CONTROL_ENABLE_RECV_ERR, val, NULL, NULL, cdone, NULL, cb_data, sterm_finish_linestate); } static int sterm_flowcontrol_state(struct sterm_data *sdata, bool val, char *sval) { if (sval) { if (strcmp(sval, "true") == 0 || strcmp(sval, "on") == 0) val = true; else if (strcmp(sval, "false") == 0 || strcmp(sval, "off") == 0) val = false; else val = strtol(sval, NULL, 0); } return sdata->o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_FLOWCTL_STATE, false, val); } static int sterm_flush(struct sterm_data *sdata, unsigned int val, const char *sval) { struct gensio_os_funcs *o = sdata->o; int tval; if (sval) { if (strcmp(sval, "recv") == 0) val = 1; else if (strcmp(sval, "xmit") == 0) val = 2; else if (strcmp(sval, "both") == 0) val = 3; else return GE_INVAL; } switch(val) { case GENSIO_SER_FLUSH_RECV: tval = GENSIO_IN_BUF; break; case GENSIO_SER_FLUSH_XMIT: tval = GENSIO_OUT_BUF; break; case GENSIO_SER_FLUSH_BOTH: tval = GENSIO_IN_BUF | GENSIO_OUT_BUF; break; default: return GE_INVAL; } o->flush(sdata->iod, tval); return 0; } static int sterm_send_break(struct sterm_data *sdata) { return sdata->o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_SEND_BREAK, false, 0); } static int sterm_acontrol(void *handler_data, struct gensio_iod *iod, bool get, unsigned int option, struct gensio_func_acontrol *idata) { struct sterm_data *sdata = handler_data; const char *data = NULL; gensio_control_done done = idata->done; void *cb_data = idata->cb_data;; if (!sdata->set_tty) return GE_NOTSUP; if (!get) /* On a get, set val to 0 and data to NULL to fetch the value. */ data = idata->data; switch (option) { case GENSIO_ACONTROL_SER_BAUD: return sterm_baud(sdata, 0, data, done, cb_data); case GENSIO_ACONTROL_SER_DATASIZE: return sterm_datasize(sdata, 0, data, done, cb_data); case GENSIO_ACONTROL_SER_PARITY: return sterm_parity(sdata, 0, data, done, cb_data); case GENSIO_ACONTROL_SER_STOPBITS: return sterm_stopbits(sdata, 0, data, done, cb_data); case GENSIO_ACONTROL_SER_FLOWCONTROL: return sterm_flowcontrol(sdata, 0, data, done, cb_data); case GENSIO_ACONTROL_SER_IFLOWCONTROL: return sterm_iflowcontrol(sdata, 0, data, done, cb_data); case GENSIO_ACONTROL_SER_SBREAK: return sterm_sbreak(sdata, 0, data, done, cb_data); case GENSIO_ACONTROL_SER_DTR: return sterm_dtr(sdata, 0, data, done, cb_data); case GENSIO_ACONTROL_SER_RTS: return sterm_rts(sdata, 0, data, done, cb_data); case GENSIO_ACONTROL_SER_SET_MODEMSTATE_MASK: return sterm_modemstate_mask(sdata, 0, data, done, cb_data); case GENSIO_ACONTROL_SER_SET_LINESTATE_MASK: if (!sdata->o->read_flags) return GE_NOTSUP; return sterm_linestate_mask(sdata, 0, data, done, cb_data); default: return GE_NOTSUP; } } static void sterm_timer_stopped(struct gensio_timer *timer, void *cb_data) { struct sterm_data *sdata = cb_data; sdata->timer_stopped = true; } static int sterm_check_close_drain(void *handler_data, struct gensio_iod *iod, enum gensio_ll_close_state state, gensio_time *next_timeout) { struct sterm_data *sdata = handler_data; struct gensio_os_funcs *o = sdata->o; int rv, err = 0; gensiods count = 0; sterm_lock(sdata); if (state == GENSIO_LL_CLOSE_STATE_START) { sdata->open = false; rv = sdata->o->stop_timer_with_done(sdata->timer, sterm_timer_stopped, sdata); if (rv) sdata->timer_stopped = true; sdata->last_close_outq_count = 0; } if (state != GENSIO_LL_CLOSE_STATE_DONE) goto out_unlock; sdata->open = false; if (sdata->termio_q) goto out_einprogress; if (!sdata->timer_stopped) goto out_einprogress; if (sdata->handling_modemstate) goto out_einprogress; rv = o->bufcount(sdata->iod, GENSIO_OUT_BUF, &count); if (rv || count <= 0) goto out_rm_lock; if (sdata->last_close_outq_count == 0) /* First time through, set the total time. */ sdata->close_timeouts_left = sdata->drain_time; if (sdata->close_timeouts_left >= 0) { if (sdata->close_timeouts_left == 0) goto out_rm_lock; sdata->close_timeouts_left--; } if (sdata->last_close_outq_count == 0 || count < sdata->last_close_outq_count) { /* First time through or some data was written, restart the timer. */ sdata->last_close_outq_count = count; sdata->char_timeouts_left = sdata->char_drain_wait; } if (sdata->char_timeouts_left >= 0) { if (sdata->char_timeouts_left == 0) goto out_rm_lock; sdata->char_timeouts_left--; } out_einprogress: err = GE_INPROGRESS; next_timeout->secs = 0; next_timeout->nsecs = 10000000; out_rm_lock: if (!err) { o->flush(sdata->iod, GENSIO_OUT_BUF); serial_rm_lock(o, sdata->ll, sdata->uucp_lock, sdata->flock_lock, o->iod_get_fd(sdata->iod), sdata->devname); gensio_fd_ll_close_now(sdata->ll); } if (err != GE_INPROGRESS) /* We are really closing, the iod will be destroyed now. */ sdata->iod = NULL; out_unlock: sterm_unlock(sdata); return err; } #ifndef _WIN32 #include #endif static bool is_a_pty(const char *ttyname) { #ifdef _WIN32 return false; #else char buf[PATH_MAX]; memset(buf, 0, sizeof(buf)); while (readlink(ttyname, buf, sizeof(buf)) > 0) ttyname = buf; if (strncmp(ttyname, "/dev/pts/", 9) == 0) return true; /* * According to the Linux man page, BSD slave devices are named: * /dev/tty[p-za-e][0-9a-f] * so we have this check for them. */ if (strncmp(ttyname, "/dev/tty", 8) != 0) return false; return (((ttyname[8] >= 'a' && ttyname[8] <= 'e') || (ttyname[8] >= 'p' && ttyname[8] <= 'z')) && ((ttyname[9] >= '0' && ttyname[9] <= '9') || (ttyname[9] >= 'a' && ttyname[9] <= 'f'))); #endif } static int sterm_sub_open(void *handler_data, struct gensio_iod **riod, gensio_time *timeout) { struct sterm_data *sdata = handler_data; struct gensio_os_funcs *o = sdata->o; int err; int options = 0; sdata->timer_stopped = false; sdata->iod = NULL; /* If it's a re-open make sure this is clear. */ if (!sdata->read_only) options |= GENSIO_OPEN_OPTION_WRITEABLE; if (!sdata->write_only) options |= GENSIO_OPEN_OPTION_READABLE; if (sdata->set_tty) options |= GENSIO_OPEN_OPTION_SERIAL; err = o->open_dev(o, sdata->devname, options, &sdata->iod); if (err) goto out; err = serial_mk_lock(o, sdata->ll, sdata->uucp_lock, sdata->flock_lock, o->iod_get_fd(sdata->iod), sdata->devname); if (err) goto out; if (sdata->set_tty) { err = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_BAUD, false, sdata->def_baud); if (err) goto out_unlock; err = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_PARITY, false, sdata->def_parity); if (err) goto out_unlock; err = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_XONXOFF, false, sdata->def_xonxoff); if (err) goto out_unlock; err = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_IXONXOFF, false, sdata->def_xonxoff); if (err) goto out_unlock; err = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_RTSCTS, false, sdata->def_rtscts); if (err) goto out_unlock; err = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_DATASIZE, false, sdata->def_datasize); if (err) goto out_unlock; err = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_STOPBITS, false, sdata->def_stopbits); if (err) goto out_unlock; err = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_LOCAL, false, sdata->def_local); if (err) goto out_unlock; if (sdata->def_hupcl >= 0) { err = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_HANGUP_ON_DONE, false, sdata->def_hupcl); if (err) goto out_unlock; } if (sdata->rs485) { err = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_RS485, false, (intptr_t) sdata->rs485); if (err) goto out_unlock; } err = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_APPLY, false, 0); if (err) goto out_unlock; if (sdata->rts_set && sdata->rts_first) { err = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_RTS, false, sdata->rts_val); if (err) goto out_unlock; } if (sdata->dtr_set) { err = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_DTR, false, sdata->dtr_val); if (err) goto out_unlock; } if (sdata->rts_set && !sdata->rts_first) { err = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_RTS, false, sdata->rts_val); if (err) goto out_unlock; } } if (sdata->set_tty && !sdata->disablebreak) { err = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_SET_BREAK, false, sdata->disablebreak); if (err) gensio_ll_log(sdata->ll, GENSIO_LOG_WARNING, "serialdev: " "Setting break failed on %s, " "try adding the nobreak option: %s", sdata->devname, gensio_err_to_str(err)); /* * Do not fail on an error here. There are USB and bluetooth * devices that fail this because they don't implement it, but * it's impossible to tell beforehand that they will fail. * This shouldn't be able to fail on a working device, so just * log and allow it. */ } sterm_lock(sdata); sdata->open = true; sdata->sent_first_modemstate = false; sterm_unlock(sdata); if (sdata->set_tty) sterm_modemstate_mask(sdata, 255, NULL, NULL, NULL); *riod = sdata->iod; return 0; out_unlock: serial_rm_lock(o, sdata->ll, sdata->uucp_lock, sdata->flock_lock, o->iod_get_fd(sdata->iod), sdata->devname); /* pty's for some reason return EIO if the remote end closes. */ if (sdata->is_pty && err == GE_IOERR) err = GE_REMCLOSE; out: if (sdata->iod) { o->close(&sdata->iod); sdata->iod = NULL; } return err; } static void sterm_free(void *handler_data) { struct sterm_data *sdata = handler_data; struct modemstate_cb *c, *n; for (c = sdata->modemstate_cbs; c; c = n) { n = c->next; sdata->o->free(sdata->o, c); } serconf_clear_q(sdata); if (sdata->rs485) sdata->o->free(sdata->o, sdata->rs485); if (sdata->lock) sdata->o->free_lock(sdata->lock); if (sdata->timer) sdata->o->free_timer(sdata->timer); if (sdata->devname) sdata->o->free(sdata->o, sdata->devname); if (sdata->deferred_op_runner) sdata->o->free_runner(sdata->deferred_op_runner); sdata->o->free(sdata->o, sdata); } static int sterm_control_raddr(struct sterm_data *sdata, char *buf, gensiods *datalen) { struct gensio_os_funcs *o = sdata->o; int tval, rv; gensiods pos = 0, buflen = *datalen; gensio_pos_snprintf(buf, buflen, &pos, "%s", sdata->devname); if (sdata->set_tty) { int baud; int stopbits; int datasize; const char *parity; int xonxoff; int rtscts; int clocal; int hangup_when_done; char str[4]; if (!sdata->iod) { baud = sdata->def_baud; stopbits = sdata->def_stopbits; datasize = sdata->def_datasize; parity = parity_to_str(sdata->def_parity); xonxoff = sdata->def_xonxoff; rtscts = sdata->def_rtscts; clocal = sdata->def_local; hangup_when_done = sdata->def_hupcl; } else { rv = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_BAUD, true, (intptr_t) &baud); if (rv) return rv; rv = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_STOPBITS, true, (intptr_t) &stopbits); if (rv) return rv; rv = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_DATASIZE, true, (intptr_t) &datasize); if (rv) return rv; rv = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_PARITY, true, (intptr_t) &tval); if (rv) return rv; parity = parity_to_str(tval); rv = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_XONXOFF, true, (intptr_t) &xonxoff); if (rv) return rv; rv = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_RTSCTS, true, (intptr_t) &rtscts); if (rv) return rv; rv = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_LOCAL, true, (intptr_t) &clocal); if (rv) return rv; rv = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_HANGUP_ON_DONE, true, (intptr_t) &hangup_when_done); if (rv) return rv; } str[0] = parity[0]; str[1] = '0' + datasize; str[2] = '0' + stopbits; str[3] = '\0'; gensio_pos_snprintf(buf, buflen, &pos, ",%d%s", baud, str); if (xonxoff) gensio_pos_snprintf(buf, buflen, &pos, ",XONXOFF"); if (rtscts) gensio_pos_snprintf(buf, buflen, &pos, ",RTSCTS"); if (clocal) gensio_pos_snprintf(buf, buflen, &pos, ",CLOCAL"); if (hangup_when_done) gensio_pos_snprintf(buf, buflen, &pos, ",HANGUP_WHEN_DONE"); } if (sdata->set_tty && sdata->iod) { rv = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_RTS, true, (intptr_t) &tval); if (rv) return rv; if (tval) gensio_pos_snprintf(buf, buflen, &pos, " RTSHI"); else gensio_pos_snprintf(buf, buflen, &pos, " RTSLO"); rv = o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_DTR, true, (intptr_t) &tval); if (rv) return rv; if (tval) gensio_pos_snprintf(buf, buflen, &pos, " DTRHI"); else gensio_pos_snprintf(buf, buflen, &pos, " DTRLO"); } else { gensio_pos_snprintf(buf, buflen, &pos, " offline"); } *datalen = pos; return 0; } static int sterm_control(void *handler_data, struct gensio_iod *iod, bool get, unsigned int option, char *data, gensiods *datalen) { struct sterm_data *sdata = handler_data; switch (option) { case GENSIO_CONTROL_SEND_BREAK: if (get) return GE_NOTSUP; return sdata->o->iod_control(sdata->iod, GENSIO_IOD_CONTROL_SEND_BREAK, false, 0); case GENSIO_CONTROL_RADDR: if (!get) return GE_NOTSUP; if (strtoul(data, NULL, 0) > 0) return GE_NOTFOUND; return sterm_control_raddr(sdata, data, datalen); case GENSIO_CONTROL_REMOTE_ID: if (!get) return GE_NOTSUP; *datalen = snprintf(data, *datalen, "%d", sdata->o->iod_get_fd(sdata->iod)); return 0; case GENSIO_CONTROL_SER_MODEMSTATE: if (get) return GE_NOTSUP; return sterm_modemstate_mask(sdata, 0, data, NULL, NULL); case GENSIO_CONTROL_SER_LINESTATE: if (!sdata->o->read_flags) return GE_NOTSUP; if (get) return GE_NOTSUP; return sterm_linestate_mask(sdata, 0, data, NULL, NULL); case GENSIO_CONTROL_SER_FLOWCONTROL_STATE: if (get) return GE_NOTSUP; return sterm_flowcontrol_state(sdata, 0, data); case GENSIO_CONTROL_SER_FLUSH: if (get) return GE_NOTSUP; return sterm_flush(sdata, 0, data); case GENSIO_CONTROL_SER_SEND_BREAK: if (get) return GE_NOTSUP; return sterm_send_break(sdata); default: return GE_NOTSUP; } } static int sterm_write(void *handler_data, struct gensio_iod *iod, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { struct sterm_data *sdata = handler_data; int rv = sdata->o->write(iod, sg, sglen, rcount); if (rv && sdata->is_pty && rv == GE_IOERR) return GE_REMCLOSE; /* We don't seem to get EPIPE from ptys */ return rv; } static int sterm_do_read(struct gensio_iod *iod, void *data, gensiods datalen, gensiods *rcount, const char ***auxdata, void *cb_data) { struct sterm_data *sdata = cb_data; int rv; if (sdata->o->read_flags) { gensiods pcount = datalen / 2, count; rv = sdata->o->read_flags(iod, data, data + pcount, pcount, &count); if (!rv) { /* We put the flags into the second half of the data. */ memmove(data + count, data + pcount, count); if (rcount) *rcount = count * 2; } } else { rv = sdata->o->read(iod, data, datalen, rcount); } if (rv && sdata->is_pty && rv == GE_IOERR) return GE_REMCLOSE; /* We don't seem to get EPIPE from ptys */ return rv; } static void sterm_read_ready(void *handler_data, struct gensio_iod *iod) { struct sterm_data *sdata = handler_data; gensio_fd_ll_handle_incoming(sdata->ll, sterm_do_read, NULL, sdata); } static gensiods sterm_deliver_read(void *handler_data, void *cb_data, gensio_ll_cb cb, int err, void *data, gensiods datalen, const void *auxdata) { struct sterm_data *sdata = handler_data; gensiods total = 0; if (!err && sdata->o->read_flags) { gensiods i, start = 0, count, tosend, plen = datalen / 2; unsigned char *buf = data, *flags = buf + plen; for (i = 0; i < plen; i++) { if ((flags[i] & (GENSIO_IOD_READ_FLAGS_BREAK | GENSIO_IOD_READ_FLAGS_ERR)) != 0) { unsigned int linestate; gensiods vlen = sizeof(linestate); /* Send the data up to the point where the event is. */ tosend = i - start; if (tosend > 0) { count = cb(cb_data, GENSIO_LL_CB_READ, 0, buf + start, tosend, NULL); if (count > tosend) count = tosend; total += count; if (count < tosend) /* Not all the data got written, give up. */ break; } /* Now send the event. */ linestate = 0; if (flags[i] & GENSIO_IOD_READ_FLAGS_BREAK && sdata->linestate_mask & GENSIO_SER_LINESTATE_BREAK) linestate |= GENSIO_SER_LINESTATE_BREAK; if (flags[i] & GENSIO_IOD_READ_FLAGS_ERR && sdata->linestate_mask & GENSIO_SER_LINESTATE_PARITY_ERR) linestate |= GENSIO_SER_LINESTATE_PARITY_ERR; if (linestate) gensio_cb(sdata->io, GENSIO_EVENT_SER_LINESTATE, 0, (unsigned char *) &linestate, &vlen, NULL); /* Note we don't report the bad data. */ start = i + 1; total++; } } tosend = i - start; if (tosend > 0) { count = cb(cb_data, GENSIO_LL_CB_READ, 0, buf + start, tosend, NULL); if (count > tosend) count = tosend; total += count; } if (total < plen) /* * We didn't deliver all the data. We have removed total * bytes from the beginning of the data and flags, so we * must shift the buffer over because the first "total * 2" * data bytes are going to be considered removed. */ memmove(buf + total * 2, buf + total, plen - total); total *= 2; /* Convert it back to the full amount. */ } else { total = cb(cb_data, GENSIO_LL_CB_READ, err, data, datalen, auxdata); } return total; } static const struct gensio_fd_ll_ops sterm_fd_ll_ops = { .sub_open = sterm_sub_open, .check_close = sterm_check_close_drain, .free = sterm_free, .write = sterm_write, .read_ready = sterm_read_ready, .control = sterm_control, .acontrol = sterm_acontrol, .deliver_read = sterm_deliver_read }; static int handle_speedstr(struct gensio_pparm_info *p, bool logerr, struct sterm_data *sdata, const char *str) { int val, rv; const char *rest = ""; val = speedstr_to_speed(p, logerr, str, &rest); if (val < 10) /* Some parameters start a digit, ignore them. */ return GE_INVAL; rv = set_serdef_from_speed(p, sdata, val, rest); if (rv) return rv; return 0; } static int process_defserial_parm(struct gensio_pparm_info *p, struct sterm_data *sdata, const char *parm) { int rv = 0, val; const char *str; bool bval; if (gensio_pparm_value(p, parm, "speed", &str) > 0) { rv = handle_speedstr(p, true, sdata, str); } else if (handle_speedstr(p, false, sdata, parm) == 0) { ; } else if (gensio_pparm_bool(p, parm, "xonxoff", &bval) > 0) { sdata->def_xonxoff = bval; } else if (gensio_pparm_bool(p, parm, "rtscts", &bval) > 0) { sdata->def_rtscts = bval; } else if (gensio_pparm_bool(p, parm, "local", &bval) > 0) { sdata->def_local = bval; } else if (gensio_pparm_bool(p, parm, "hangup-when-done", &bval) > 0) { sdata->def_hupcl = bval; } else if (gensio_pparm_bool(p, parm, "dtr", &bval) > 0) { sdata->dtr_set = true; sdata->dtr_val = bval; } else if (gensio_pparm_bool(p, parm, "rts", &bval) > 0) { if (!sdata->dtr_set) sdata->rts_first = true; sdata->rts_set = true; sdata->rts_val = bval; /* Everything below is deprecated. */ } else if (strcasecmp(parm, "1STOPBIT") == 0) { sdata->def_stopbits = 1; } else if (strcasecmp(parm, "2STOPBITS") == 0) { sdata->def_stopbits = 2; } else if (strcasecmp(parm, "5DATABITS") == 0) { sdata->def_datasize = 5; } else if (strcasecmp(parm, "6DATABITS") == 0) { sdata->def_datasize = 6; } else if (strcasecmp(parm, "7DATABITS") == 0) { sdata->def_datasize = 7; } else if (strcasecmp(parm, "8DATABITS") == 0) { sdata->def_datasize = 8; } else if ((val = lookup_parity_str(parm)) != -1) { sdata->def_parity = val; } else if (strcasecmp(parm, "-XONXOFF") == 0) { sdata->def_xonxoff = 0; } else if (strcasecmp(parm, "-RTSCTS") == 0) { sdata->def_rtscts = 0; } else if (strcasecmp(parm, "-LOCAL") == 0) { sdata->def_local = 0; } else if (strcasecmp(parm, "HANGUP_WHEN_DONE") == 0) { sdata->def_hupcl = 1; } else if (strcasecmp(parm, "-HANGUP_WHEN_DONE") == 0) { sdata->def_hupcl = 0; } else { gensio_pparm_unknown_parm(p, parm); rv = GE_INVAL; } return rv; } static int sergensio_process_parms(struct gensio_pparm_info *p, struct sterm_data *sdata) { int argc, i; const char **argv; int err = gensio_str_to_argv(sdata->o, sdata->parms, &argc, &argv, " \f\t\n\r\v,"); const char *str; if (err) { gensio_pparm_log(p, "Invalid parameters," "likely unterminated string in '%s'", sdata->parms); return err; } for (i = 0; i < argc; i++) { if (gensio_pparm_bool(p, argv[i], "wronly", &sdata->write_only) > 0) { /* In the later parms, wronly sets both write only and set_tty. */ sdata->set_tty = !sdata->write_only; continue; } else if (gensio_pparm_bool(p, argv[i], "nobreak", &sdata->disablebreak) > 0) { continue; } else if (gensio_pparm_value(p, argv[i], "rs485", &str) > 0) { if (sdata->rs485) sdata->o->free(sdata->o, sdata->rs485); sdata->rs485 = gensio_strdup(sdata->o, str); if (!sdata->rs485) { err = GE_NOMEM; break; } continue; /* The following is deprecated. */ } else if (strcasecmp(argv[i], "-NOBREAK") == 0) { sdata->disablebreak = false; continue; } err = process_defserial_parm(p, sdata, argv[i]); if (err) break; } gensio_argv_free(sdata->o, argv); return err; } static int sergensio_setup_defaults(struct gensio_pparm_info *p, struct sterm_data *sdata) { struct gensio_os_funcs *o = sdata->o; int val, err; char *str; err = gensio_get_default(o, "serialdev", "speed", false, GENSIO_DEFAULT_STR, &str, NULL); if (err) { gensio_log(o, GENSIO_LOG_ERR, "Failed getting default serialdev speed:" " %s", gensio_err_to_str(err)); return err; } if (str) { if (handle_speedstr(p, false, sdata, str)) { gensio_log(o, GENSIO_LOG_ERR, "Default speed settings (%s) are invalid," " defaulting to 9600N81", str); sdata->def_baud = 9600; sdata->def_parity = GENSIO_SER_PARITY_NONE; sdata->def_datasize = 8; sdata->def_stopbits = 1; } o->free(o, str); } val = 0; err = gensio_get_default(o, "serialdev", "xonxoff", false, GENSIO_DEFAULT_BOOL, NULL, &val); if (err) return err; sdata->def_xonxoff = val; val = 0; err = gensio_get_default(o, "serialdev", "rtscts", false, GENSIO_DEFAULT_BOOL, NULL, &val); if (err) return err; sdata->def_rtscts = val; val = 0; err = gensio_get_default(o, "serialdev", "local", false, GENSIO_DEFAULT_BOOL, NULL, &val); if (err) return err; sdata->def_local = val; val = 0; err = gensio_get_default(o, "serialdev", "hangup-when-done", false, GENSIO_DEFAULT_INT, NULL, &val); if (err) return err; sdata->def_hupcl = val; err = gensio_get_default(o, "serialdev", "rs485", false, GENSIO_DEFAULT_STR, &str, NULL); if (err) { gensio_log(o, GENSIO_LOG_ERR, "Failed getting default serialdev rs485:" " %s", gensio_err_to_str(err)); return err; } sdata->rs485 = str; return 0; } static int iodev_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, bool set_tty, gensio_event cb, void *user_data, struct gensio **rio) { const char *devname = gdata; struct sterm_data *sdata = o->zalloc(o, sizeof(*sdata)); int err; char *comma; gensiods max_read_size = GENSIO_DEFAULT_BUF_SIZE; int i, ival; bool lock_set = false, dummy = false, wronly = false, rdonly = false; const char *s; char *end; GENSIO_DECLARE_PPGENSIO(p, o, cb, "serialdev", user_data); if (!sdata) return GE_NOMEM; sdata->o = o; if (!set_tty) { sdata->uucp_lock = false; sdata->flock_lock = false; } else { err = gensio_get_default(o, "sergensio", "uucplock", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (err) goto out_err; sdata->uucp_lock = ival; err = gensio_get_default(o, "sergensio", "flock", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (err) goto out_err; sdata->flock_lock = ival; } err = gensio_get_default(o, "sergensio", "drain_time", false, GENSIO_DEFAULT_INT, NULL, &sdata->drain_time); if (err) goto out_err; err = gensio_get_default(o, "sergensio", "char_drain_wait", false, GENSIO_DEFAULT_INT, NULL, &sdata->char_drain_wait); if (err) goto out_err; for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(&p, args[i], "readbuf", &max_read_size) > 0) continue; if (gensio_pparm_bool(&p, args[i], "wronly", &wronly) > 0) continue; if (gensio_pparm_bool(&p, args[i], "rdonly", &rdonly) > 0) continue; if (gensio_pparm_value(&p, args[i], "drain_time", &s) > 0) { if (strcmp(s, "off") == 0) { sdata->drain_time = -1; } else { sdata->drain_time = strtol(s, &end, 0); if (*end != '\0') goto out_inval; } continue; } if (gensio_pparm_value(&p, args[i], "char_drain_wait", &s) > 0) { if (strcmp(s, "off") == 0) { sdata->char_drain_wait = -1; } else { sdata->char_drain_wait = strtol(s, &end, 0); if (*end != '\0') goto out_inval; } continue; } if (set_tty && gensio_pparm_bool(&p, args[i], "nouucplock", &sdata->uucp_lock) > 0) { sdata->uucp_lock = !sdata->uucp_lock; lock_set = true; continue; } if (set_tty && gensio_pparm_bool(&p, args[i], "uucplock", &sdata->uucp_lock) > 0) { lock_set = true; continue; } if (set_tty && gensio_pparm_bool(&p, args[i], "flock", &sdata->flock_lock) > 0) { lock_set = true; continue; } /* custspeed is ignored now */ if (gensio_pparm_bool(&p, args[i], "custspeed", &dummy) > 0) continue; out_inval: gensio_pparm_unknown_parm(&p, args[i]); err = GE_INVAL; goto out_err; } if (wronly && rdonly) { gensio_pparm_slog(&p, "You cannot set both wronly and rdonly"); err = GE_INVAL; goto out_err; } sdata->timer = o->alloc_timer(o, serialdev_timeout, sdata); if (!sdata->timer) goto out_nomem; sdata->devname = gensio_strdup(o, devname); if (!sdata->devname) goto out_nomem; sdata->is_pty = is_a_pty(sdata->devname); sdata->write_only = wronly; sdata->read_only = rdonly; sdata->set_tty = set_tty; comma = strchr(sdata->devname, ','); if (comma) *comma++ = '\0'; if (set_tty && !lock_set) { const char *slash = strrchr(devname, '/'); /* * If the user didn't force it, don't do locking if the * devname is "tty", as in "/dev/tty". That does all sorts * of bad things... */ if (slash) slash++; else slash = devname; /* Don't do uucp locking on /dev/tty or ptys. flock is on on ptys */ sdata->uucp_lock = !(strcmp(slash, "tty") == 0 || sdata->is_pty); sdata->flock_lock = !(strcmp(slash, "tty") == 0); } if (set_tty) { err = sergensio_setup_defaults(&p, sdata); if (err) goto out_err; if (comma) { sdata->parms = comma; err = sergensio_process_parms(&p, sdata); if (err) goto out_err; } } else if (comma) { gensio_pparm_slog(&p, "Serial port options not accepted for 'dev' gensios"); err = GE_INVAL; goto out_err; } sdata->deferred_op_runner = o->alloc_runner(o, sterm_deferred_op, sdata); if (!sdata->deferred_op_runner) goto out_nomem; sdata->lock = o->alloc_lock(o); if (!sdata->lock) goto out_nomem; /* * For the flags field to work, the buffer size must double sized, * flags are held in the second half of the buffer. */ if (o->read_flags) max_read_size *= 2; sdata->ll = fd_gensio_ll_alloc(o, NULL, &sterm_fd_ll_ops, sdata, max_read_size, sdata->write_only, sdata->read_only); if (!sdata->ll) goto out_nomem; /* * After this point, freeing the ll or io will free sdata through * the free callbacks. */ sdata->io = base_gensio_alloc(o, sdata->ll, NULL, NULL, "serialdev", cb, user_data); if (!sdata->io) { gensio_ll_free(sdata->ll); return GE_NOMEM; } gensio_set_is_serial(sdata->io, true); *rio = sdata->io; return 0; out_nomem: err = GE_NOMEM; out_err: sterm_free(sdata); return err; } static int serialdev_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **rio) { return iodev_gensio_alloc(gdata, args, o, true, cb, user_data, rio); } static int str_to_serialdev_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { return serialdev_gensio_alloc(str, args, o, cb, user_data, new_gensio); } static int dev_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **rio) { return iodev_gensio_alloc(gdata, args, o, false, cb, user_data, rio); } static int str_to_dev_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { return dev_gensio_alloc(str, args, o, cb, user_data, new_gensio); } int gensio_init_serialdev(struct gensio_os_funcs *o) { int rv; rv = register_gensio(o, "serialdev", str_to_serialdev_gensio, serialdev_gensio_alloc); if (rv) return rv; rv = register_gensio(o, "sdev", str_to_serialdev_gensio, serialdev_gensio_alloc); if (rv) return rv; rv = register_gensio(o, "dev", str_to_dev_gensio, dev_gensio_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/mdns.c0000664000175000017500000025464614752425772010374 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2020 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #if HAVE_MDNS #include #include #ifdef _WIN32 #include #include #include #else #include #include #include #ifdef __MSYS__ typedef struct in6_addr IN6_ADDR; #include #endif #endif #include #include #include #if HAVE_AVAHI #include #include #include #include #include "avahi_watcher.h" #elif HAVE_DNSSD #include #elif HAVE_WINMDNS #include #include #endif /* Returns true on failure (error) */ static bool dupstr(struct gensio_os_funcs *o, const char *src, char **dest) { if (src) { char *ret = gensio_strdup(o, src); if (!ret) return true; *dest = ret; } return false; } struct gensio_mdns_service; struct gensio_mdns { struct gensio_os_funcs *o; struct gensio_list services; struct gensio_list watches; #if HAVE_AVAHI AvahiPoll *ap; AvahiClient *ac; AvahiClientState state; #elif HAVE_DNSSD DNSServiceRef dnssd_sref; struct gensio_iod *iod; int dnssd_fd; #endif #if HAVE_DNSSD || HAVE_WINMDNS struct gensio_lock *lock; #endif unsigned int refcount; bool freed; gensio_mdns_done free_done; void *free_userdata; bool runner_pending; struct gensio_runner *runner; struct gensio_list callbacks; }; static void gensio_mdns_vlog(struct gensio_mdns *m, enum gensio_log_levels l, char *fmt, va_list ap) { gensio_vlog(m->o, l, fmt, ap); } static void gensio_mdns_log(struct gensio_mdns *m, enum gensio_log_levels l, char *fmt, ...) { va_list ap; va_start(ap, fmt); gensio_mdns_vlog(m, l, fmt, ap); va_end(ap); } struct mdns_str_data { void (*cleanup)(struct gensio_os_funcs *, struct mdns_str_data *); bool (*cmp)(struct mdns_str_data *, const char *str); void *extdata; }; /* Returns true if compare string is NULL or if the strings compare. */ static bool mdns_rawstr_cmp(struct mdns_str_data *sdata, const char *str) { if (!sdata->extdata) return true; return strcmp(str, sdata->extdata) == 0; } static void mdns_rawstr_cleanup(struct gensio_os_funcs *o, struct mdns_str_data *sdata) { if (sdata->extdata) o->free(o, sdata->extdata); } #if defined(HAVE_REGEXEC) || defined(HAVE_PCRE_POSIX) #include #ifdef HAVE_PCRE_POSIX #include #else #include #endif static void regex_str_cleanup(struct gensio_os_funcs *o, struct mdns_str_data *sdata) { regfree(sdata->extdata); o->free(o, sdata->extdata); } static bool regex_str_cmp(struct mdns_str_data *sdata, const char *str) { return regexec(sdata->extdata, str, 0, NULL, 0) == 0; } static int regex_str_setup(struct gensio_mdns *m, const char *str1, struct mdns_str_data *sdata) { struct gensio_os_funcs *o = m->o; int rv; sdata->extdata = o->zalloc(o, sizeof(regex_t)); if (!sdata->extdata) return GE_NOMEM; rv = regcomp(sdata->extdata, str1 + 1, REG_NOSUB); if (rv) { char errbuf[200]; regerror(rv, sdata->extdata, errbuf, sizeof(errbuf)); gensio_mdns_log(m, GENSIO_LOG_ERR, "mdns: regex error: %s", errbuf); regfree(sdata->extdata); o->free(o, sdata->extdata); sdata->extdata = NULL; if (rv == REG_ESPACE) return GE_NOMEM; return GE_INVAL; } sdata->cmp = regex_str_cmp; sdata->cleanup = regex_str_cleanup; return 0; } #else static int regex_str_setup(struct gensio_mdns *m, const char *str1, struct mdns_str_data *sdata) { gensio_mdns_log(m, GENSIO_LOG_ERR, "mdns: regex not supported"); return GE_NOTSUP; } #endif #ifdef HAVE_FNMATCH #include static void glob_str_cleanup(struct gensio_os_funcs *o, struct mdns_str_data *sdata) { o->free(o, sdata->extdata); } static bool glob_str_cmp(struct mdns_str_data *sdata, const char *str) { return fnmatch(sdata->extdata, str, 0) == 0; } static int glob_str_setup(struct gensio_mdns *m, const char *str1, struct mdns_str_data *sdata) { struct gensio_os_funcs *o = m->o; sdata->extdata = gensio_strdup(o, str1 + 1); if (!sdata->extdata) return GE_NOMEM; sdata->cmp = glob_str_cmp; sdata->cleanup = glob_str_cleanup; return 0; } #else static int glob_str_setup(struct gensio_mdns *m, const char *str1, struct mdns_str_data *sdata) { gensio_mdns_log(m, GENSIO_LOG_ERR, "mdns: glob not supported"); return GE_NOTSUP; } #endif static int mdns_str_setup(struct gensio_mdns *m, const char *str1, struct mdns_str_data *sdata) { struct gensio_os_funcs *o = m->o; if (str1 && str1[0] == '%') return regex_str_setup(m, str1, sdata); if (str1 && str1[0] == '@') return glob_str_setup(m, str1, sdata); if (str1 && str1[0] == '=') str1++; if (str1) { sdata->extdata = gensio_strdup(o, str1); if (!sdata->extdata) return GE_NOMEM; } else { sdata->extdata = NULL; } sdata->cmp = mdns_rawstr_cmp; sdata->cleanup = mdns_rawstr_cleanup; return 0; } static bool mdns_str_cmp(struct mdns_str_data *sdata, const char *str) { return sdata->cmp(sdata, str); } static void mdns_str_cleanup(struct gensio_os_funcs *o, struct mdns_str_data *sdata) { if (sdata->cleanup) sdata->cleanup(o, sdata); } static void gensio_mdns_finish_free(struct gensio_mdns *m) { struct gensio_os_funcs *o = m->o; if (m->free_done) m->free_done(m, m->free_userdata); if (m->runner) o->free_runner(m->runner); o->free(o, m); } #if HAVE_AVAHI static int protocol_to_avahi_protocol(int protocol, AvahiProtocol *aprotocol) { switch(protocol) { case GENSIO_NETTYPE_IPV4: *aprotocol = AVAHI_PROTO_INET; break; case GENSIO_NETTYPE_IPV6: *aprotocol = AVAHI_PROTO_INET6; break; case GENSIO_NETTYPE_UNSPEC: *aprotocol = AVAHI_PROTO_UNSPEC; break; default: return GE_INVAL; } return 0; } static int avahi_protocol_to_protocol(AvahiProtocol aprotocol, int *protocol) { switch(aprotocol) { case AVAHI_PROTO_UNSPEC: *protocol = GENSIO_NETTYPE_UNSPEC; return 0; case AVAHI_PROTO_INET: *protocol = GENSIO_NETTYPE_IPV4; return 0; #ifdef AF_INET6 case AVAHI_PROTO_INET6: *protocol = GENSIO_NETTYPE_IPV6; return 0; #endif default: return GE_INVAL; } } static AvahiIfIndex interface_to_avahi_interface(int ifinterface) { if (ifinterface == -1) return AVAHI_IF_UNSPEC; return ifinterface; } static int avahi_interface_to_interface(AvahiIfIndex ainterface) { return ainterface; } static void gensio_mdns_lock(struct gensio_mdns *m) { gensio_avahi_lock(m->ap); } static void gensio_mdns_unlock(struct gensio_mdns *m) { gensio_avahi_unlock(m->ap); } static void avahi_finish_free(AvahiPoll *ap, void *userdata) { struct gensio_mdns *m = userdata; /* Make sure everything is out of the lock. */ gensio_mdns_lock(m); gensio_mdns_unlock(m); gensio_mdns_finish_free(m); } static int gensio_mdnslib_init(struct gensio_mdns *m) { m->ap = alloc_gensio_avahi_poll(m->o); if (!m->ap) return GE_NOMEM; return 0; } static void gensio_mdnslib_free(struct gensio_mdns *m) { if (m->ac) { /* We are fully initialized */ avahi_client_free(m->ac); gensio_avahi_poll_free(m->ap, avahi_finish_free, m); } else { gensio_avahi_poll_free(m->ap, NULL, NULL); gensio_mdns_finish_free(m); } } #elif HAVE_DNSSD static int i_dnssd_err_to_err(struct gensio_mdns *m, DNSServiceErrorType derr, int lineno) { int err; switch (derr) { case kDNSServiceErr_Unknown: err = GE_OSERR; break; case kDNSServiceErr_NoSuchName: err = GE_NOTFOUND; break; case kDNSServiceErr_NoMemory: err = GE_NOMEM; break; case kDNSServiceErr_BadParam: err = GE_INVAL; break; case kDNSServiceErr_BadReference: err = GE_OSERR; break; case kDNSServiceErr_BadState: err = GE_INCONSISTENT; break; case kDNSServiceErr_BadFlags: err = GE_INVAL; break; case kDNSServiceErr_Unsupported: err = GE_NOTSUP; break; case kDNSServiceErr_NotInitialized: err = GE_NOTREADY; break; case kDNSServiceErr_AlreadyRegistered: err = GE_INUSE; break; case kDNSServiceErr_NameConflict: err = GE_EXISTS; break; case kDNSServiceErr_Invalid: err = GE_INVAL; break; case kDNSServiceErr_Firewall: err = GE_OSERR; break; case kDNSServiceErr_Incompatible: err = GE_INCONSISTENT; break; case kDNSServiceErr_BadInterfaceIndex: err = GE_INVAL; break; case kDNSServiceErr_Refused: err = GE_CONNREFUSE; break; case kDNSServiceErr_NoSuchRecord: err = GE_NOTFOUND; break; case kDNSServiceErr_NoAuth: err = GE_AUTHREJECT; break; case kDNSServiceErr_NoSuchKey: err = GE_KEYINVALID; break; case kDNSServiceErr_NATTraversal: err = GE_OSERR; break; case kDNSServiceErr_DoubleNAT: err = GE_OSERR; break; case kDNSServiceErr_BadTime: err = GE_INVAL; break; case kDNSServiceErr_BadSig: err = GE_CERTINVALID; break; case kDNSServiceErr_BadKey: err = GE_KEYINVALID; break; case kDNSServiceErr_Transient: err = GE_OSERR; break; case kDNSServiceErr_ServiceNotRunning: err = GE_NOTREADY; break; case kDNSServiceErr_NATPortMappingUnsupported: err = GE_OSERR; break; case kDNSServiceErr_NATPortMappingDisabled: err = GE_OSERR; break; case kDNSServiceErr_NoRouter: err = GE_OSERR; break; case kDNSServiceErr_PollingMode: err = GE_OSERR; break; case kDNSServiceErr_Timeout: err = GE_TIMEDOUT; break; case kDNSServiceErr_DefunctConnection: err = GE_OSERR; break; case kDNSServiceErr_PolicyDenied: err = GE_OSERR; break; #ifdef kDNSServiceErr_NotPermitted case kDNSServiceErr_NotPermitted: err = GE_PERM; break; #endif default: err = GE_OSERR; } /* FIXME - DNSSD doesn't provide a string translation. */ if (err == GE_OSERR) { gensio_mdns_log(m, GENSIO_LOG_ERR, "DNSSD error on line %d: %d", lineno, derr); } return err; } #define dnssd_err_to_err(m, err) i_dnssd_err_to_err(m, err, __LINE__) static int interface_to_dnssd_interface(int ifinterface, uint32_t *sinterface) { /* * FIXME - is this right? interface 0 is always localhost, so you * don't run mdns on that, so that's why zero is use as all * interfaces? */ if (ifinterface == 0) return GE_INVAL; if (ifinterface < 0) { *sinterface = 0; return 0; } *sinterface = ifinterface; return 0; } static int dnssd_interface_to_interface(uint32_t sinterface) { return sinterface; } static int protocol_to_dnssd_protocol(int protocol, DNSServiceProtocol *sprotocol) { switch (protocol) { case GENSIO_NETTYPE_UNSPEC: *sprotocol = kDNSServiceProtocol_IPv4 | kDNSServiceProtocol_IPv6; break; case GENSIO_NETTYPE_IPV4: *sprotocol = kDNSServiceProtocol_IPv4; break; case GENSIO_NETTYPE_IPV6: *sprotocol = kDNSServiceProtocol_IPv6; break; default: return GE_INVAL; } return 0; } /* * dnssd strings end in a '.', but the gensio ones don't. Compensate. */ static char * dnssd_str_fix(struct gensio_os_funcs *o, const char *str) { gensiods len; if (!str) return NULL; len = strlen(str); if (len < 2) return NULL; return gensio_strndup(o, str, len - 1); } #endif #if HAVE_DNSSD || HAVE_WINMDNS static int gensio_mdnslib_init(struct gensio_mdns *m) { m->lock = m->o->alloc_lock(m->o); if (!m->lock) return GE_NOMEM; return 0; } static void gensio_mdnslib_free(struct gensio_mdns *m) { m->o->free_lock(m->lock); gensio_mdns_finish_free(m); } static void gensio_mdns_lock(struct gensio_mdns *m) { m->o->lock(m->lock); } static void gensio_mdns_unlock(struct gensio_mdns *m) { m->o->unlock(m->lock); } #endif static void gensio_mdns_ref(struct gensio_mdns *m) { m->refcount++; } static void gensio_mdns_deref(struct gensio_mdns *m) { /* Can't use this for the final deref. */ assert(m->refcount > 1); m->refcount--; } static void gensio_mdns_deref_and_unlock(struct gensio_mdns *m) { assert(m->refcount > 0); m->refcount--; if (m->refcount == 0) { gensio_mdns_unlock(m); gensio_mdnslib_free(m); return; } gensio_mdns_unlock(m); } struct gensio_mdns_callback { struct gensio_link link; bool in_queue; bool remove; /* Remove the watch/service. */ bool namechange; /* Service name changed. */ /* * Report that no more watch data is pending or that a service has * finished. */ bool all_for_now; struct gensio_mdns_watch *w; struct gensio_mdns_service *s; struct gensio_mdns_watch_data *data; }; static void enqueue_callback(struct gensio_mdns *m, struct gensio_mdns_callback *c) { if (c->remove) return; if (!c->in_queue) { gensio_list_add_tail(&m->callbacks, &c->link); c->in_queue = true; gensio_mdns_ref(m); } if (!m->runner_pending) { m->runner_pending = true; gensio_mdns_ref(m); m->o->run(m->runner); } } /* * Service Advertising * * Code following deals with advertising services on the network. * It's pretty simple, in all libraries you just call a function with * the right parameters and it advertises. It gives you a handle to * cancel the operation. */ #if HAVE_WINMDNS struct gensio_mdns_req_info { bool is_dereg; struct gensio_mdns_service *s; }; #endif struct gensio_mdns_service { struct gensio_link link; struct gensio_mdns *m; char *name; char *type; char *domain; char *host; int port; bool removed; gensio_mdns_service_cb cb; void *cb_data; struct gensio_mdns_callback cbdata; bool reported; #if HAVE_AVAHI AvahiIfIndex avahi_interface; AvahiProtocol avahi_protocol; AvahiStringList *txt; AvahiEntryGroup *group; #elif HAVE_DNSSD uint32_t dnssd_interface; DNSServiceProtocol dnssd_protocol; char *dnssd_txt; uint32_t dnssd_txtlen; bool dnssd_started; DNSServiceRef dnssd_sref; #elif HAVE_WINMDNS int win_interface; int win_protocol; wchar_t **win_keys; wchar_t **win_values; unsigned int win_kvcount; wchar_t *win_host; wchar_t *win_name; DNS_SERVICE_REGISTER_REQUEST req; DNS_SERVICE_REGISTER_REQUEST dereq; struct gensio_mdns_req_info reginfo; struct gensio_mdns_req_info dereginfo; DNS_SERVICE_INSTANCE inst; DNS_SERVICE_CANCEL cancel; #endif /* Used to handle name collisions. */ unsigned int nameseq; gensio_cntstr *currname; }; static void gensio_mdnslib_add_service(struct gensio_mdns_service *s); #if HAVE_AVAHI /* Lock should already be held when calling this. */ static void avahi_group_callback(AvahiEntryGroup *group, AvahiEntryGroupState state, void *userdata) { struct gensio_mdns_service *s = userdata; struct gensio_mdns *m = s->m; struct gensio_os_funcs *o = m->o; if (state == AVAHI_ENTRY_GROUP_COLLISION) { gensio_cntstr *newname; int err; s->nameseq++; err = gensio_cntstr_sprintf(o, &newname, "%s(%u)", s->name, s->nameseq); if (err) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Out of memory in group collision: %s", gensio_err_to_str(err)); goto done; } gensio_cntstr_free(o, s->currname); s->currname = newname; gensio_mdns_log(m, GENSIO_LOG_WARNING, "service %s renamed to %s", s->name, gensio_cntstr_get(s->currname)); gensio_mdnslib_add_service(s); s->cbdata.namechange = true; enqueue_callback(m, &s->cbdata); } /* FIXME - handle other states. */ done: if (!s->reported) { s->reported = true; enqueue_callback(m, &s->cbdata); } } /* Must be called with the Avahi poll lock held. */ static void gensio_mdnslib_add_service(struct gensio_mdns_service *s) { struct gensio_mdns *m = s->m; struct gensio_os_funcs *o = m->o;; int err; if (m->state != AVAHI_CLIENT_S_RUNNING) /* We'll catch it later. */ return; if (!s->group) s->group = avahi_entry_group_new(m->ac, avahi_group_callback, s); if (!s->group) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Out of memory adding a service"); return; } retry: err = avahi_entry_group_add_service_strlst(s->group, s->avahi_interface, s->avahi_protocol, 0, gensio_cntstr_get(s->currname), s->type, s->domain, s->host, s->port, s->txt); if (err == AVAHI_ERR_COLLISION) { gensio_cntstr *newname; s->nameseq++; err = gensio_cntstr_sprintf(o, &newname, "%s(%u)", s->name, s->nameseq); if (err) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Error allocating service strings: %s", gensio_err_to_str(err)); return; } gensio_cntstr_free(o, s->currname); s->currname = newname; goto retry; } else if (err) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Error adding service strings: %s", avahi_strerror(err), err); return; } err = avahi_entry_group_commit(s->group); if (err) gensio_mdns_log(m, GENSIO_LOG_ERR, "Error committing service entry: %s", avahi_strerror(err)); } static int gensio_mdnslib_initservice(struct gensio_mdns_service *s, int ipdomain, int ifinterface, const char * const *txt) { int err; err = protocol_to_avahi_protocol(ipdomain, &s->avahi_protocol); if (err) return err; if (ifinterface < 0) s->avahi_interface = AVAHI_IF_UNSPEC; else s->avahi_interface = ifinterface; if (txt && txt[0]) { s->txt = avahi_string_list_new_from_array((const char **) txt, -1); if (!s->txt) return GE_NOMEM; } return 0; } /* Must be called with the Avahi poll lock held. */ static void gensio_mdnslib_free_service(struct gensio_os_funcs *o, struct gensio_mdns_service *s) { if (s->group) avahi_entry_group_free(s->group); if (s->txt) avahi_string_list_free(s->txt); } static void gensio_mdnslib_remove_service(struct gensio_mdns_service *s) { enqueue_callback(s->m, &s->cbdata); s->cbdata.remove = true; } #elif HAVE_DNSSD static void dnssd_service_done(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, void *context) { struct gensio_mdns_service *s = context; struct gensio_mdns *m = s->m; if (errorCode) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Error from service registration: %d", errorCode); return; } if (strcmp(name, gensio_cntstr_get(s->currname)) != 0) { gensio_cntstr *newname; int err; gensio_mdns_log(m, GENSIO_LOG_WARNING, "service %s renamed to %s", s->name, name); err = gensio_cntstr_make(m->o, name, &newname); if (err) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Allocation error in group collision: %s", gensio_err_to_str(err)); goto done; } gensio_cntstr_free(m->o, s->currname); s->currname = newname; s->cbdata.namechange = true; enqueue_callback(m, &s->cbdata); } done: if (!s->reported) { s->reported = true; enqueue_callback(m, &s->cbdata); } } static void gensio_mdnslib_add_service(struct gensio_mdns_service *s) { struct gensio_mdns *m = s->m; DNSServiceErrorType derr; s->dnssd_sref = m->dnssd_sref; derr = DNSServiceRegister(&s->dnssd_sref, kDNSServiceFlagsShareConnection, s->dnssd_interface, s->name, s->type, s->domain, s->host, htons(s->port), s->dnssd_txtlen, s->dnssd_txt, dnssd_service_done, s); if (derr) gensio_mdns_log(m, GENSIO_LOG_ERR, "Error registering service: %d", derr); } static int gensio_mdnslib_initservice(struct gensio_mdns_service *s, int ipdomain, int ifinterface, const char * const *txt) { struct gensio_mdns *m = s->m; int err; err = interface_to_dnssd_interface(ifinterface, &s->dnssd_interface); if (err) return err; err = protocol_to_dnssd_protocol(ipdomain, &s->dnssd_protocol); if (err) return err; if (txt && txt[0]) { unsigned int i, len = 0, p; char *dtxt; for (i = 0; txt[i]; i++) len += strlen(txt[i]) + 1; if (len > 65535) return GE_INVAL; dtxt = m->o->zalloc(m->o, len); if (!dtxt) return GE_NOMEM; for (len = 0, i = 0; txt[i]; i++) { p = strlen(txt[i]); dtxt[len++] = p; memcpy(dtxt + len, txt[i], p); len += p; } s->dnssd_txt = dtxt; s->dnssd_txtlen = len; } return 0; } static void gensio_mdnslib_free_service(struct gensio_os_funcs *o, struct gensio_mdns_service *s) { if (s->dnssd_started) DNSServiceRefDeallocate(s->dnssd_sref); if (s->dnssd_txt) o->free(o, s->dnssd_txt); } static void gensio_mdnslib_remove_service(struct gensio_mdns_service *s) { enqueue_callback(s->m, &s->cbdata); s->cbdata.remove = true; } #elif HAVE_WINMDNS /* * It is completely unclear from the Windows documentation how to use * DNSServiceBrowse(). It seemed at first that you had to add every * individual IP address. Then I experimented with just adding one IP * address for an interface, and it didn't make any difference. * Setting both IP addresses to NULL didn't make any difference. * * No matter what, all the IP addresses for an interface are added * with a single registration. I have no idea if the IfIndex field * works, I don't have a system with two IP interfaces. * * There is also no way to set the protocol field for registering a * service. All the IP addresses are added no matter what. * * Also, if you cancel with DNSServiceBrowseCancel, you don't get * another callback saying the cancel is complete. So it may be racy * and there may be nothing that can be done about it. I can't tell * if the cancel waits until it is out of the callback, there is no * documentation about how any of this works. * * When the browser callback is called, it is called each time with * all known IP addresses. So you have to scan that list and check * for removals. Again, completely undocumented. * * So it works like Avahi and DNSSD work, sort of. */ static int str_to_wchar(struct gensio_os_funcs *o, const char *s, wchar_t **rws) { size_t len; wchar_t *ws; len = mbstowcs(NULL, s, 0); if (len == (size_t) -1) return GE_INVAL; len++; ws = o->zalloc(o, len * sizeof(wchar_t)); if (!ws) return GE_NOMEM; mbstowcs(ws, s, len); *rws = ws; return 0; } static int str_to_wcharn(struct gensio_os_funcs *o, const char *is, gensiods n, wchar_t **rws) { size_t len; wchar_t *ws; char *s = gensio_strndup(o, is, n); if (!s) return GE_NOMEM; len = mbstowcs(NULL, s, 0); if (len == (size_t) -1) { o->free(o, s); return GE_INVAL; } len++; ws = o->zalloc(o, len * sizeof(wchar_t)); if (!ws) { o->free(o, s); return GE_NOMEM; } mbstowcs(ws, s, len); o->free(o, s); *rws = ws; return 0; } static int wchar_to_str(struct gensio_os_funcs *o, const wchar_t *ws, char **rs) { size_t len; char *s; len = wcstombs(NULL, ws, 0); if (len == (size_t) -1) return GE_INVAL; len++; s = o->zalloc(o, len); if (!s) return GE_NOMEM; wcstombs(s, ws, len); *rs = s; return 0; } static int wstring_array_to_argv(struct gensio_os_funcs *o, gensiods len, wchar_t **wstrs, const char ***rstrs) { const char **strs = NULL; char *s; gensiods args = 0, argc = 0; int err = 0; unsigned int i; for (i = 0; i < len; i++) { err = wchar_to_str(o, wstrs[i], &s); if (err) goto out_err; err = gensio_argv_append(o, &strs, s, &args, &argc, false); if (err) { o->free(o, s); goto out_err; } } err = gensio_argv_append(o, &strs, NULL, &args, &argc, false); if (err) goto out_err; *rstrs = strs; return 0; out_err: if (strs) gensio_argv_free(o, strs); return err; } static void WINAPI win_serv_done(DWORD Status, void *context, DNS_SERVICE_INSTANCE *inst) { struct gensio_mdns_req_info *reginfo = context; struct gensio_mdns_service *s = reginfo->s; struct gensio_mdns *m = s->m; struct gensio_os_funcs *o = m->o; int err; gensio_mdns_lock(m); if (reginfo->is_dereg) { enqueue_callback(s->m, &s->cbdata); s->cbdata.remove = true; goto out_done; } else if (Status == ERROR_CANCELLED) { /* Nothing to do here, on a cancellation we will get a dereg after. */ goto out_done; } else if (Status != ERROR_SUCCESS) { err = gensio_os_err_to_err(m->o, Status); gensio_mdns_log(m, GENSIO_LOG_ERR, "Error from service register callback: %s", gensio_err_to_str(err)); } else if (inst) { char *name = NULL, *dot; err = wchar_to_str(o, inst->pszInstanceName, &name); if (err) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Error allocating winserv string: %s", gensio_err_to_str(err)); goto out_free; } dot = strrchr(name, '.'); if (!dot || dot == name) goto out_invalid_name; *dot = '\0'; dot = strrchr(name, '.'); if (!dot || dot == name) goto out_invalid_name; *dot = '\0'; dot = strrchr(name, '.'); if (!dot || dot == name) goto out_invalid_name; *dot = '\0'; if (strcmp(name, gensio_cntstr_get(s->currname)) != 0) { gensio_cntstr *newname; err = gensio_cntstr_make(o, name, &newname); if (err) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Error allocating winserv cntstr: %s", gensio_err_to_str(err)); goto out_free; } gensio_cntstr_free(o, s->currname); s->currname = newname; s->cbdata.namechange = true; if (s->reported) enqueue_callback(m, &s->cbdata); } goto out_free; out_invalid_name: gensio_mdns_log(m, GENSIO_LOG_ERR, "Invalid mdns name in winserv callback: %ls", inst->pszInstanceName); out_free: if (name) o->free(o, name); } if (!s->reported) { s->reported = true; enqueue_callback(m, &s->cbdata); } out_done: if (inst) DnsServiceFreeInstance(inst); gensio_mdns_unlock(m); } static void gensio_mdnslib_add_service(struct gensio_mdns_service *s) { struct gensio_os_funcs *o = s->m->o; DWORD rv; int err; s->req.Version = DNS_QUERY_REQUEST_VERSION1; s->req.InterfaceIndex = s->win_interface; s->req.pServiceInstance = &s->inst; s->req.pRegisterCompletionCallback = win_serv_done; s->req.unicastEnabled = false; s->dereq = s->req; s->inst.pszInstanceName = s->win_name; s->inst.pszHostName = s->win_host; s->inst.wPort = s->port; s->inst.wPriority = 0; s->inst.wWeight = 0; s->inst.dwPropertyCount = s->win_kvcount; s->inst.keys = s->win_keys; s->inst.values = s->win_values; s->reginfo.is_dereg = false; s->reginfo.s = s; s->dereginfo.is_dereg = true; s->dereginfo.s = s; s->req.pQueryContext = &s->reginfo; s->dereq.pQueryContext = &s->dereginfo; rv = DnsServiceRegister(&s->req, &s->cancel); if (rv != DNS_REQUEST_PENDING) { err = gensio_os_err_to_err(o, rv); goto out_err; } return; out_err: gensio_mdns_log(s->m, GENSIO_LOG_ERR, "Error registering service: %s", gensio_err_to_str(err)); } static int gensio_mdnslib_initservice(struct gensio_mdns_service *s, int ipdomain, int ifinterface, const char * const *txt) { struct gensio_os_funcs *o = s->m->o; unsigned int i, kvcount = 0; wchar_t **keys = NULL, **values = NULL; char *domain = s->domain, *tmps, *chost; char hostname[256]; wchar_t *name = NULL, *host = NULL; int err = 0; if (ifinterface == 0) return GE_INVAL; s->win_protocol = ipdomain; if (ifinterface == -1) s->win_interface = 0; else s->win_interface = ifinterface; if (!domain) domain = "local"; if (s->host) { chost = s->host; } else { if (gethostname(hostname, sizeof(hostname)) != 0) { err = GE_NOTFOUND; goto out_err; } chost = hostname; } /* You have to construct full names for this to work. */ tmps = gensio_alloc_sprintf(o, "%s.%s", chost, domain); if (!tmps) goto out_nomem; err = str_to_wchar(o, tmps, &host); o->free(o, tmps); if (err) goto out_err; tmps = gensio_alloc_sprintf(o, "%s.%s.%s", s->name, s->type, domain); if (!tmps) goto out_nomem; err = str_to_wchar(o, tmps, &name); o->free(o, tmps); if (err) goto out_err; if (txt && txt[0]) { for (kvcount = 0; txt[kvcount]; kvcount++) ; keys = o->zalloc(o, kvcount * sizeof(*keys)); if (!keys) goto out_nomem; values = o->zalloc(o, kvcount * sizeof(*values)); if (!values) goto out_nomem; for (i = 0; i < kvcount; i++) { char *vp = strchr(txt[i], '='); if (!vp) goto out_inval; err = str_to_wcharn(o, txt[i], vp - txt[i], &(keys[i])); if (err) goto out_err; err = str_to_wchar(o, vp + 1, &(values[i])); if (err) goto out_err; } s->win_keys = keys; s->win_values = values; s->win_kvcount = kvcount; } s->win_name = name; s->win_host = host; return 0; out_nomem: err = GE_NOMEM; goto out_err; out_inval: err = GE_INVAL; out_err: if (name) o->free(o, name); if (host) o->free(o, host); if (keys) { for (i = 0; i < kvcount; i++) { if (keys[i]) o->free(o, keys[i]); } } if (values) { for (i = 0; i < kvcount; i++) { if (values[i]) o->free(o, values[i]); } } return err; } static void gensio_mdnslib_free_service(struct gensio_os_funcs *o, struct gensio_mdns_service *s) { wchar_t **keys = s->win_keys, **values = s->win_values; unsigned int i, kvcount = s->win_kvcount; if (keys) { for (i = 0; i < kvcount; i++) { if (keys[i]) o->free(o, keys[i]); } o->free(o, keys); } if (values) { for (i = 0; i < kvcount; i++) { if (values[i]) o->free(o, values[i]); } o->free(o, values); } if (s->win_name) o->free(o, s->win_name); if (s->win_host) o->free(o, s->win_host); } static void gensio_mdnslib_remove_service(struct gensio_mdns_service *s) { DWORD rv; /* * Cancelling the service on Windows is unfortunately complicated, * but that seems to be the Windows way. If the registration * report is not already done, then we cancel it first. The * cancel, is unfortunately, synchronous, so we must release the * lock, but that should be safe here, and we are waiting on a * non-blocking callback so that's not going to be an issue. * * There is a race here, we can still call cancel if the * registration is just being called, but that's ok, as the cancel * will return success and just not do anything. * * After that, we deregister. If the service has been cancelled, * the registration callback will get called with an error, but it * still gets called, and that's all that matters. */ if (!s->reported) { /* * For some reason the cancel waits for the callback to be * called, so we can't hold the lock here. */ gensio_mdns_unlock(s->m); rv = DnsServiceRegisterCancel(&s->cancel); gensio_mdns_lock(s->m); if (rv != ERROR_SUCCESS) { int err = gensio_os_err_to_err(s->m->o, rv); gensio_mdns_log(s->m, GENSIO_LOG_ERR, "Error cancelling mdns service registration: %s", gensio_err_to_str(err)); } } rv = DnsServiceDeRegister(&s->dereq, NULL); if (rv != DNS_REQUEST_PENDING) { int err = gensio_os_err_to_err(s->m->o, rv); gensio_mdns_log(s->m, GENSIO_LOG_ERR, "Error deregistering mdns service registration: %s", gensio_err_to_str(err)); enqueue_callback(s->m, &s->cbdata); s->cbdata.remove = true; } } #endif /* HAVE_AVAHI */ static void free_service(struct gensio_os_funcs *o, struct gensio_mdns_service *s) { struct gensio_mdns *m = s->m; if (s->link.list) gensio_list_rm(&m->services, &s->link); gensio_mdnslib_free_service(o, s); if (s->currname) gensio_cntstr_free(o, s->currname); if (s->name) o->free(o, s->name); if (s->type) o->free(o, s->type); if (s->domain) o->free(o, s->domain); if (s->host) o->free(o, s->host); o->free(o, s); gensio_mdns_deref(m); } static int i_gensio_mdns_remove_service(struct gensio_mdns_service *s) { s->removed = true; gensio_mdnslib_remove_service(s); return 0; } int gensio_mdns_remove_service(struct gensio_mdns_service *s) { struct gensio_mdns *m = s->m; int err; gensio_mdns_lock(m); err = i_gensio_mdns_remove_service(s); gensio_mdns_unlock(m); return err; } int gensio_mdns_add_service2(struct gensio_mdns *m, int ifinterface, int ipdomain, const char *name, const char *type, const char *domain, const char *host, int port, const char * const *txt, gensio_mdns_service_cb cb, void *cb_data, struct gensio_mdns_service **rservice) { struct gensio_os_funcs *o = m->o; struct gensio_mdns_service *s; int err = GE_NOMEM; if (!name || !type) return GE_INVAL; s = o->zalloc(m->o, sizeof(*s)); if (!s) return GE_NOMEM; s->m = m; gensio_mdns_ref(m); s->port = port; s->name = gensio_strdup(o, name); if (!s->name) goto out_err; s->type = gensio_strdup(o, type); if (!s->type) goto out_err; if (dupstr(o, domain, &s->domain)) goto out_err; if (dupstr(o, host, &s->host)) goto out_err; err = gensio_cntstr_make(o, s->name, &s->currname); if (err) goto out_err; s->cb = cb; s->cb_data = cb_data; s->cbdata.s = s; err = gensio_mdnslib_initservice(s, ipdomain, ifinterface, txt); if (err) goto out_err; gensio_mdns_lock(m); gensio_list_add_tail(&m->services, &s->link); gensio_mdnslib_add_service(s); gensio_mdns_unlock(m); if (rservice) *rservice = s; return 0; out_err: gensio_mdns_lock(m); free_service(o, s); gensio_mdns_deref_and_unlock(m); return err; } int gensio_mdns_add_service(struct gensio_mdns *m, int ifinterface, int ipdomain, const char *name, const char *type, const char *domain, const char *host, int port, const char * const *txt, struct gensio_mdns_service **rservice) { return gensio_mdns_add_service2(m, ifinterface, ipdomain, name, type, domain, host, port, txt, NULL, NULL, rservice); } /* * MDNS lookups * * This code is pretty complicated. For both Avahi and DNS-SD, there * is a three-stage process to get the results of a lookup. * * For Avahi, the first stage is to add a watch with the parameters * you want, which is an gensio_mdns_watch type. This is done with * avahi_service_type_new(). The callback from that will have a MDNS * type. Then a gensio_mdns_watch_browser is allocated for that type * and avahi_service_browser_new() is called with the new type. It's * callback will be called with a name for each service of that type. * It then calls the mdns_browser_callback() common to all libraries, * which will allocate a gensio_mdns_watch_resolver type for final * resolution. In there that name is then resolved with * avahi_service_resolver_new(), which is called for each address for * the name, which has all the informaion for that service. * * DNS-SD is similar but different. A watch is added as Avahi, with * DNSServiceBrowse(). That function, however, must have a type * supplied and it only reports names of that type. There is no way * that I can find to browse for types. So the first stack callback, * which uses the gensio_mdns_watch_browser type, has the name we are * looking for. That callback then calls DNSServiceResolve() whose * callback reports a port and a hostname, but no addresses. That * callback will call mdns_browser_callback(), which allocates a * resolver (with the port) and call DNSServiceGetAddrInfo() to * convert resolve the individual addresses. The callbacks for that * will hvae the addresses we want, and those are reported to the * user. * * There are four tiers of data structures: * * gensio_mdns_watch - created by gensio_mdns_add_watch(), the main * watch structure. * * gensio_mdns_watch_browser - created by * avahi_service_type_callback() and dnssd_watch_callback(), * callbacks from the main watdh. A list of these is kept in * gensio_mdns_watch. * * gensio_mdns_watch_resolver - created by mdns_browser_callback(), * which is called from avahi_service_browser_callback() and * dnssd_service_callback(), callbacks from the watch browser * callback. A list of these is kept in * gensio_mdns_watch_browser. * * gensio_mdns_result - Holds the final results of the callbacks, * one for each IP address from the query. Created in * mdns_resolver_callback(). * * Windows works differently than Avahi and DNSMD, it actually works * more like the interface to this library. There's one callback with * information. However, to make it more compatible with this code, * it builds the whole type/browser structure artificially. */ struct gensio_mdns_result; struct gensio_mdns_watch_data { struct gensio_mdns_result *result; enum gensio_mdns_data_state state; int ifinterface; int ipdomain; char *name; char *type; char *domain; char *host; struct gensio_addr *addr; const char **txt; }; static void gensio_mdns_free_watch_data(struct gensio_os_funcs *o, struct gensio_mdns_watch_data *d) { if (d->name) o->free(o, d->name); if (d->type) o->free(o, d->type); if (d->domain) o->free(o, d->domain); if (d->host) o->free(o, d->host); if (d->addr) gensio_addr_free(d->addr); if (d->txt) gensio_argv_free(o, d->txt); o->free(o, d); } struct gensio_mdns_watch_resolver; struct gensio_mdns_result { struct gensio_link link; struct gensio_mdns_watch_resolver *resolver; struct gensio_mdns_callback cbdata; bool found; uint16_t port; }; static void result_free(struct gensio_os_funcs *o, struct gensio_mdns_result *e) { if (e->cbdata.data) gensio_mdns_free_watch_data(o, e->cbdata.data); o->free(o, e); } struct gensio_mdns_watch_resolver { struct gensio_link link; struct gensio_mdns_watch_browser *b; int ifinterface; int protocol; uint16_t port; /* Not used for avahi. */ char *host; char *name; char *type; char *domain; const char **txt; /* Not used for avahi. */ #if HAVE_AVAHI AvahiServiceResolver *avahi_resolver; #endif #if HAVE_DNSSD DNSServiceRef dnssd_sref; #endif struct gensio_list results; }; #if HAVE_WINMDNS static struct gensio_mdns_result * result_find(struct gensio_mdns_watch_resolver *r, int ifinterface, int protocol, const char *name, const char *type, const char *domain, const char *host, struct gensio_addr *addr, uint16_t port) { struct gensio_mdns_result *e = NULL; struct gensio_link *l; gensio_list_for_each(&r->results, l) { e = gensio_container_of(l, struct gensio_mdns_result, link); if (e->cbdata.data->ifinterface == ifinterface && e->cbdata.data->ipdomain == protocol && gensio_addr_equal(e->cbdata.data->addr, addr, false, false) && strcmp(e->cbdata.data->host, host) == 0 && strcmp(e->cbdata.data->name, name) == 0 && strcmp(e->cbdata.data->type, type) == 0 && strcmp(e->cbdata.data->domain, domain) == 0) break; else e = NULL; } return e; } #endif static void result_remove(struct gensio_mdns *m, struct gensio_mdns_watch_resolver *r, struct gensio_mdns_result *e) { gensio_list_rm(&r->results, &e->link); if (e->cbdata.in_queue) { if (e->cbdata.data->state == GENSIO_MDNS_WATCH_NEW_DATA) { /* In queue but not reported, just remove it. */ gensio_list_rm(&m->callbacks, &e->cbdata.link); gensio_mdns_deref(m); result_free(m->o, e); } /* Otherwise already scheduled for removal. */ } else { /* Report removal */ e->cbdata.data->state = GENSIO_MDNS_WATCH_DATA_GONE; enqueue_callback(m, &e->cbdata); } } struct gensio_mdns_watch { struct gensio_link link; struct gensio_mdns *m; struct mdns_str_data name; struct mdns_str_data type; struct mdns_str_data domain; int ifinterface; int protocol; char *domainstr; /* Need this to kick things off. */ char *typestr; struct mdns_str_data host; #if HAVE_AVAHI AvahiServiceTypeBrowser *avahi_browser; #elif HAVE_DNSSD DNSServiceRef dnssd_sref; #elif HAVE_WINMDNS DNS_SERVICE_CANCEL winmdns_cancel; #endif bool removed; unsigned int service_calls_pending; gensio_mdns_watch_cb cb; void *userdata; struct gensio_mdns_callback callback_data; gensio_mdns_watch_done remove_done; void *remove_done_data; struct gensio_list browsers; }; static void mdns_resolver_callback(struct gensio_mdns_watch_resolver *r, struct gensio_mdns_watch *w, enum gensio_mdns_data_state state, int ifinterface, int protocol, const char *name, const char *type, const char *domain, const char *host, struct gensio_addr *addr, uint16_t port, const char **txt) { struct gensio_mdns *m = w->m; struct gensio_mdns_callback *c = NULL; struct gensio_os_funcs *o = m->o; struct gensio_mdns_result *e; if (!mdns_str_cmp(&w->host, host)) goto out_nomem; if (!mdns_str_cmp(&w->name, name)) goto out_nomem; if (!mdns_str_cmp(&w->domain, domain)) goto out_nomem; if (!mdns_str_cmp(&w->type, type)) goto out_nomem; e = o->zalloc(o, sizeof(*e)); if (!e) goto out_nomem; e->resolver = r; e->port = port; e->found = true; c = &e->cbdata; c->w = w; c->data = o->zalloc(o, sizeof(*(c->data))); if (!c->data) goto out_nomem; c->data->result = e; c->data->state = state; c->data->ifinterface = ifinterface; c->data->ipdomain = protocol; c->data->addr = addr; addr = NULL; c->data->txt = txt; txt = NULL; if (dupstr(o, name, &c->data->name)) goto out_nomem; if (dupstr(o, type, &c->data->type)) goto out_nomem; if (dupstr(o, domain, &c->data->domain)) goto out_nomem; if (dupstr(o, host, &c->data->host)) goto out_nomem; gensio_list_add_tail(&r->results, &e->link); enqueue_callback(m, c); return; out_nomem: if (addr) gensio_addr_free(addr); if (txt) gensio_argv_free(o, txt); if (c && c->data) gensio_mdns_free_watch_data(o, c->data); } struct gensio_mdns_watch_browser { struct gensio_link link; struct gensio_mdns_watch *w; int ifinterface; int protocol; char *name; /* Not used for avahi. */ char *type; char *domain; #if HAVE_AVAHI AvahiServiceBrowser *avahi_browser; #endif #if HAVE_DNSSD DNSServiceRef dnssd_sref; #endif struct gensio_list resolvers; }; static void browser_finish_one(struct gensio_mdns_watch *w); #if HAVE_AVAHI static void gensio_mdnslib_reset_finish_one(struct gensio_mdns_watch *w) { } static void gensio_mdnslib_resolver_free(struct gensio_os_funcs *o, struct gensio_mdns_watch_resolver *r) { if (r->avahi_resolver) avahi_service_resolver_free(r->avahi_resolver); } /* Will be called with the lock held. */ static void avahi_service_resolver_callback(AvahiServiceResolver *ar, AvahiIfIndex ainterface, AvahiProtocol aprotocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host, const AvahiAddress *a, uint16_t port, AvahiStringList *atxt, AvahiLookupResultFlags flags, void *userdata) { struct gensio_mdns_watch_resolver *r = userdata; struct gensio_mdns_watch_browser *b = r->b; struct gensio_mdns_watch *w = b->w; struct gensio_mdns *m = w->m; struct gensio_os_funcs *o = m->o; struct gensio_addr *addr; int nettype, addrsize, rv, ifinterface; const void *addrdata = NULL; const char **txt = NULL; enum gensio_mdns_data_state state; #ifdef AF_INET6 struct sockaddr_in6 s6 = { .sin6_family = AF_INET6 }; #endif ifinterface = avahi_interface_to_interface(ainterface); switch (event) { case AVAHI_RESOLVER_FOUND: state = GENSIO_MDNS_NEW_DATA; break; case AVAHI_RESOLVER_FAILURE: gensio_mdns_log(m, GENSIO_LOG_ERR, "Error from resolver: %s", avahi_strerror(avahi_client_errno(m->ac))); default: return; } switch(a->proto) { case AVAHI_PROTO_INET: nettype = GENSIO_NETTYPE_IPV4; addrsize = sizeof(a->data.ipv4); addrdata = &a->data.ipv4; break; #ifdef AF_INET6 case AVAHI_PROTO_INET6: nettype = GENSIO_NETTYPE_IPV6; addrsize = sizeof(s6); addrdata = &s6; memcpy(&s6.sin6_addr, &a->data.ipv6, sizeof(s6.sin6_addr)); if (IN6_IS_ADDR_LINKLOCAL(&s6.sin6_addr)) s6.sin6_scope_id = ifinterface; /* Port is not used here. */ break; #endif default: return; } if (gensio_addr_create(o, nettype, addrdata, addrsize, port, &addr)) return; if (atxt) { gensiods args = 0, argc = 0; AvahiStringList *str; for (str = atxt; str; str = str->next) { rv = gensio_argv_append(o, &txt, (char *) str->text, &args, &argc, true); if (rv) goto out; } rv = gensio_argv_append(o, &txt, NULL, &args, &argc, false); if (rv) goto out; } mdns_resolver_callback(r, w, state, ifinterface, nettype, name, type, domain, host, addr, port, txt); return; out: if (addr) gensio_addr_free(addr); if (txt) gensio_argv_free(o, txt); } static void gensio_mdnslib_browser_free(struct gensio_os_funcs *o, struct gensio_mdns_watch_browser *b) { if (b->avahi_browser) avahi_service_browser_free(b->avahi_browser); } static int gensio_mdnslib_start_resolver(struct gensio_mdns *m, struct gensio_mdns_watch_resolver *r, int ifinterface, int iprotocol, const char *host, const char *type, const char *domain, int iaprotocol) { int err; AvahiProtocol protocol; AvahiProtocol aprotocol; err = protocol_to_avahi_protocol(iprotocol, &protocol); if (err) return err; err = protocol_to_avahi_protocol(iaprotocol, &aprotocol); if (err) return err; r->avahi_resolver = avahi_service_resolver_new(m->ac, ifinterface, protocol, host, type, domain, aprotocol, 0, avahi_service_resolver_callback, r); if (!r->avahi_resolver) return GE_NOMEM; return 0; } #elif HAVE_DNSSD static void gensio_mdnslib_reset_finish_one(struct gensio_mdns_watch *w) { /* We don't have to count these like avahi, just set it so it will finish */ w->service_calls_pending = 1; } static void gensio_mdnslib_resolver_free(struct gensio_os_funcs *o, struct gensio_mdns_watch_resolver *r) { DNSServiceRefDeallocate(r->dnssd_sref); } static void gensio_mdnslib_browser_free(struct gensio_os_funcs *o, struct gensio_mdns_watch_browser *b) { DNSServiceRefDeallocate(b->dnssd_sref); } static void dnssd_resolve_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *hostname, const struct sockaddr *address, uint32_t ttl, void *context) { struct gensio_mdns_watch_resolver *r = context; struct gensio_mdns_watch_browser *b = r->b; struct gensio_mdns_watch *w = b->w; struct gensio_mdns *m = w->m; struct gensio_os_funcs *o = m->o; struct gensio_addr *addr = NULL; int nettype, rv, ifinterface; enum gensio_mdns_data_state state; char *host = NULL; const char **txt = NULL; if (errorCode) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Error from resolver: %d", errorCode); return; } ifinterface = dnssd_interface_to_interface(interfaceIndex); switch (address->sa_family) { case AF_INET: { struct sockaddr_in *addr4 = (struct sockaddr_in *) address; rv = gensio_addr_create(o, GENSIO_NETTYPE_IPV4, &addr4->sin_addr, sizeof(struct in_addr), r->port, &addr); nettype = GENSIO_NETTYPE_IPV4; break; } case AF_INET6: { struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) address; rv = gensio_addr_create(o, GENSIO_NETTYPE_IPV6, &addr6->sin6_addr, sizeof(struct in6_addr), r->port, &addr); nettype = GENSIO_NETTYPE_IPV6; break; } default: gensio_mdns_log(m, GENSIO_LOG_ERR, "Unknown address type from resolver: %d", address->sa_family); goto out; } if (rv) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Error allocating resolver address: %s", gensio_err_to_str(rv)); goto out; } host = dnssd_str_fix(o, hostname); if (!host) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Error allocating hostname: %s", gensio_err_to_str(GE_NOMEM)); goto out; } if (r->txt) { rv = gensio_argv_copy(o, r->txt, NULL, &txt); if (rv) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Error copying txt: %s", gensio_err_to_str(rv)); goto out; } } state = GENSIO_MDNS_NEW_DATA; mdns_resolver_callback(r, w, state, ifinterface, nettype, r->name, r->type, r->domain, host, addr, r->port, txt); out: if (host) o->free(o, host); if (!(flags & kDNSServiceFlagsMoreComing)) browser_finish_one(w); } static int gensio_mdnslib_start_resolver(struct gensio_mdns *m, struct gensio_mdns_watch_resolver *r, int ifinterface, int protocol, const char *host, const char *type, const char *domain, int iaprotocol) { DNSServiceErrorType derr; uint32_t sinterface; DNSServiceProtocol sprotocol; int err; err = interface_to_dnssd_interface(ifinterface, &sinterface); if (err) return err; err = protocol_to_dnssd_protocol(protocol, &sprotocol); if (err) return err; r->dnssd_sref = m->dnssd_sref; derr = DNSServiceGetAddrInfo(&r->dnssd_sref, kDNSServiceFlagsShareConnection, sinterface, sprotocol, host, dnssd_resolve_callback, r); if (derr) return dnssd_err_to_err(m, derr); return 0; } #elif defined(HAVE_WINMDNS) static void gensio_mdnslib_reset_finish_one(struct gensio_mdns_watch *w) { /* We don't have to count these like avahi, just set it so it will finish */ w->service_calls_pending = 1; } static void gensio_mdnslib_resolver_free(struct gensio_os_funcs *o, struct gensio_mdns_watch_resolver *r) { } static void gensio_mdnslib_browser_free(struct gensio_os_funcs *o, struct gensio_mdns_watch_browser *b) { } #endif /* HAVE_AVAHI */ static void browser_remove(struct gensio_mdns_watch_browser *b); static void resolver_remove(struct gensio_mdns_watch_resolver *r); static void resolver_free(struct gensio_os_funcs *o, struct gensio_mdns_watch_resolver *r) { gensio_mdnslib_resolver_free(o, r); if (r->host) o->free(o, r->host); if (r->name) o->free(o, r->name); if (r->type) o->free(o, r->type); if (r->domain) o->free(o, r->domain); if (r->txt) gensio_argv_free(o, r->txt); o->free(o, r); } static struct gensio_mdns_watch_resolver * resolver_find(struct gensio_mdns_watch_browser *b, int ifinterface, int protocol, int port, const char *host, const char *name, const char *type, const char *domain) { struct gensio_mdns_watch_resolver *r = NULL; struct gensio_link *l; gensio_list_for_each(&b->resolvers, l) { r = gensio_container_of(l, struct gensio_mdns_watch_resolver, link); if (r->ifinterface == ifinterface && r->protocol == protocol && (port == -1 || port == r->port) && (host == NULL || strcmp(r->host, host) == 0) && (name == NULL || strcmp(r->name, name) == 0) && strcmp(r->type, type) == 0 && strcmp(r->domain, domain) == 0) break; else r = NULL; } return r; } static void resolver_remove(struct gensio_mdns_watch_resolver *r) { struct gensio_mdns_watch_browser *b = r->b; struct gensio_mdns_watch *w = b->w; struct gensio_mdns *m = w->m; struct gensio_os_funcs *o = m->o; struct gensio_link *l, *l2; gensio_list_for_each_safe(&r->results, l, l2) { struct gensio_mdns_result *e = gensio_container_of(l, struct gensio_mdns_result, link); result_remove(m, r, e); } gensio_list_rm(&b->resolvers, &r->link); resolver_free(o, r); } static void browser_finish_one(struct gensio_mdns_watch *w) { struct gensio_mdns *m = w->m; if (w->callback_data.all_for_now) return; assert(w->service_calls_pending > 0); w->service_calls_pending--; if (w->service_calls_pending == 0) { w->callback_data.all_for_now = true; enqueue_callback(m, &w->callback_data); } } static void browser_free(struct gensio_os_funcs *o, struct gensio_mdns_watch_browser *b) { gensio_mdnslib_browser_free(o, b); if (b->type) o->free(o, b->type); if (b->domain) o->free(o, b->domain); if (b->name) o->free(o, b->name); o->free(o, b); } #if !HAVE_WINMDNS static void mdns_browser_callback(struct gensio_mdns_watch_browser *b, int ifinterface, int protocol, int port, const char **txt, const char *host, const char *name, const char *type, const char *domain) { struct gensio_mdns_watch_resolver *r = NULL; struct gensio_mdns_watch *w = b->w; struct gensio_mdns *m = w->m; struct gensio_os_funcs *o = m->o; int err = GE_NOMEM; if (w->ifinterface != -1 && ifinterface != w->ifinterface) goto out; if (w->protocol != GENSIO_NETTYPE_UNSPEC && protocol != w->protocol) goto out; if (!mdns_str_cmp(&w->name, name)) goto out; r = o->zalloc(o, sizeof(*r)); if (!r) goto out_err; gensio_list_init(&r->results); r->b = b; r->ifinterface = ifinterface; r->protocol = protocol; r->port = port; r->txt = txt; txt = NULL; if (dupstr(o, host, &r->host)) goto out_err; if (dupstr(o, name, &r->name)) goto out_err; if (dupstr(o, type, &r->type)) goto out_err; if (dupstr(o, domain, &r->domain)) goto out_err; gensio_list_add_tail(&b->resolvers, &r->link); err = gensio_mdnslib_start_resolver(m, r, ifinterface, protocol, host, type, domain, w->protocol); if (err) { gensio_list_rm(&b->resolvers, &r->link); goto out_err; } return; out_err: gensio_mdns_log(m, GENSIO_LOG_ERR, "Error allocating browser: %s", gensio_err_to_str(err)); if (r) resolver_free(o, r); out: if (txt) gensio_argv_free(o, txt); } #endif static struct gensio_mdns_watch_browser * browser_find(struct gensio_mdns_watch *w, int ifinterface, int protocol, const char *name, const char *type, const char *domain) { struct gensio_mdns_watch_browser *b; struct gensio_link *l; /* If we have the resolver set, remove it. */ gensio_list_for_each(&w->browsers, l) { b = gensio_container_of(l, struct gensio_mdns_watch_browser, link); if (b->ifinterface == ifinterface && b->protocol == protocol && (!name || strcmp(b->name, name) == 0) && strcmp(b->type, type) == 0 && strcmp(b->domain, domain) == 0) return b; } return NULL; } static void browser_remove(struct gensio_mdns_watch_browser *b) { struct gensio_mdns_watch *w; struct gensio_link *l, *l2; if (!b) return; w = b->w; gensio_list_for_each_safe(&b->resolvers, l, l2) { struct gensio_mdns_watch_resolver *r = gensio_container_of(l, struct gensio_mdns_watch_resolver, link); resolver_remove(r); } gensio_list_rm(&w->browsers, &b->link); browser_free(w->m->o, b); } #if HAVE_AVAHI static void avahi_service_browser_callback(AvahiServiceBrowser *ab, AvahiIfIndex ainterface, AvahiProtocol aprotocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void *userdata) { struct gensio_mdns_watch_browser *b = userdata; struct gensio_mdns_watch *w = b->w; struct gensio_mdns *m = w->m; struct gensio_mdns_watch_resolver *r = NULL; int protocol, ifinterface; ifinterface = avahi_interface_to_interface(ainterface); switch (event) { case AVAHI_BROWSER_NEW: case AVAHI_BROWSER_REMOVE: /* Handle this one below. */ break; case AVAHI_BROWSER_ALL_FOR_NOW: browser_finish_one(w); return; case AVAHI_BROWSER_CACHE_EXHAUSTED: default: return; case AVAHI_BROWSER_FAILURE: gensio_mdns_log(m, GENSIO_LOG_ERR, "Error from browser: %s", avahi_strerror(avahi_client_errno(m->ac))); return; } if (avahi_protocol_to_protocol(aprotocol, &protocol)) return; /* See if it aready exists. */ r = resolver_find(b, ifinterface, protocol, -1, NULL, name, type, domain); if (event == AVAHI_BROWSER_REMOVE) { /* If we have the resolver, remove it. */ if (r) { resolver_remove(r); if (gensio_list_empty(&b->resolvers)) browser_remove(b); } return; } if (r) return; /* We already have it. */ mdns_browser_callback(b, ifinterface, protocol, -1, NULL, name, name, type, domain); } /* Will be called with the lock held. */ static void avahi_service_type_callback(AvahiServiceTypeBrowser *ab, AvahiIfIndex ainterface, AvahiProtocol aprotocol, AvahiBrowserEvent event, const char *type, const char *domain, AvahiLookupResultFlags flags, void *userdata) { struct gensio_mdns_watch *w = userdata; struct gensio_mdns *m = w->m; struct gensio_os_funcs *o = m->o; struct gensio_mdns_watch_browser *b = NULL; int protocol, ifinterface, err; if (w->removed) return; ifinterface = avahi_interface_to_interface(ainterface); switch (event) { case AVAHI_BROWSER_NEW: case AVAHI_BROWSER_REMOVE: /* Handle this one below. */ break; case AVAHI_BROWSER_ALL_FOR_NOW: browser_finish_one(w); return; case AVAHI_BROWSER_CACHE_EXHAUSTED: default: return; case AVAHI_BROWSER_FAILURE: gensio_mdns_log(m, GENSIO_LOG_ERR, "Error from type browser: %s", avahi_strerror(avahi_client_errno(m->ac))); return; } err = avahi_protocol_to_protocol(aprotocol, &protocol); if (err) return; b = browser_find(w, ifinterface, protocol, NULL, type, domain); if (event == AVAHI_BROWSER_REMOVE) { if (b) browser_remove(b); return; } if (b) return; /* We already have it. */ if (w->ifinterface != -1 && ifinterface != w->ifinterface) return; if (w->protocol != GENSIO_NETTYPE_UNSPEC && protocol != w->protocol) return; if (!mdns_str_cmp(&w->type, type)) return; if (!mdns_str_cmp(&w->domain, domain)) return; b = o->zalloc(o, sizeof(*b)); if (!b) goto out_err; gensio_list_init(&b->resolvers); b->w = w; b->ifinterface = ifinterface; b->protocol = protocol; if (dupstr(o, type, &b->type)) goto out_err; if (dupstr(o, domain, &b->domain)) goto out_err; gensio_list_add_tail(&w->browsers, &b->link); w->service_calls_pending++; b->avahi_browser = avahi_service_browser_new(m->ac, ainterface, aprotocol, type, domain, 0, avahi_service_browser_callback, b); if (!b->avahi_browser) { gensio_list_rm(&w->browsers, &b->link); w->service_calls_pending--; goto out_err; } return; out_err: gensio_mdns_log(m, GENSIO_LOG_ERR, "Out of memory allocating service type browser"); if (b) browser_free(o, b); } static int gensio_mdnslib_add_watch(struct gensio_mdns_watch *w) { struct gensio_mdns *m = w->m; AvahiProtocol aprotocol; AvahiIfIndex ainterface; int err; err = protocol_to_avahi_protocol(w->protocol, &aprotocol); if (err) return GE_INVAL; if (m->state != AVAHI_CLIENT_S_RUNNING) /* This will be caught later when avahi is ready. */ return 0; ainterface = interface_to_avahi_interface(w->ifinterface); w->avahi_browser = avahi_service_type_browser_new(m->ac, ainterface, aprotocol, w->domainstr, 0, avahi_service_type_callback, w); if (w->avahi_browser) w->service_calls_pending++; else return GE_NOMEM; return 0; } static void gensio_mdnslib_watch_free(struct gensio_mdns_watch *w) { if (w->avahi_browser) avahi_service_type_browser_free(w->avahi_browser); enqueue_callback(w->m, &w->callback_data); w->callback_data.remove = true; } #elif HAVE_DNSSD static void dnssd_service_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port, /* In network byte order */ uint16_t txtLen, const unsigned char *txtRecord, void *context) { struct gensio_mdns_watch_browser *b = context; struct gensio_mdns_watch *w = b->w; struct gensio_mdns *m = w->m; struct gensio_os_funcs *o = m->o; struct gensio_mdns_watch_resolver *r = NULL; int ifinterface, rv = 0; const char **txt = NULL; char *host = NULL; port = ntohs(port); if (errorCode) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Error from service: %d", errorCode); return; } ifinterface = dnssd_interface_to_interface(interfaceIndex); host = dnssd_str_fix(o, hosttarget); if (!host) goto out_err; /* See if it aready exists. */ r = resolver_find(b, ifinterface, b->protocol, port, host, NULL, b->type, b->domain); if (!r) { /* One means no records. */ if (txtRecord && txtLen > 1) { gensiods args = 0, argc = 0; const unsigned char *str; uint8_t len; for (str = txtRecord; str - txtRecord < txtLen; str += len) { len = *str; str++; if (str - txtRecord + len > txtLen) { rv = GE_INVAL; goto out_err; } rv = gensio_argv_nappend(o, &txt, (char *) str, len, &args, &argc, true); if (rv) goto out_err; } rv = gensio_argv_append(o, &txt, NULL, &args, &argc, false); if (rv) goto out_err; } mdns_browser_callback(b, ifinterface, b->protocol, port, txt, host, b->name, b->type, b->domain); } goto out; out_err: gensio_mdns_log(m, GENSIO_LOG_ERR, "Out of memory processing txt string"); if (txt) gensio_argv_free(o, txt); out: if (host) o->free(o, host); if (!(flags & kDNSServiceFlagsMoreComing)) browser_finish_one(w); } static void dnssd_watch_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *itype, const char *idomain, void *context) { struct gensio_mdns_watch *w = context; struct gensio_mdns *m = w->m; struct gensio_os_funcs *o = m->o; struct gensio_mdns_watch_browser *b = NULL; DNSServiceErrorType derr; int ifinterface, err = 0; char *type = NULL; char *domain = NULL; if (w->removed) return; if (errorCode) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Error from browse: %d", errorCode); return; } ifinterface = dnssd_interface_to_interface(interfaceIndex); err = GE_NOMEM; type = dnssd_str_fix(o, itype); if (!type) goto out_err; domain = dnssd_str_fix(o, idomain); if (!domain) goto out_err; b = browser_find(w, ifinterface, w->protocol, name, type, domain); if (!(flags & kDNSServiceFlagsAdd)) { if (b) browser_remove(b); goto out; } if (b) goto out; /* We already have it. */ if (w->ifinterface != -1 && ifinterface != w->ifinterface) goto out; if (!mdns_str_cmp(&w->name, name)) goto out; if (!mdns_str_cmp(&w->type, type)) goto out; if (!mdns_str_cmp(&w->domain, domain)) goto out; b = o->zalloc(o, sizeof(*b)); if (!b) goto out_err; gensio_list_init(&b->resolvers); b->w = w; b->ifinterface = ifinterface; b->protocol = w->protocol; if (dupstr(o, name, &b->name)) goto out_err; if (dupstr(o, type, &b->type)) goto out_err; if (dupstr(o, domain, &b->domain)) goto out_err; gensio_list_add_tail(&w->browsers, &b->link); b->dnssd_sref = m->dnssd_sref; derr = DNSServiceResolve(&b->dnssd_sref, kDNSServiceFlagsShareConnection, interfaceIndex, name, itype, idomain, dnssd_service_callback, b); if (derr) { err = dnssd_err_to_err(m, derr); gensio_list_rm(&w->browsers, &b->link); goto out_err; } goto out; out_err: gensio_mdns_log(m, GENSIO_LOG_ERR, "Error allocating service type browser: %s", gensio_err_to_str(err)); if (b) browser_free(o, b); out: if (type) o->free(o, type); if (domain) o->free(o, domain); if (!(flags & kDNSServiceFlagsMoreComing)) browser_finish_one(w); } static int gensio_mdnslib_add_watch(struct gensio_mdns_watch *w) { struct gensio_mdns *m = w->m; DNSServiceErrorType derr; uint32_t sinterface; char *typestr = w->typestr; char *domainstr = w->domainstr; int err; if (!typestr) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Attempt to add a watch with mdnssd without type"); return GE_INCONSISTENT; } else if (*typestr == '@' || *typestr == '%') { gensio_mdns_log(m, GENSIO_LOG_ERR, "Attempt to add a watch with DNSSD with a glob or regex type"); return GE_INCONSISTENT; } else if (domainstr && (*domainstr == '@' || *domainstr == '%')) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Attempt to add a watch with DNSSD with a glob or regex domain"); return GE_INCONSISTENT; } err = interface_to_dnssd_interface(w->ifinterface, &sinterface); if (err) return err; w->dnssd_sref = m->dnssd_sref; derr = DNSServiceBrowse(&w->dnssd_sref, kDNSServiceFlagsShareConnection, sinterface, typestr, domainstr, dnssd_watch_callback, w); if (derr) { err = dnssd_err_to_err(m, derr); return err; } return 0; } static void gensio_mdnslib_watch_free(struct gensio_mdns_watch *w) { DNSServiceRefDeallocate(w->dnssd_sref); enqueue_callback(w->m, &w->callback_data); w->callback_data.remove = true; } #elif HAVE_WINMDNS static void WINAPI win_browse_query_complete(void *context, DNS_QUERY_RESULT *bres) { struct gensio_mdns_watch *w = context; struct gensio_mdns *m = w->m; struct gensio_os_funcs *o = m->o; struct gensio_mdns_watch_browser *b = NULL; struct gensio_mdns_watch_resolver *r = NULL; struct gensio_mdns_result *e; struct gensio_link *l, *l2; DNS_RECORD *rec; char *name = NULL; char *host = NULL; char *domain = NULL; /* Points to something in name. */ char *dot; const char **txt = NULL; uint16_t port = 0; DWORD rv; int err = 0; gensio_mdns_lock(m); if (bres->QueryStatus == ERROR_CANCELLED) { enqueue_callback(m, &w->callback_data); w->callback_data.remove = true; goto out_unlock; } if (w->removed) goto out_unlock; if (bres->QueryStatus != ERROR_SUCCESS) { err = gensio_os_err_to_err(o, bres->QueryStatus); gensio_mdns_log(m, GENSIO_LOG_ERR, "Error from browse: %s (%d)", gensio_err_to_str(err), bres->QueryStatus); goto out_unlock; } /* * The first run through we extract the name, host, domain, and * txt. We will handle A and AAAA records in the next run. */ for (rec = bres->pQueryRecords; rec; rec = rec->pNext) { switch (rec->wType) { case DNS_TYPE_PTR: /* * Extract the service name from the string. Format is like: * * name._srv._tcp.local * * We have to search back through the '.'s to get the values. * Also extract the domain as part of this. */ if (name) /* Did we already get this? */ break; err = wchar_to_str(o, (wchar_t *) rec->Data.PTR.pNameHost, &name); if (err) goto out_err; dot = strrchr(name, '.'); if (!dot) { err = GE_INVAL; goto out_err; } domain = dot + 1; if (dot == name) { err = GE_INVAL; goto out_err; } *dot = '\0'; dot = strrchr(name, '.'); if (!dot || dot == name) { err = GE_INVAL; goto out_err; } *dot = '\0'; dot = strrchr(name, '.'); if (!dot || dot == name) { err = GE_INVAL; goto out_err; } *dot = '\0'; break; case DNS_TYPE_SRV: /* * Get the hostname here. Have to remove the domain. */ if (host) /* Did we already get this? */ break; err = wchar_to_str(o, (wchar_t *) rec->Data.SRV.pNameTarget, &host); if (err) goto out_err; dot = strrchr(host, '.'); if (!dot) { err = GE_INVAL; goto out_err; } *dot = '\0'; port = rec->Data.SRV.wPort; break; case DNS_TYPE_TEXT: if (txt) /* Did we already get this? */ break; if (rec->Data.TXT.dwStringCount < 1) break; if (rec->Data.TXT.dwStringCount == 1 && ((wchar_t *) (rec->Data.TXT.pStringArray[0]))[0] == 0) { break; } err = wstring_array_to_argv(o, rec->Data.TXT.dwStringCount, (wchar_t **) rec->Data.TXT.pStringArray, &txt); if (err) goto out_err; break; default: break; } } /* We have to get these from the results. */ if (!name || !host || port == 0) { /* No need to check domain, it comes with name. */ err = GE_INVAL; goto out_err; } err = GE_NOMEM; b = browser_find(w, w->ifinterface, w->protocol, NULL, w->typestr, domain); if (!b) { b = o->zalloc(o, sizeof(*b)); if (!b) goto out_err; gensio_list_init(&b->resolvers); b->w = w; b->ifinterface = w->ifinterface; b->protocol = w->protocol; if (dupstr(o, w->typestr, &b->type)) goto out_err; if (dupstr(o, domain, &b->domain)) goto out_err; gensio_list_add_tail(&w->browsers, &b->link); } r = resolver_find(b, w->ifinterface, w->protocol, -1, NULL, name, w->typestr, domain); if (!r) { r = o->zalloc(o, sizeof(*r)); if (!r) goto out_err; gensio_list_init(&r->results); r->b = b; r->ifinterface = w->ifinterface; r->protocol = w->protocol; r->port = port; if (txt) { err = gensio_argv_copy(o, txt, NULL, &r->txt); if (err) goto out_err; } if (dupstr(o, host, &r->host)) goto out_err; if (dupstr(o, name, &r->name)) goto out_err; if (dupstr(o, w->typestr, &r->type)) goto out_err; if (dupstr(o, domain, &r->domain)) goto out_err; gensio_list_add_tail(&b->resolvers, &r->link); } gensio_list_for_each(&r->results, l) { e = gensio_container_of(l, struct gensio_mdns_result, link); e->found = false; } /* Now we get the A and AAAA records. */ for (rec = bres->pQueryRecords; rec; rec = rec->pNext) { switch (rec->wType) { case DNS_TYPE_A: { struct sockaddr_in in; DWORD ifidx; struct gensio_addr *addr; const char **txt2 = NULL; if (w->protocol != GENSIO_NETTYPE_IPV4 && w->protocol != GENSIO_NETTYPE_UNSPEC) break; memset(&in, 0, sizeof(in)); in.sin_family = AF_INET; in.sin_port = port; memcpy(&in.sin_addr, &rec->Data.A.IpAddress, sizeof(in.sin_addr)); /* Why doesn't windows pass this in? */ rv = GetBestInterfaceEx((struct sockaddr *) &in, &ifidx); if (rv != ERROR_SUCCESS) break; err = gensio_addr_create(o, GENSIO_NETTYPE_IPV4, &in.sin_addr, sizeof(in.sin_addr), port, &addr); if (err) break; e = result_find(r, ifidx, GENSIO_NETTYPE_IPV4, name, w->typestr, domain, host, addr, port); if (e) { e->found = true; gensio_addr_free(addr); break; } if (txt) { err = gensio_argv_copy(o, r->txt, NULL, &txt2); if (err) { gensio_addr_free(addr); break; } } mdns_resolver_callback(r, w, GENSIO_MDNS_NEW_DATA, ifidx, GENSIO_NETTYPE_IPV4, name, w->typestr, domain, host, addr, port, txt2); } #ifdef AF_INET6 case DNS_TYPE_AAAA: { struct sockaddr_in6 in6; DWORD ifidx; struct gensio_mdns_result *e; struct gensio_addr *addr; const char **txt2 = NULL; if (w->protocol != GENSIO_NETTYPE_IPV6 && w->protocol != GENSIO_NETTYPE_UNSPEC) break; memset(&in6, 0, sizeof(in6)); in6.sin6_family = AF_INET6; in6.sin6_port = port; memcpy(&in6.sin6_addr, &rec->Data.AAAA.Ip6Address, sizeof(in6.sin6_addr)); /* Why doesn't windows pass this in? */ rv = GetBestInterfaceEx((struct sockaddr *) &in6, &ifidx); if (rv != ERROR_SUCCESS) break; in6.sin6_scope_id = ifidx; err = gensio_addr_create(o, GENSIO_NETTYPE_IPV6, &in6, sizeof(in6), port, &addr); if (err) break; e = result_find(r, ifidx, GENSIO_NETTYPE_IPV6, name, w->typestr, domain, host, addr, port); if (e) { e->found = true; gensio_addr_free(addr); break; } if (txt) { err = gensio_argv_copy(o, txt, NULL, &txt2); if (err) { gensio_addr_free(addr); break; } } mdns_resolver_callback(r, w, GENSIO_MDNS_NEW_DATA, ifidx, GENSIO_NETTYPE_IPV6, name, w->typestr, domain, host, addr, port, txt2); break; } #endif default: break; } } gensio_list_for_each_safe(&r->results, l, l2) { e = gensio_container_of(l, struct gensio_mdns_result, link); if (!e->found) result_remove(m, r, e); } out_err: if (err) gensio_log(o, GENSIO_LOG_INFO, "Invalid mdns data: %s", gensio_err_to_str(err)); if (name) o->free(o, name); if (host) o->free(o, host); if (txt) gensio_argv_free(o, txt); if (r && gensio_list_empty(&r->results)) resolver_remove(r); if (b && gensio_list_empty(&b->resolvers)) browser_remove(b); if (!gensio_list_empty(&m->callbacks)) browser_finish_one(w); out_unlock: if (bres->pQueryRecords) DnsRecordListFree(bres->pQueryRecords, DnsFreeRecordList); gensio_mdns_unlock(m); } static int gensio_mdnslib_add_watch(struct gensio_mdns_watch *w) { struct gensio_mdns *m = w->m; struct gensio_os_funcs *o = m->o; DNS_SERVICE_BROWSE_REQUEST breq; DNS_STATUS rv; char *tname = NULL; char *typestr = w->typestr; char *domainstr = w->domainstr; wchar_t *qname; int err; if (w->ifinterface == 0) return GE_INVAL; if (!typestr) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Attempt to add a watch with Windows MDNS without type"); return GE_INCONSISTENT; } else if (*typestr == '@' || *typestr == '%') { gensio_mdns_log(m, GENSIO_LOG_ERR, "Attempt to add a watch with Windows MDNS with a glob or regex type"); return GE_INCONSISTENT; } else if (domainstr && (*domainstr == '@' || *domainstr == '%')) { gensio_mdns_log(m, GENSIO_LOG_ERR, "Attempt to add a watch with Windows MDNS with a glob or regex domain"); return GE_INCONSISTENT; } memset(&breq, 0, sizeof(breq)); if (!domainstr) domainstr = "local"; tname = gensio_alloc_sprintf(o, "%s.%s", typestr, domainstr); if (!tname) return GE_NOMEM; err = str_to_wchar(o, tname, &qname); o->free(o, tname); if (err) return err; breq.Version = DNS_QUERY_REQUEST_VERSION2; if (w->ifinterface == -1) breq.InterfaceIndex = 0; else breq.InterfaceIndex = w->ifinterface; breq.QueryName = qname; breq.pBrowseCallbackV2 = win_browse_query_complete; breq.pQueryContext = w; rv = DnsServiceBrowse(&breq, &w->winmdns_cancel); if (rv != DNS_REQUEST_PENDING) err = gensio_os_err_to_err(o, rv); o->free(o, qname); return err; } static void gensio_mdnslib_watch_free(struct gensio_mdns_watch *w) { DnsServiceBrowseCancel(&w->winmdns_cancel); } #endif static void watch_free(struct gensio_os_funcs *o, struct gensio_mdns_watch *w) { if (w->typestr) o->free(o, w->typestr); if (w->domainstr) o->free(o, w->domainstr); mdns_str_cleanup(o, &w->host); mdns_str_cleanup(o, &w->domain); mdns_str_cleanup(o, &w->type); mdns_str_cleanup(o, &w->name); o->free(o, w); } int gensio_mdns_add_watch(struct gensio_mdns *m, int ifinterface, int ipdomain, const char *name, const char *type, const char *domain, const char *host, gensio_mdns_watch_cb callback, void *userdata, struct gensio_mdns_watch **rwatch) { struct gensio_mdns_watch *w; struct gensio_os_funcs *o = m->o; int err = GE_NOMEM; w = o->zalloc(o, sizeof(*w)); if (!w) return GE_NOMEM; w->m = m; gensio_mdns_ref(m); w->cb = callback; w->callback_data.w = w; w->userdata = userdata; w->ifinterface = ifinterface; w->protocol = ipdomain; gensio_list_init(&w->browsers); gensio_mdnslib_reset_finish_one(w); err = mdns_str_setup(m, name, &w->name); if (err) goto out_err; err = mdns_str_setup(m, type, &w->type); if (err) goto out_err; err = mdns_str_setup(m, domain, &w->domain); if (err) goto out_err; err = mdns_str_setup(m, host, &w->host); if (err) goto out_err; /* * Windows and DNSSD need type set and can use domain, but they can't * be regexes or globs. At least handle the '=' case for them. * These are not used for avahi. */ if (domain && *domain == '=') domain++; if (type && *type == '=') type++; if (dupstr(o, domain, &w->domainstr)) goto out_err; if (dupstr(o, type, &w->typestr)) goto out_err; gensio_mdns_lock(m); gensio_list_add_tail(&m->watches, &w->link); err = gensio_mdnslib_add_watch(w); gensio_mdns_unlock(m); if (err) { gensio_list_rm(&m->watches, &w->link); goto out_err; } if (rwatch) *rwatch = w; return 0; out_err: gensio_mdns_lock(m); watch_free(o, w); gensio_mdns_deref_and_unlock(m); return err; } static int i_gensio_mdns_remove_watch(struct gensio_mdns_watch *w, gensio_mdns_watch_done done, void *userdata) { struct gensio_mdns *m = w->m; struct gensio_os_funcs *o = m->o; struct gensio_link *l, *l2; struct gensio_link *li, *li2; struct gensio_link *lj, *lj2; struct gensio_mdns_watch_resolver *r; struct gensio_mdns_watch_browser *b; struct gensio_mdns_result *e; w->removed = true; w->remove_done = done; w->remove_done_data = userdata; gensio_list_rm(&m->watches, &w->link); gensio_list_for_each_safe(&w->browsers, l, l2) { b = gensio_container_of(l, struct gensio_mdns_watch_browser, link); gensio_list_for_each_safe(&b->resolvers, li, li2) { r = gensio_container_of(li, struct gensio_mdns_watch_resolver, link); gensio_list_for_each_safe(&r->results, lj, lj2) { e = gensio_container_of(lj, struct gensio_mdns_result, link); if (e->cbdata.in_queue) { gensio_list_rm(&m->callbacks, &e->cbdata.link); gensio_mdns_deref(m); } gensio_list_rm(&r->results, &e->link); result_free(o, e); } gensio_list_rm(&b->resolvers, &r->link); resolver_free(o, r); } gensio_list_rm(&w->browsers, &b->link); browser_free(o, b); } gensio_mdnslib_watch_free(w); return 0; } int gensio_mdns_remove_watch(struct gensio_mdns_watch *w, gensio_mdns_watch_done done, void *userdata) { struct gensio_mdns *m = w->m; int err; gensio_mdns_lock(m); if (w->removed) err = GE_INUSE; else err = i_gensio_mdns_remove_watch(w, done, userdata); gensio_mdns_unlock(m); return err; } /* * Base allocation code * * A gensio_mdns structure is allocated here. Both Avahi and DNS-SD * maintain a single file descriptor for all connections using this * allocated structure, though some special work has to be done with * DNS-SD to make this work. * * This structure will hold all running watches, which will point to * all running browsers, which will point to all running resolvers. */ #if HAVE_AVAHI /* Lock should already be held when calling this. */ static void avahi_client_callback(AvahiClient *ac, AvahiClientState state, void *userdata) { struct gensio_mdns *m = userdata; struct gensio_link *l; struct gensio_mdns_service *s; struct gensio_mdns_watch *w; if (m->state == state) return; m->state = state; if (state == AVAHI_CLIENT_S_RUNNING) { gensio_list_for_each(&m->services, l) { s = gensio_container_of(l, struct gensio_mdns_service, link); gensio_mdnslib_add_service(s); } gensio_list_for_each(&m->watches, l) { w = gensio_container_of(l, struct gensio_mdns_watch, link); gensio_mdnslib_add_watch(w); } } /* FIXME - handle other states. */ } int gensio_mdnslib_start(struct gensio_mdns *m) { int aerr; gensio_mdns_lock(m); m->ac = avahi_client_new(m->ap, AVAHI_CLIENT_NO_FAIL, avahi_client_callback, m, &aerr); gensio_mdns_unlock(m); if (!m->ac) { gensio_log(m->o, GENSIO_LOG_ERR, "mdns: Can't allocate avahi client: %s", avahi_strerror(aerr)); return GE_NOMEM; } return 0; } static void gensio_mdnslib_disable(struct gensio_mdns *m) { gensio_avahi_poll_disable(m->ap); } #elif HAVE_DNSSD static void dnssd_read_handler(struct gensio_iod *iod, void *cb_data) { struct gensio_mdns *m = cb_data; gensio_mdns_lock(m); DNSServiceProcessResult(m->dnssd_sref); gensio_mdns_unlock(m); } static void dnssd_except_handler(struct gensio_iod *iod, void *cb_data) { dnssd_read_handler(iod, cb_data); } static void dnssd_cleared_handler(struct gensio_iod *iod, void *cb_data) { struct gensio_mdns *m = cb_data; gensio_mdns_lock(m); m->o->release_iod(m->iod); DNSServiceRefDeallocate(m->dnssd_sref); gensio_mdns_deref_and_unlock(m); } int gensio_mdnslib_start(struct gensio_mdns *m) { struct gensio_os_funcs *o = m->o; DNSServiceErrorType derr; int err; m->dnssd_fd = -1; derr = DNSServiceCreateConnection(&m->dnssd_sref); if (derr) { err = dnssd_err_to_err(m, derr); goto out_err; } m->dnssd_fd = DNSServiceRefSockFD(m->dnssd_sref); err = o->add_iod(o, GENSIO_IOD_SOCKET, m->dnssd_fd, &m->iod); if (err) goto out_err; err = o->set_fd_handlers(m->iod, m, dnssd_read_handler, NULL, dnssd_except_handler, dnssd_cleared_handler); if (err) goto out_err; gensio_mdns_ref(m); o->set_read_handler(m->iod, true); o->set_except_handler(m->iod, true); return 0; out_err: if (m->iod) o->clear_fd_handlers_norpt(m->iod); if (m->dnssd_fd != -1) DNSServiceRefDeallocate(m->dnssd_sref); return err; } static void gensio_mdnslib_disable(struct gensio_mdns *m) { m->o->clear_fd_handlers(m->iod); } #elif HAVE_WINMDNS int gensio_mdnslib_start(struct gensio_mdns *m) { return 0; } static void gensio_mdnslib_disable(struct gensio_mdns *m) { } #endif static void mdns_runner(struct gensio_runner *runner, void *userdata) { struct gensio_mdns *m = userdata; struct gensio_os_funcs *o = m->o; struct gensio_link *l; struct gensio_mdns_callback *c; gensio_mdns_lock(m); while (!gensio_list_empty(&m->callbacks)) { l = gensio_list_first(&m->callbacks); c = gensio_container_of(l, struct gensio_mdns_callback, link); gensio_list_rm(&m->callbacks, &c->link); c->in_queue = false; gensio_mdns_deref(m); if (c->s) { struct gensio_mdns_service *s = c->s; if (c->remove) { if (s->cb) { gensio_mdns_unlock(m); s->cb(s, GENSIO_MDNS_SERVICE_REMOVED, NULL, s->cb_data); gensio_mdns_lock(m); } free_service(m->o, s); } else { enum gensio_mdns_service_event ev = GENSIO_MDNS_SERVICE_READY; if (c->namechange) ev = GENSIO_MDNS_SERVICE_READY_NEW_NAME; c->namechange = false; c->all_for_now = false; if (s->cb) { gensio_cntstr *str = gensio_cntstr_ref(o, s->currname); gensio_mdns_unlock(m); s->cb(s, ev, gensio_cntstr_get(str), s->cb_data); gensio_mdns_lock(m); gensio_cntstr_free(o, str); } } } else if (c->w) { struct gensio_mdns_watch *w = c->w; if (c->remove) { if (w->remove_done) { gensio_mdns_unlock(m); w->remove_done(w, w->remove_done_data); gensio_mdns_lock(m); } watch_free(o, w); gensio_mdns_deref(m); } else { if (c->data) { struct gensio_mdns_watch_data *d = c->data; /* * Store this, as d may be freed if it's not * GENSIO_MDNS_WATCH_DATA_GONE. */ enum gensio_mdns_data_state state = d->state; if (!m->freed && !w->removed) { gensio_mdns_unlock(m); w->cb(w, d->state, d->ifinterface, d->ipdomain, d->name, d->type, d->domain, d->host, d->addr, d->txt, w->userdata); gensio_mdns_lock(m); } if (state == GENSIO_MDNS_WATCH_DATA_GONE) result_free(o, d->result); } else if (c->all_for_now) { gensio_mdnslib_reset_finish_one(w); c->all_for_now = false; gensio_mdns_unlock(m); w->cb(w, GENSIO_MDNS_WATCH_ALL_FOR_NOW, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, w->userdata); gensio_mdns_lock(m); } } } } m->runner_pending = false; gensio_mdns_deref_and_unlock(m); } int gensio_alloc_mdns(struct gensio_os_funcs *o, struct gensio_mdns **new_m) { struct gensio_mdns *m; int err; m = o->zalloc(o, sizeof(*m)); if (!m) return GE_NOMEM; m->o = o; m->refcount = 1; err = gensio_mdnslib_init(m); if (err) { o->free(o, m); return err; } m->runner = o->alloc_runner(o, mdns_runner, m); if (!m->runner) { gensio_mdnslib_free(m); return GE_NOMEM; } gensio_list_init(&m->services); gensio_list_init(&m->watches); gensio_list_init(&m->callbacks); err = gensio_mdnslib_start(m); if (err) { gensio_mdnslib_free(m); return err; } *new_m = m; return 0; } int gensio_free_mdns(struct gensio_mdns *m, gensio_mdns_done done, void *userdata) { struct gensio_os_funcs *o = m->o; struct gensio_link *l, *l2; int err = 0; gensio_mdns_lock(m); if (m->freed) { err = GE_INUSE; goto out_unlock; } gensio_mdnslib_disable(m); m->freed = true; m->free_done = done; m->free_userdata = userdata; gensio_list_for_each_safe(&m->callbacks, l, l2) { struct gensio_mdns_callback *c = gensio_container_of(l, struct gensio_mdns_callback, link); if (c->remove) /* Have to do the remove in the runner to avoid locking issues. */ continue; gensio_list_rm(&m->callbacks, &c->link); c->in_queue = false; gensio_mdns_deref(m); if (c->data && c->data->state == GENSIO_MDNS_WATCH_DATA_GONE) result_free(o, c->data->result); } if (m->refcount == 1 && !m->runner_pending) { /* * Run the runner to delete this. Don't add a reference here, * we want the runner to delete it. */ m->runner_pending = true; o->run(m->runner); } else { /* * Services or watches are left or the runner is going to run, * set it to be deleted in the runner after those are deleted. */ gensio_mdns_deref(m); } out_unlock: gensio_mdns_unlock(m); return err; } #else int gensio_alloc_mdns(struct gensio_os_funcs *o, struct gensio_mdns **m) { return GE_NOTSUP; } int gensio_free_mdns(struct gensio_mdns *m, gensio_mdns_done done, void *userdata) { return GE_NOTSUP; } int gensio_mdns_add_service(struct gensio_mdns *m, int ifinterface, int ipdomain, const char *name, const char *type, const char *domain, const char *host, int port, const char * const *txt, struct gensio_mdns_service **rservice) { return GE_NOTSUP; } int gensio_mdns_add_service2(struct gensio_mdns *m, int ifinterface, int ipdomain, const char *name, const char *type, const char *domain, const char *host, int port, const char * const *txt, gensio_mdns_service_cb cb, void *cb_data, struct gensio_mdns_service **rservice) { return GE_NOTSUP; } int gensio_mdns_remove_service(struct gensio_mdns_service *s) { return GE_NOTSUP; } int gensio_mdns_add_watch(struct gensio_mdns *m, int ifinterface, int ipdomain, const char *name, const char *type, const char *domain, const char *host, gensio_mdns_watch_cb callback, void *userdata, struct gensio_mdns_watch **rwatch) { return GE_NOTSUP; } int gensio_mdns_remove_watch(struct gensio_mdns_watch *w, gensio_mdns_watch_done done, void *userdata) { return GE_NOTSUP; } #endif gensio-3.0.0/lib/gensio_script.c0000664000175000017500000004546414747451760012277 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include enum script_state { SCRIPT_CLOSED, SCRIPT_IN_SUB_OPEN, SCRIPT_IN_OPEN, SCRIPT_OPEN, SCRIPT_OPEN_FAIL }; struct script_filter { struct gensio_filter *filter; struct gensio_os_funcs *o; enum script_state state; int err; struct gensio_lock *lock; gensio_filter_cb filter_cb; void *filter_cb_data; /* * Script to gensio buffer, handles data coming from the script * gensio and out the main gensio. */ unsigned char scrtog_buf[1024]; gensiods scrtog_pos; gensiods scrtog_len; /* * Gensio to script buffer, handles data coming from the main gensio * and out to the script. */ unsigned char gtoscr_buf[1024]; gensiods gtoscr_pos; gensiods gtoscr_len; char *str; struct gensio *io; }; #define filter_to_script(v) ((struct script_filter *) \ gensio_filter_get_user_data(v)) static void script_lock(struct script_filter *sfilter) { sfilter->o->lock(sfilter->lock); } static void script_unlock(struct script_filter *sfilter) { sfilter->o->unlock(sfilter->lock); } static bool script_ul_read_pending(struct gensio_filter *filter) { return false; } static bool script_ll_write_pending(struct gensio_filter *filter) { struct script_filter *sfilter = filter_to_script(filter); bool rv = false; script_lock(sfilter); if (sfilter->state == SCRIPT_IN_OPEN) rv = sfilter->scrtog_len > 0; script_unlock(sfilter); return rv; } static bool script_ll_read_needed(struct gensio_filter *filter) { struct script_filter *sfilter = filter_to_script(filter); bool rv = false; script_lock(sfilter); if (sfilter->state == SCRIPT_IN_OPEN) rv = sfilter->gtoscr_len == 0; script_unlock(sfilter); return rv; } static int script_check_open_done(struct gensio_filter *filter, struct gensio *io) { struct script_filter *sfilter = filter_to_script(filter); return sfilter->err; } static void script_finish_close(struct gensio *io, void *close_data) { struct script_filter *sfilter = close_data; char data[50]; gensiods datalen = sizeof(data); if (!sfilter->err) { /* Check that the script returned no error. */ int err = gensio_control(sfilter->io, 0, true, GENSIO_CONTROL_EXIT_CODE, data, &datalen); if (!err) { int errcode = strtoul(data, 0, 0); if (errcode != 0) { err = GE_LOCALCLOSED; sfilter->state = SCRIPT_OPEN_FAIL; } } else if (err == GE_NOTFOUND) { /* Not stdio or pty, no subprogram. */ err = 0; } sfilter->err = err; } if (sfilter->err) sfilter->state = SCRIPT_OPEN_FAIL; else sfilter->state = SCRIPT_OPEN; gensio_free(sfilter->io); sfilter->io = NULL; sfilter->filter_cb(sfilter->filter_cb_data, GENSIO_FILTER_CB_OPEN_DONE, NULL); } static void script_handle_err_unlock(struct script_filter *sfilter, int err) { if (sfilter->state == SCRIPT_IN_OPEN) { if (err == GE_REMCLOSE) { /* Normal close */ err = 0; } } handle_err: sfilter->err = err; if (err) { gensio_set_read_callback_enable(sfilter->io, false); gensio_set_write_callback_enable(sfilter->io, false); sfilter->state = SCRIPT_OPEN_FAIL; script_unlock(sfilter); script_finish_close(sfilter->io, sfilter); } else { err = gensio_close(sfilter->io, script_finish_close, sfilter); if (err) goto handle_err; } script_unlock(sfilter); } static void script_open_done(struct gensio *io, int err, void *open_data) { struct script_filter *sfilter = open_data; script_lock(sfilter); if (err) { script_handle_err_unlock(sfilter, err); } else { sfilter->state = SCRIPT_IN_OPEN; gensio_set_read_callback_enable(sfilter->io, true); script_unlock(sfilter); sfilter->filter_cb(sfilter->filter_cb_data, GENSIO_FILTER_CB_INPUT_READY, NULL); } } static int script_sub_event(struct gensio *io, void *user_data, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) { struct script_filter *sfilter = user_data; gensiods count; bool call_handler = false; if (sfilter->state != SCRIPT_IN_OPEN || io != sfilter->io) /* Not in the right state, or an old io. */ return GE_NOTSUP; switch(event) { case GENSIO_EVENT_READ: script_lock(sfilter); if (err) goto handle_err; if (*buflen == 0) { /* Shouldn't happen, but just in case. */ } else if (sfilter->scrtog_len > 0) { gensio_set_read_callback_enable(sfilter->io, false); *buflen = 0; } else { count = *buflen; if (count > sizeof(sfilter->scrtog_buf)) count = sizeof(sfilter->scrtog_buf); memcpy(sfilter->scrtog_buf, buf, count); sfilter->scrtog_pos = 0; sfilter->scrtog_len = count; call_handler = true; gensio_set_read_callback_enable(sfilter->io, false); } script_unlock(sfilter); if (call_handler) sfilter->filter_cb(sfilter->filter_cb_data, GENSIO_FILTER_CB_OUTPUT_READY, NULL); return 0; case GENSIO_EVENT_WRITE_READY: script_lock(sfilter); if (sfilter->gtoscr_len == 0) { gensio_set_write_callback_enable(sfilter->io, false); } else { err = gensio_write(sfilter->io, &count, sfilter->gtoscr_buf + sfilter->gtoscr_pos, sfilter->gtoscr_len, NULL); if (err) goto handle_err; if (count >= sfilter->gtoscr_len) { sfilter->gtoscr_len = 0; sfilter->gtoscr_pos = 0; call_handler = true; gensio_set_write_callback_enable(sfilter->io, false); } else { sfilter->gtoscr_len -= count; sfilter->gtoscr_pos += count; } } script_unlock(sfilter); if (call_handler) sfilter->filter_cb(sfilter->filter_cb_data, GENSIO_FILTER_CB_INPUT_READY, NULL); return 0; default: return GE_NOTSUP; } handle_err: script_handle_err_unlock(sfilter, err); return err; } static int script_try_connect(struct gensio_filter *filter, gensio_time *timeout) { struct script_filter *sfilter = filter_to_script(filter); int err = GE_INPROGRESS; script_lock(sfilter); switch(sfilter->state) { case SCRIPT_IN_SUB_OPEN: case SCRIPT_IN_OPEN: break; case SCRIPT_CLOSED: err = str_to_gensio(sfilter->str, sfilter->o, script_sub_event, sfilter, &sfilter->io); if (!err) { err = gensio_open(sfilter->io, script_open_done, sfilter); if (err) { gensio_free(sfilter->io); sfilter->io = NULL; } } if (!err) { sfilter->state = SCRIPT_IN_SUB_OPEN; err = GE_INPROGRESS; } break; case SCRIPT_OPEN: case SCRIPT_OPEN_FAIL: err = 0; break; } script_unlock(sfilter); return err; } static int script_try_disconnect(struct gensio_filter *filter, gensio_time *timeout) { struct script_filter *sfilter = filter_to_script(filter); int err; script_lock(sfilter); switch(sfilter->state) { case SCRIPT_IN_SUB_OPEN: case SCRIPT_IN_OPEN: gensio_free(sfilter->io); sfilter->io = NULL; /* fallthrough */ case SCRIPT_OPEN: sfilter->state = SCRIPT_CLOSED; err = 0; break; default: err = GE_NOTREADY; } script_unlock(sfilter); return err; } static int script_ul_write(struct gensio_filter *filter, gensio_ul_filter_data_handler handler, void *cb_data, gensiods *rcount, const struct gensio_sg *isg, gensiods sglen, const char *const *auxdata) { struct script_filter *sfilter = filter_to_script(filter); gensiods count = 0; int err = 0; if (sfilter->state == SCRIPT_OPEN) return handler(cb_data, rcount, isg, sglen, auxdata); script_lock(sfilter); switch(sfilter->state) { case SCRIPT_IN_SUB_OPEN: *rcount = 0; break; case SCRIPT_IN_OPEN: if (sfilter->scrtog_len > 0) { struct gensio_sg sg; sg.buf = sfilter->scrtog_buf + sfilter->scrtog_pos; sg.buflen = sfilter->scrtog_len; script_unlock(sfilter); err = handler(sfilter->filter_cb_data, &count, &sg, 1, auxdata); script_lock(sfilter); if (err) goto out_err; if (count >= sfilter->scrtog_len) { sfilter->scrtog_len = 0; sfilter->scrtog_pos = 0; gensio_set_read_callback_enable(sfilter->io, true); } else { sfilter->scrtog_len -= count; sfilter->scrtog_pos += count; } } break; default: return GE_NOTREADY; } script_unlock(sfilter); if (rcount) *rcount = count; return 0; out_err: script_handle_err_unlock(sfilter, err); return err; } static int script_ll_write(struct gensio_filter *filter, gensio_ll_filter_data_handler handler, void *cb_data, gensiods *rcount, unsigned char *buf, gensiods buflen, const char *const *auxdata) { struct script_filter *sfilter = filter_to_script(filter); int err = 0; gensiods count = 0; if (sfilter->state == SCRIPT_OPEN) return handler(cb_data, rcount, buf, buflen, auxdata); script_lock(sfilter); switch(sfilter->state) { case SCRIPT_IN_SUB_OPEN: break; case SCRIPT_IN_OPEN: if (sfilter->gtoscr_len == 0 && buflen > 0) { if (buflen > sizeof(sfilter->gtoscr_buf)) buflen = sizeof(sfilter->gtoscr_buf); memcpy(sfilter->gtoscr_buf, buf, buflen); sfilter->gtoscr_len = buflen; sfilter->gtoscr_pos = 0; count = buflen; gensio_set_write_callback_enable(sfilter->io, true); } break; default: err = GE_NOTREADY; } script_unlock(sfilter); if (!err && rcount) *rcount = count; return err; } static int script_setup(struct gensio_filter *filter) { struct script_filter *sfilter = filter_to_script(filter); sfilter->err = 0; sfilter->scrtog_len = 0; sfilter->scrtog_pos = 0; sfilter->gtoscr_len = 0; sfilter->gtoscr_pos = 0; sfilter->state = SCRIPT_CLOSED; return 0; } static void script_filter_cleanup(struct gensio_filter *filter) { struct script_filter *sfilter = filter_to_script(filter); if (sfilter->io) { gensio_free(sfilter->io); sfilter->io = NULL; } } static void sfilter_free(struct script_filter *sfilter) { if (sfilter->lock) sfilter->o->free_lock(sfilter->lock); if (sfilter->filter) gensio_filter_free_data(sfilter->filter); if (sfilter->str) sfilter->o->free(sfilter->o, sfilter->str); sfilter->o->free(sfilter->o, sfilter); } static void script_free(struct gensio_filter *filter) { struct script_filter *sfilter = filter_to_script(filter); sfilter_free(sfilter); } static int script_set_callback(struct gensio_filter *filter, gensio_filter_cb cb, void *cb_data) { struct script_filter *sfilter = filter_to_script(filter); sfilter->filter_cb = cb; sfilter->filter_cb_data = cb_data; return 0; } static int gensio_script_filter_func(struct gensio_filter *filter, int op, void *func, void *data, gensiods *count, void *buf, const void *cbuf, gensiods buflen, const char *const *auxdata) { switch (op) { case GENSIO_FILTER_FUNC_SET_CALLBACK: return script_set_callback(filter, func, data); case GENSIO_FILTER_FUNC_UL_READ_PENDING: return script_ul_read_pending(filter); case GENSIO_FILTER_FUNC_LL_WRITE_PENDING: return script_ll_write_pending(filter); case GENSIO_FILTER_FUNC_LL_READ_NEEDED: return script_ll_read_needed(filter); case GENSIO_FILTER_FUNC_CHECK_OPEN_DONE: return script_check_open_done(filter, data); case GENSIO_FILTER_FUNC_TRY_CONNECT: return script_try_connect(filter, data); case GENSIO_FILTER_FUNC_TRY_DISCONNECT: return script_try_disconnect(filter, data); case GENSIO_FILTER_FUNC_UL_WRITE_SG: return script_ul_write(filter, func, data, count, cbuf, buflen, auxdata); case GENSIO_FILTER_FUNC_LL_WRITE: return script_ll_write(filter, func, data, count, buf, buflen, auxdata); case GENSIO_FILTER_FUNC_SETUP: return script_setup(filter); case GENSIO_FILTER_FUNC_CLEANUP: script_filter_cleanup(filter); return 0; case GENSIO_FILTER_FUNC_FREE: script_free(filter); return 0; case GENSIO_FILTER_FUNC_CONTROL: return GE_NOTSUP; default: return GE_NOTSUP; } } static struct gensio_filter * gensio_script_filter_raw_alloc(struct gensio_os_funcs *o, char *str) { struct script_filter *sfilter; sfilter = o->zalloc(o, sizeof(*sfilter)); if (!sfilter) return NULL; sfilter->o = o; sfilter->str = str; sfilter->lock = o->alloc_lock(o); if (!sfilter->lock) goto out_nomem; sfilter->filter = gensio_filter_alloc_data(o, gensio_script_filter_func, sfilter); if (!sfilter->filter) goto out_nomem; return sfilter->filter; out_nomem: sfilter_free(sfilter); return NULL; } static int gensio_script_filter_alloc(struct gensio_pparm_info *p, struct gensio_os_funcs *o, const char * const args[], struct gensio_filter **rfilter) { struct gensio_filter *filter; const char *scr = NULL; const char *gensioscr = NULL; char *str; unsigned int i; for (i = 0; args && args[i]; i++) { if (gensio_pparm_value(p, args[i], "script", &scr) > 0) continue; if (gensio_pparm_value(p, args[i], "gensio", &gensioscr) > 0) continue; gensio_pparm_unknown_parm(p, args[i]); return GE_INVAL; } if (!scr && !gensioscr) { gensio_pparm_slog(p, "You must specify either script or gensio"); return GE_INVAL; } if (scr) str = gensio_alloc_sprintf(o, "stdio(noredir-stderr),%s", scr); else str = gensio_strdup(o, gensioscr); filter = gensio_script_filter_raw_alloc(o, str); if (!filter) { o->free(o, str); return GE_NOMEM; } *rfilter = filter; return 0; } static int script_gensio_alloc(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **net) { int err; struct gensio_filter *filter; struct gensio_ll *ll; struct gensio *io; GENSIO_DECLARE_PPGENSIO(p, o, cb, "script", user_data); err = gensio_script_filter_alloc(&p, o, args, &filter); if (err) return err; ll = gensio_gensio_ll_alloc(o, child); if (!ll) { gensio_filter_free(filter); return GE_NOMEM; } gensio_ref(child); /* So gensio_ll_free doesn't free the child if fail */ io = base_gensio_alloc(o, ll, filter, child, "script", cb, user_data); if (!io) { gensio_ll_free(ll); gensio_filter_free(filter); return GE_NOMEM; } gensio_set_attr_from_child(io, child); gensio_free(child); /* Lose the ref we acquired. */ *net = io; return 0; } static int str_to_script_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct gensio *io2; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio(str, o, cb, user_data, &io2); if (err) return err; err = script_gensio_alloc(io2, args, o, cb, user_data, new_gensio); if (err) gensio_free(io2); return err; } struct scriptna_data { struct gensio_accepter *acc; const char **args; struct gensio_os_funcs *o; gensio_accepter_event cb; void *user_data; }; static void scriptna_free(void *acc_data) { struct scriptna_data *nadata = acc_data; if (nadata->args) gensio_argv_free(nadata->o, nadata->args); nadata->o->free(nadata->o, nadata); } static int scriptna_alloc_gensio(void *acc_data, const char * const *iargs, struct gensio *child, struct gensio **rio) { struct scriptna_data *nadata = acc_data; return script_gensio_alloc(child, iargs, nadata->o, NULL, NULL, rio); } static int scriptna_new_child(void *acc_data, void **finish_data, struct gensio_filter **filter) { struct scriptna_data *nadata = acc_data; GENSIO_DECLARE_PPACCEPTER(p, nadata->o, nadata->cb, "script", nadata->user_data); return gensio_script_filter_alloc(&p, nadata->o, nadata->args, filter); } static int scriptna_finish_parent(void *acc_data, void *finish_data, struct gensio *io) { gensio_set_attr_from_child(io, gensio_get_child(io, 0)); return 0; } static int gensio_gensio_acc_script_cb(void *acc_data, int op, void *data1, void *data2, void *data3, const void *data4) { switch (op) { case GENSIO_GENSIO_ACC_ALLOC_GENSIO: return scriptna_alloc_gensio(acc_data, data4, data1, data2); case GENSIO_GENSIO_ACC_NEW_CHILD: return scriptna_new_child(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FINISH_PARENT: return scriptna_finish_parent(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FREE: scriptna_free(acc_data); return 0; default: return GE_NOTSUP; } } static int script_gensio_accepter_alloc(struct gensio_accepter *child, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { struct scriptna_data *nadata; int err; nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) return GE_NOMEM; err = gensio_argv_copy(o, args, NULL, &nadata->args); if (err) { o->free(o, nadata); return err; } nadata->o = o; nadata->cb = cb; nadata->user_data = user_data; err = gensio_gensio_accepter_alloc(child, o, "script", cb, user_data, gensio_gensio_acc_script_cb, nadata, &nadata->acc); if (err) goto out_err; gensio_acc_set_is_reliable(nadata->acc, gensio_acc_is_reliable(child)); gensio_acc_set_is_packet(nadata->acc, gensio_acc_is_packet(child)); gensio_acc_set_is_message(nadata->acc, gensio_acc_is_message(child)); *accepter = nadata->acc; return 0; out_err: scriptna_free(nadata); return err; } static int str_to_script_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { int err; struct gensio_accepter *acc2 = NULL; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio_accepter(str, o, cb, user_data, &acc2); if (!err) { err = script_gensio_accepter_alloc(acc2, args, o, cb, user_data, acc); if (err) gensio_acc_free(acc2); } return err; } int gensio_init_script(struct gensio_os_funcs *o) { int rv; rv = register_filter_gensio(o, "script", str_to_script_gensio, script_gensio_alloc); if (rv) return rv; rv = register_filter_gensio_accepter(o, "script", str_to_script_gensio_accepter, script_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/os_unix_selector.c0000664000175000017500000013246514747451760013011 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* This file holds code to abstract the "select" call and make it easier to use. The main thread lives here, the rest of the code uses a callback interface. Basically, other parts of the program can register file descriptors with this code, when interesting things happen on those file descriptors this code will call routines registered with it. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include /* * Older BSD systems have kevent, but don't have EVFILT_EXCEPT, which * we need for TCP urgent data to work. So just fall back to select * in that case. */ #ifdef HAVE_KEVENT #include #ifdef EVFILT_EXCEPT #define USE_KEVENT #endif #endif #ifdef HAVE_EPOLL_PWAIT #include #define SEL_FD_ADD EPOLL_CTL_ADD #define SEL_FD_DEL EPOLL_CTL_DEL #define SEL_FD_MOD EPOLL_CTL_MOD #elif defined(USE_KEVENT) #define SEL_FD_ADD 1 #define SEL_FD_DEL 2 #define SEL_FD_MOD 3 #else /* These don't do anything if using pselect(). */ #define SEL_FD_ADD 0 #define SEL_FD_DEL 0 #define SEL_FD_MOD 0 #endif #include "errtrig.h" #ifndef EBADFD /* At least MacOS doesn't have EBADFD. */ #define EBADFD EBADF #endif static void * sel_alloc(unsigned int size) { void *d; if (do_errtrig()) return NULL; d = malloc(size); if (d) memset(d, 0, size); return d; } struct sel_runner_s { struct selector_s *sel; sel_runner_func_t func; void *cb_data; int in_use; sel_runner_t *next; }; typedef struct fd_state_s { int deleted; unsigned int use_count; sel_fd_cleared_cb done; sel_runner_t done_runner; int tmp_fd; void *done_cbdata; } fd_state_t; /* The control structure for each file descriptor. */ typedef struct fd_control_s { /* This structure is allocated when an FD is set and it holds whether the FD has been deleted and information to handle the deletion. */ fd_state_t *state; /* Link in the hash list. */ struct fd_control_s *next; /* Handlers for various events on an fd. */ void *data; /* Passed to the handlers */ sel_fd_handler_t handle_read; sel_fd_handler_t handle_write; sel_fd_handler_t handle_except; int fd; /* Keep track of whether the event is enabled here. */ char read_enabled; char write_enabled; char except_enabled; /* On kevent, some I/O types don't handle EXCEPT, track that. */ enum { SEL_RDWR = 0, SEL_RDWR_NOEXC } iodir; #ifdef HAVE_EPOLL_PWAIT /* See the comment in process_fds_epoll() on the use of this. */ uint32_t saved_events; #endif } fd_control_t; typedef struct heap_val_s { /* Set this to the function to call when the timeout occurs. */ sel_timeout_handler_t handler; /* Set this to whatever you like. You can use this to store your own data. */ void *user_data; /* Set this to the time when the timer will go off. */ struct timeval timeout; /* Who owns me? */ struct selector_s *sel; /* Am I currently running? */ int in_heap; /* Am I currently stopped? */ int stopped; /* Have I been freed? */ int freed; /* Am I currently in a handler? */ int in_handler; sel_timeout_handler_t done_handler; void *done_cb_data; } heap_val_t; typedef struct theap_s theap_t; #define heap_s theap_s #define heap_node_s sel_timer_s #define HEAP_EXPORT_NAME(s) theap_ ## s #define HEAP_NAMES_LOCAL static #define HEAP_OUTPUT_PRINTF "(%ld.%7.7ld)" #define HEAP_OUTPUT_DATA pos->timeout.tv_sec, pos->timeout.tv_usec static int cmp_timeval(const struct timeval *tv1, const struct timeval *tv2) { if (tv1->tv_sec < tv2->tv_sec) return -1; if (tv1->tv_sec > tv2->tv_sec) return 1; if (tv1->tv_usec < tv2->tv_usec) return -1; if (tv1->tv_usec > tv2->tv_usec) return 1; return 0; } static int heap_cmp_key(heap_val_t *v1, heap_val_t *v2) { return cmp_timeval(&v1->timeout, &v2->timeout); } #include "heap.h" /* Used to build a list of threads that may need to be woken if a timer on the top of the heap changes, or an FD is added/removed. See i_wake_sel_thread() for more info. */ typedef struct sel_wait_list_s { /* The thread to wake up. */ long thread_id; /* How to wake it. */ sel_send_sig_cb send_sig; void *send_sig_cb_data; /* * The time when the thread is set to wake up. Depending on the * situation we can be using timeval or timespec, so we need both. */ struct timeval wake_time; union { #ifdef BROKEN_PSELECT volatile struct timeval tv; #endif volatile struct timespec ts; } wait_time; #ifdef BROKEN_PSELECT bool signalled; #endif struct sel_wait_list_s *next, *prev; } sel_wait_list_t; struct selector_s { /* This is an hash table of file descriptors. */ fd_control_t *fds[FD_SETSIZE]; /* If something is deleted, we increment this count. This way when a select/epoll returns a non-timeout, we know that we need to ignore it as it may be from the just deleted fd. */ unsigned long fd_del_count; void *fd_lock; /* The timer heap. */ theap_t timer_heap; /* This is a list of items waiting to be woken up because they are sitting in a select. See i_wake_sel_thread() for more info. */ sel_wait_list_t wait_list; void *timer_lock; sel_runner_t *runner_head; sel_runner_t *runner_tail; int wake_sig; /* Used for epoll and kevent. -1 otherwise. */ int evfd; sel_lock_t *(*sel_lock_alloc)(void *cb_data); void (*sel_lock_free)(sel_lock_t *); void (*sel_lock)(sel_lock_t *); void (*sel_unlock)(sel_lock_t *); /* Everything below is only used for select() and ignore for epoll. */ /* These are the offical fd_sets used to track what file descriptors need to be monitored. */ volatile fd_set read_set; volatile fd_set write_set; volatile fd_set except_set; volatile int maxfd; /* The largest file descriptor registered with this code. */ }; static int *handle_set; static void (*handle_sig)(int sig, void *data); static void *handle_sig_data; void sel_set_handle_sig(int *ihandle_set, void (*ihandle_sig)(int sig, void *data), void *ihandle_sig_data) { handle_set = ihandle_set; handle_sig = ihandle_sig; handle_sig_data = ihandle_sig_data; } static void sel_timer_lock(struct selector_s *sel) { if (sel->sel_lock) sel->sel_lock(sel->timer_lock); } static void sel_timer_unlock(struct selector_s *sel) { if (sel->sel_lock) sel->sel_unlock(sel->timer_lock); } static void sel_fd_lock(struct selector_s *sel) { if (sel->sel_lock) sel->sel_lock(sel->fd_lock); } static void sel_fd_unlock(struct selector_s *sel) { if (sel->sel_lock) sel->sel_unlock(sel->fd_lock); } #ifdef USE_PTHREADS #define sel_set_sigmask(newmask, oldmask) \ pthread_sigmask(SIG_SETMASK, newmask, oldmask) #else #define sel_set_sigmask(newmask, oldmask) \ (sigprocmask(SIG_SETMASK, newmask, oldmask) == -1 ? errno : 0) #endif #ifdef BROKEN_PSELECT static void pre_signal(sel_wait_list_t *item) { item->signalled = true; memset(&item->wait_time, 0, sizeof(item->wait_time)); } static void pre_kill_one(struct selector_s *sel, long thread_id) { sel_wait_list_t *item = NULL; item = sel->wait_list.next; while (item != &sel->wait_list) { if (thread_id == item->thread_id) { pre_signal(item); break; } item = item->next; } } #else #define pre_signal(item) do {} while(false) #define pre_kill_one(sel, thread_id) do {} while(false) #endif /* This function will wake the SEL thread. It must be called with the timer lock held, because it messes with timeout. For broken pselect(), where the signal mask is not applied atomically, we have a workaround. The operation is is subtle, but it does work. We have a pointer to the actual timeout passed in to pselect. When we want to wake the pselect, we set the timeout to zero first. That way, if the select has calculated the timeout but has not yet called select, then this will set it to zero (causing it to wait zero time). If select has already been called, then the signal send should wake it up. We only need to do this after we have calculated the timeout, but before we have called select, thus only things in the wait list matter. */ static void i_wake_sel_thread(struct selector_s *sel, struct timeval *new_timeout) { sel_wait_list_t *item; item = sel->wait_list.next; while (item != &sel->wait_list) { if (item->send_sig && (!new_timeout || cmp_timeval(new_timeout, &item->wake_time) < 0)) { pre_signal(item); item->send_sig(item->thread_id, item->send_sig_cb_data); } item = item->next; } } void sel_wake_all(struct selector_s *sel) { sel_timer_lock(sel); i_wake_sel_thread(sel, NULL); sel_timer_unlock(sel); } static void i_sel_wake_first(struct selector_s *sel) { sel_wait_list_t *item; item = sel->wait_list.next; if (item->send_sig && item != &sel->wait_list) { pre_signal(item); item->send_sig(item->thread_id, item->send_sig_cb_data); } } /* See comment on i_wake_sel_thread() for notes on BROKEN_PSELECT. */ void sel_wake_one(struct selector_s *sel, long thread_id, sel_send_sig_cb killer, void *cb_data) { sel_timer_lock(sel); pre_kill_one(sel, thread_id); killer(thread_id, cb_data); sel_timer_unlock(sel); } static void wake_timer_sel_thread(struct selector_s *sel, volatile sel_timer_t *old_top, struct timeval *new_timeout) { if (old_top != theap_get_top(&sel->timer_heap)) /* If the top value changed, restart the waiting threads if required. */ i_wake_sel_thread(sel, new_timeout); } /* Wait list management. These *must* be called with the timer list locked, and the values in the item *must not* change while in the list. */ static void add_sel_wait_list(struct selector_s *sel, sel_wait_list_t *item, sel_send_sig_cb send_sig, void *cb_data, long thread_id, struct timeval *wake_time) { item->thread_id = thread_id; item->send_sig = send_sig; item->send_sig_cb_data = cb_data; item->wake_time = *wake_time; #ifdef BROKEN_PSELECT item->signalled = false; #endif item->next = sel->wait_list.next; item->prev = &sel->wait_list; sel->wait_list.next->prev = item; sel->wait_list.next = item; } static void remove_sel_wait_list(struct selector_s *sel, sel_wait_list_t *item) { item->next->prev = item->prev; item->prev->next = item->next; } /* Initialize a single file descriptor. */ static void init_fd(fd_control_t *fd) { fd->state = NULL; fd->data = NULL; fd->handle_read = NULL; fd->handle_write = NULL; fd->handle_except = NULL; fd->read_enabled = 0; fd->write_enabled = 0; fd->except_enabled = 0; } #ifdef HAVE_EPOLL_PWAIT static int sel_update_fd(struct selector_s *sel, fd_control_t *fdc, int op) { struct epoll_event event; int rv; if (sel->evfd < 0) return 1; memset(&event, 0, sizeof(event)); event.events = EPOLLONESHOT; event.data.fd = fdc->fd; if (fdc->saved_events) { if (op == EPOLL_CTL_DEL) return 0; if (!fdc->read_enabled && !fdc->except_enabled) return 0; fdc->saved_events = 0; op = EPOLL_CTL_ADD; if (fdc->read_enabled) event.events |= EPOLLIN | EPOLLHUP; if (fdc->except_enabled) event.events |= EPOLLERR | EPOLLPRI; } else if (op != EPOLL_CTL_DEL) { if (fdc->read_enabled) event.events |= EPOLLIN | EPOLLHUP; if (fdc->write_enabled) event.events |= EPOLLOUT; if (fdc->except_enabled) event.events |= EPOLLERR | EPOLLPRI; } /* This should only fail due to system problems, and if that's the case, well, we should probably terminate. */ rv = epoll_ctl(sel->evfd, op, fdc->fd, &event); if (rv) { perror("epoll_ctl"); assert(0); } return 0; } #elif defined(USE_KEVENT) static int sel_update_fd(struct selector_s *sel, fd_control_t *fdc, int op) { struct kevent chlist[3]; int rv; struct timespec zerotime = { 0, 0 }; if (sel->evfd < 0) return 1; memset(chlist, 0, sizeof(chlist)); chlist[0].ident = fdc->fd; if (op == SEL_FD_DEL) chlist[0].flags |= EV_DELETE; else chlist[0].flags |= EV_ADD | EV_CLEAR; chlist[1] = chlist[0]; chlist[2] = chlist[0]; chlist[0].filter = EVFILT_READ; chlist[1].filter = EVFILT_WRITE; chlist[2].filter = EVFILT_EXCEPT; if (op != SEL_FD_DEL) { if (fdc->read_enabled) chlist[0].flags |= EV_ENABLE; else chlist[0].flags |= EV_DISABLE; if (fdc->write_enabled) chlist[1].flags |= EV_ENABLE; else chlist[1].flags |= EV_DISABLE; if (fdc->except_enabled) { chlist[2].flags |= EV_ENABLE; chlist[2].fflags |= NOTE_OOB; } else { chlist[2].flags |= EV_DISABLE; } } retry: if (fdc->iodir == SEL_RDWR) { rv = kevent(sel->evfd, chlist, 3, NULL, 0, &zerotime); if (rv == -1) { if (errno == EINVAL) { /* Non-sockets may not accept EVFILT_EXCEPT, retry without. */ fdc->iodir = SEL_RDWR_NOEXC; goto retry; } } } else { rv = kevent(sel->evfd, chlist, 2, NULL, 0, &zerotime); } if (rv) { perror("kevent"); assert(0); } return 0; } #else static int sel_update_fd(struct selector_s *sel, fd_control_t *fdc, int op) { return 1; } #endif static void finish_oldstate(sel_runner_t *runner, void *cbdata) { fd_state_t *oldstate = cbdata; if (oldstate->done) oldstate->done(oldstate->tmp_fd, oldstate->done_cbdata); free(oldstate); } /* Must be called with sel fd lock held. */ static fd_control_t * get_fd(struct selector_s *sel, int fd) { fd_control_t *fdc = sel->fds[fd % FD_SETSIZE]; while (fdc && fdc->fd != fd) fdc = fdc->next; return fdc; } static void valid_fd(struct selector_s *sel, int fd, fd_control_t **rfdc) { fd_control_t *fdc; assert(fd >= 0); fdc = get_fd(sel, fd); assert(fdc != NULL); *rfdc = fdc; } /* Set the handlers for a file descriptor. */ int sel_set_fd_handlers(struct selector_s *sel, int fd, void *data, sel_fd_handler_t read_handler, sel_fd_handler_t write_handler, sel_fd_handler_t except_handler, sel_fd_cleared_cb done) { fd_control_t *fdc; fd_state_t *state, *oldstate = NULL; void *olddata = NULL; int added = 1; if (sel->evfd < 0 && fd >= FD_SETSIZE) return EMFILE; state = sel_alloc(sizeof(*state)); if (!state) return ENOMEM; memset(state, 0, sizeof(*state)); state->done = done; memset(&state->done_runner, 0, sizeof(state->done_runner)); state->done_runner.sel = sel; sel_fd_lock(sel); fdc = get_fd(sel, fd); if (!fdc) { fdc = sel_alloc(sizeof(*fdc)); if (!fdc) { sel_fd_unlock(sel); free(state); return ENOMEM; } fdc->fd = fd; /* Add it to the list. */ fdc->next = sel->fds[fd % FD_SETSIZE]; sel->fds[fd % FD_SETSIZE] = fdc; } if (fdc->state) { oldstate = fdc->state; olddata = fdc->data; added = 0; #ifdef HAVE_EPOLL_PWAIT fdc->saved_events = 0; #endif sel->fd_del_count++; } fdc->state = state; fdc->data = data; fdc->handle_read = read_handler; fdc->handle_write = write_handler; fdc->handle_except = except_handler; if (added) { /* Move maxfd up if necessary. */ if (fd > sel->maxfd) sel->maxfd = fd; if (sel_update_fd(sel, fdc, SEL_FD_ADD)) sel_wake_all(sel); } else { if (sel_update_fd(sel, fdc, SEL_FD_MOD)) sel_wake_all(sel); } sel_fd_unlock(sel); if (oldstate) { oldstate->deleted = 1; if (oldstate->use_count == 0) { oldstate->tmp_fd = fd; oldstate->done_cbdata = olddata; sel_run(&oldstate->done_runner, finish_oldstate, oldstate); } } return 0; } static void i_sel_clear_fd_handler(struct selector_s *sel, int fd, int rpt) { fd_control_t *fdc; fd_state_t *oldstate = NULL; void *olddata = NULL; sel_fd_lock(sel); valid_fd(sel, fd, &fdc); if (fdc->state) { oldstate = fdc->state; olddata = fdc->data; fdc->state = NULL; sel_update_fd(sel, fdc, SEL_FD_DEL); #ifdef HAVE_EPOLL_PWAIT fdc->saved_events = 0; #endif sel->fd_del_count++; } init_fd(fdc); if (sel->evfd < 0) { FD_CLR(fd, (fd_set *) &sel->read_set); FD_CLR(fd, (fd_set *) &sel->write_set); FD_CLR(fd, (fd_set *) &sel->except_set); } /* Move maxfd down if necessary. */ if (fd == sel->maxfd) { while (sel->maxfd >= 0 && (!sel->fds[sel->maxfd] || !sel->fds[sel->maxfd]->state)) sel->maxfd--; } if (oldstate) { oldstate->deleted = 1; if (!rpt) oldstate->done = NULL; if (oldstate->use_count == 0) { oldstate->tmp_fd = fd; oldstate->done_cbdata = olddata; sel_run(&oldstate->done_runner, finish_oldstate, oldstate); } } sel_fd_unlock(sel); } /* Clear the handlers for a file descriptor and remove it from select's monitoring. */ void sel_clear_fd_handlers(struct selector_s *sel, int fd) { i_sel_clear_fd_handler(sel, fd, 1); } /* Clear the handlers for a file descriptor and remove it from select's monitoring, except that fd_cleared is not called. */ void sel_clear_fd_handlers_norpt(struct selector_s *sel, int fd) { i_sel_clear_fd_handler(sel, fd, 0); } /* Set whether the file descriptor will be monitored for data ready to read on the file descriptor. */ void sel_set_fd_read_handler(struct selector_s *sel, int fd, int state) { fd_control_t *fdc; sel_fd_lock(sel); valid_fd(sel, fd, &fdc); if (!fdc->state) goto out; if (state == SEL_FD_HANDLER_ENABLED) { if (fdc->read_enabled) goto out; fdc->read_enabled = 1; if (sel->evfd < 0) FD_SET(fd, (fd_set *) &sel->read_set); } else if (state == SEL_FD_HANDLER_DISABLED) { if (!fdc->read_enabled) goto out; fdc->read_enabled = 0; if (sel->evfd < 0) FD_CLR(fd, (fd_set *) &sel->read_set); } if (sel_update_fd(sel, fdc, SEL_FD_MOD)) sel_wake_all(sel); out: sel_fd_unlock(sel); } /* Set whether the file descriptor will be monitored for when the file descriptor can be written to. */ void sel_set_fd_write_handler(struct selector_s *sel, int fd, int state) { fd_control_t *fdc; sel_fd_lock(sel); valid_fd(sel, fd, &fdc); if (!fdc->state) goto out; if (state == SEL_FD_HANDLER_ENABLED) { if (fdc->write_enabled) goto out; fdc->write_enabled = 1; if (sel->evfd < 0) FD_SET(fd, (fd_set *) &sel->write_set); } else if (state == SEL_FD_HANDLER_DISABLED) { if (!fdc->write_enabled) goto out; fdc->write_enabled = 0; if (sel->evfd < 0) FD_CLR(fd, (fd_set *) &sel->write_set); } if (sel_update_fd(sel, fdc, SEL_FD_MOD)) sel_wake_all(sel); out: sel_fd_unlock(sel); } /* Set whether the file descriptor will be monitored for exceptions on the file descriptor. */ void sel_set_fd_except_handler(struct selector_s *sel, int fd, int state) { fd_control_t *fdc; sel_fd_lock(sel); valid_fd(sel, fd, &fdc); if (!fdc->state) goto out; if (state == SEL_FD_HANDLER_ENABLED) { if (fdc->except_enabled) goto out; fdc->except_enabled = 1; if (sel->evfd < 0) FD_SET(fd, (fd_set *) &sel->except_set); } else if (state == SEL_FD_HANDLER_DISABLED) { if (!fdc->except_enabled) goto out; fdc->except_enabled = 0; if (sel->evfd < 0) FD_CLR(fd, (fd_set *) &sel->except_set); } if (sel_update_fd(sel, fdc, SEL_FD_MOD)) sel_wake_all(sel); out: sel_fd_unlock(sel); } static void diff_timeval(struct timeval *dest, struct timeval *left, struct timeval *right) { if ( (left->tv_sec < right->tv_sec) || ( (left->tv_sec == right->tv_sec) && (left->tv_usec < right->tv_usec))) { /* If left < right, just force to zero, don't allow negative numbers. */ dest->tv_sec = 0; dest->tv_usec = 0; return; } dest->tv_sec = left->tv_sec - right->tv_sec; dest->tv_usec = left->tv_usec - right->tv_usec; while (dest->tv_usec < 0) { dest->tv_usec += 1000000; dest->tv_sec--; } } static void add_timeval(struct timeval *dest, struct timeval *left, struct timeval *right) { dest->tv_sec = left->tv_sec + right->tv_sec; dest->tv_usec = left->tv_usec + right->tv_usec; while (dest->tv_usec > 1000000) { dest->tv_usec -= 1000000; dest->tv_sec++; } } int sel_alloc_timer(struct selector_s *sel, sel_timeout_handler_t handler, void *user_data, sel_timer_t **new_timer) { sel_timer_t *timer; timer = sel_alloc(sizeof(*timer)); if (!timer) return ENOMEM; memset(timer, 0, sizeof(*timer)); timer->val.handler = handler; timer->val.user_data = user_data; timer->val.sel = sel; timer->val.stopped = 1; *new_timer = timer; return 0; } static int sel_stop_timer_i(struct selector_s *sel, sel_timer_t *timer) { int rv = 0; if (timer->val.stopped) rv = ETIMEDOUT; /* * It should not be possible for the timer to be stopped but in * the heap, but that's happening sometimes. (The opposite is * possible, a timer can be not stopped but not in the heap; that * is used to signal a timer restart on return from a timer * handler.) So make sure it's not in the heap. */ if (timer->val.in_heap) { theap_remove(&sel->timer_heap, timer); timer->val.in_heap = 0; } timer->val.stopped = 1; return rv; } int sel_free_timer(sel_timer_t *timer) { struct selector_s *sel = timer->val.sel; int in_handler; sel_timer_lock(sel); if (timer->val.in_heap) sel_stop_timer_i(sel, timer); timer->val.freed = 1; in_handler = timer->val.in_handler; sel_timer_unlock(sel); if (!in_handler) free(timer); return 0; } int sel_start_timer(sel_timer_t *timer, struct timeval *timeout) { struct selector_s *sel = timer->val.sel; volatile sel_timer_t *old_top; sel_timer_lock(sel); if (timer->val.in_heap) { sel_timer_unlock(sel); return EBUSY; } old_top = theap_get_top(&sel->timer_heap); timer->val.timeout = *timeout; if (!timer->val.in_handler) { /* Wait until the handler returns to start the timer. */ theap_add(&sel->timer_heap, timer); timer->val.in_heap = 1; } timer->val.stopped = 0; wake_timer_sel_thread(sel, old_top, timeout); sel_timer_unlock(sel); return 0; } int sel_stop_timer(sel_timer_t *timer) { struct selector_s *sel = timer->val.sel; int rv; sel_timer_lock(sel); rv = sel_stop_timer_i(sel, timer); sel_timer_unlock(sel); return rv; } int sel_stop_timer_with_done(sel_timer_t *timer, sel_timeout_handler_t done_handler, void *cb_data) { struct selector_s *sel = timer->val.sel; int rv = EBUSY; sel_timer_lock(sel); if (timer->val.done_handler) goto out_unlock; rv = ETIMEDOUT; if (timer->val.stopped || timer->val.in_handler) goto out_unlock; rv = 0; timer->val.stopped = 1; timer->val.done_handler = done_handler; timer->val.done_cb_data = cb_data; /* * We don't want to run the done handler here to avoid locking * issues. So set it in_handler and stick it on the top of the * heap with an immediate timeout so it will be processed now. */ timer->val.in_handler = 1; if (timer->val.in_heap) { theap_remove(&sel->timer_heap, timer); timer->val.in_heap = 0; } sel_get_monotonic_time(&timer->val.timeout); theap_add(&sel->timer_heap, timer); timer->val.in_heap = 1; out_unlock: sel_timer_unlock(sel); return rv; } void sel_get_monotonic_time(struct timeval *tv) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); tv->tv_sec = ts.tv_sec; tv->tv_usec = (ts.tv_nsec + 500) / 1000; } /* * Process timers on selector. The timeout is always set, to a very * long value if no timers are waiting. Note that this *must* be * called with sel->timer_lock held. Note that if this processes * any timers, the timeout will be set to { 0,0 }. */ static void process_timers(struct selector_s *sel, unsigned int *count, volatile struct timeval *timeout, struct timeval *abstime) { struct timeval now; sel_timer_t *timer; timer = theap_get_top(&sel->timer_heap); sel_get_monotonic_time(&now); while (timer && cmp_timeval(&now, &timer->val.timeout) >= 0) { theap_remove(&(sel->timer_heap), timer); timer->val.in_heap = 0; timer->val.stopped = 1; /* * A timer may be in a handler here if it has been stopped with * a done_handler. In that case the timer was stopped, so we * don't call the main handler. */ if (!timer->val.in_handler) { timer->val.in_handler = 1; sel_timer_unlock(sel); timer->val.handler(sel, timer, timer->val.user_data); sel_timer_lock(sel); } (*count)++; if (timer->val.done_handler) { sel_timeout_handler_t done_handler = timer->val.done_handler; void *done_cb_data = timer->val.done_cb_data; timer->val.done_handler = NULL; timer->val.in_handler = 1; sel_timer_unlock(sel); done_handler(sel, timer, done_cb_data); sel_timer_lock(sel); } timer->val.in_handler = 0; if (timer->val.freed) free(timer); else if (!timer->val.stopped) { /* We were restarted while in the handler. */ theap_add(&sel->timer_heap, timer); timer->val.in_heap = 1; } timer = theap_get_top(&sel->timer_heap); } if (*count) { /* If called, set the timeout to zero. */ timeout->tv_sec = 0; timeout->tv_usec = 0; *abstime = now; } else if (timer) { diff_timeval((struct timeval *) timeout, (struct timeval *) &timer->val.timeout, &now); *abstime = timer->val.timeout; } else { /* No timers, just set a long time. */ timeout->tv_sec = 100000; timeout->tv_usec = 0; now.tv_sec +=timeout->tv_sec; *abstime = now; } } int sel_alloc_runner(struct selector_s *sel, sel_runner_t **new_runner) { sel_runner_t *runner; runner = sel_alloc(sizeof(*runner)); if (!runner) return ENOMEM; memset(runner, 0, sizeof(*runner)); runner->sel = sel; *new_runner = runner; return 0; } int sel_free_runner(sel_runner_t *runner) { struct selector_s *sel = runner->sel; sel_timer_lock(sel); if (runner->in_use) { sel_timer_unlock(sel); return EBUSY; } sel_timer_unlock(sel); free(runner); return 0; } int sel_run(sel_runner_t *runner, sel_runner_func_t func, void *cb_data) { struct selector_s *sel = runner->sel; sel_timer_lock(sel); if (runner->in_use) { sel_timer_unlock(sel); return EBUSY; } runner->func = func; runner->cb_data = cb_data; runner->next = NULL; runner->in_use = 1; if (sel->runner_tail) { sel->runner_tail->next = runner; sel->runner_tail = runner; } else { sel->runner_head = runner; sel->runner_tail = runner; } /* Make sure someone is awake to run the runner. */ i_sel_wake_first(sel); sel_timer_unlock(sel); return 0; } static unsigned int process_runners(struct selector_s *sel) { sel_runner_t *runner = sel->runner_head, *next_runner; int count = 0; sel->runner_head = NULL; sel->runner_tail = NULL; while (runner) { sel_runner_func_t func; void *cb_data; next_runner = runner->next; runner->in_use = 0; func = runner->func; cb_data = runner->cb_data; sel_timer_unlock(sel); func(runner, cb_data); count++; sel_timer_lock(sel); runner = next_runner; } return count; } static void handle_selector_call(struct selector_s *sel, fd_control_t *fdc, volatile fd_set *fdset, int enabled, sel_fd_handler_t handler) { void *data; fd_state_t *state; if (handler == NULL) { /* Somehow we don't have a handler for this. Just shut it down. */ if (fdset) FD_CLR(fdc->fd, (fd_set *) fdset); return; } if (!enabled) /* The value was cleared, ignore it. */ return; data = fdc->data; state = fdc->state; if (!state) /* * Can happen because we are called multiple times in succession. * Just ignore it. */ return; state->use_count++; sel_fd_unlock(sel); handler(fdc->fd, data); sel_fd_lock(sel); state->use_count--; if (state->deleted && state->use_count == 0) { fdc->state = NULL; if (state->done) { sel_fd_unlock(sel); state->done(fdc->fd, data); sel_fd_lock(sel); } free(state); } } static void setup_my_sigmask(sigset_t *sigmask, sigset_t *isigmask) { if (isigmask) { *sigmask = *isigmask; } else { sel_set_sigmask(NULL, sigmask); } } /* * return == 0 when timeout * > 0 when successful * < 0 when error */ static int process_fds(struct selector_s *sel, sel_wait_list_t *item, sigset_t *isigmask) { fd_set tmp_read_set; fd_set tmp_write_set; fd_set tmp_except_set; int i; int err; int num_fds; sigset_t sigmask; unsigned long entry_fd_del_count; fd_control_t *fdc; setup_my_sigmask(&sigmask, isigmask); sel_fd_lock(sel); entry_fd_del_count = sel->fd_del_count; memcpy(&tmp_read_set, (void *) &sel->read_set, sizeof(tmp_read_set)); memcpy(&tmp_write_set, (void *) &sel->write_set, sizeof(tmp_write_set)); memcpy(&tmp_except_set, (void *) &sel->except_set, sizeof(tmp_except_set)); num_fds = sel->maxfd + 1; sel_fd_unlock(sel); if (sel->wake_sig) sigdelset(&sigmask, sel->wake_sig); #ifdef BROKEN_PSELECT do { int old_errno; sigset_t oldmask; bool time_fixed = false; /* * A signal may have been sent before this process was queued on a * wait queue, so we may have the signal pending without having * been queued or had the time set to zero. We detect that here * and set things up properly. */ if (sel->wake_sig) { sigpending(&oldmask); if (!item->signalled && sigismember(&oldmask, sel->wake_sig)) { pre_signal(item); time_fixed = true; } } err = sel_set_sigmask(&sigmask, &oldmask); if (err < 0) return err; /* If we don't have the wake sig blocked, fix it. */ if (sel->wake_sig && !sigismember(&oldmask, sel->wake_sig)) { sigaddset(&oldmask, sel->wake_sig); /* * Make sure this returns immediately, just in case we * were signalled. */ item->wait_time.tv.tv_sec = 0; item->wait_time.tv.tv_usec = 0; time_fixed = true; } err = select(num_fds, &tmp_read_set, &tmp_write_set, &tmp_except_set, (struct timeval *) &item->wait_time.tv); if (time_fixed && err == 0) { err = -1; errno = EINTR; } old_errno = errno; sel_set_sigmask(&oldmask, NULL); errno = old_errno; } while(false); #else err = pselect(num_fds, &tmp_read_set, &tmp_write_set, &tmp_except_set, (struct timespec *) &item->wait_time.ts, &sigmask); #endif if (err < 0) { if (errno == EBADF || errno == EBADFD) /* We raced, just retry it. No loop here, timeout may be wrong. */ errno = EINTR; goto out; } /* We got some I/O. */ sel_fd_lock(sel); if (entry_fd_del_count != sel->fd_del_count) /* Something was deleted from the FD set, don't process this as it may be from the old fd wakeup. */ goto out_unlock; for (i = 0; i <= sel->maxfd; i++) { if (FD_ISSET(i, &tmp_read_set)) { valid_fd(sel, i, &fdc); handle_selector_call(sel, fdc, &sel->read_set, fdc->read_enabled, fdc->handle_read); } if (FD_ISSET(i, &tmp_write_set)) { valid_fd(sel, i, &fdc); handle_selector_call(sel, fdc, &sel->write_set, fdc->write_enabled, fdc->handle_write); } if (FD_ISSET(i, &tmp_except_set)) { valid_fd(sel, i, &fdc); handle_selector_call(sel, fdc, &sel->except_set, fdc->except_enabled, fdc->handle_except); } } out_unlock: sel_fd_unlock(sel); out: return err; } #ifdef HAVE_EPOLL_PWAIT static int process_fds_epoll(struct selector_s *sel, sel_wait_list_t *item, sigset_t *isigmask) { int rv; struct epoll_event event; int timeout; sigset_t sigmask; fd_control_t *fdc; unsigned long entry_fd_del_count; setup_my_sigmask(&sigmask, isigmask); if (item->wait_time.ts.tv_sec > 600) /* Don't wait over 10 minutes, to work around an old epoll bug and avoid issues with timeout overflowing on 64-bit systems, which is much larger that 10 minutes, but who cares. */ timeout = 600 * 1000; else timeout = ((item->wait_time.ts.tv_sec * 1000) + (item->wait_time.ts.tv_nsec + 999999) / 1000000); if (sel->wake_sig) sigdelset(&sigmask, sel->wake_sig); sel_fd_lock(sel); entry_fd_del_count = sel->fd_del_count; sel_fd_unlock(sel); rv = epoll_pwait(sel->evfd, &event, 1, timeout, &sigmask); if (rv <= 0) return rv; sel_fd_lock(sel); valid_fd(sel, event.data.fd, &fdc); if (entry_fd_del_count != sel->fd_del_count) /* Something was deleted from the FD set, don't process this as it may be from the old fd wakeup. */ goto rearm; if (event.events & (EPOLLHUP | EPOLLERR)) { /* * The crazy people that designed epoll made it so that EPOLLHUP * and EPOLLERR always wake it up, even if they are not set. That * makes this fairly inconvenient, because we don't want to wake * up in that case unless we explicitly ask for it. Fortunately, * in those cases we can pretty easily simulate it by just deleting * it, since in those cases you will not get anything but an * EPOLLHUP or EPOLLERR, anyway, and then doing the callback * by hand. */ sel_update_fd(sel, fdc, SEL_FD_DEL); fdc->saved_events = event.events & (EPOLLHUP | EPOLLERR); /* * Have it handle read data, too, so if there is a pending * error it will get handled. */ event.events |= EPOLLIN; } if (event.events & (EPOLLIN | EPOLLHUP)) handle_selector_call(sel, fdc, NULL, fdc->read_enabled, fdc->handle_read); if (event.events & EPOLLOUT) handle_selector_call(sel, fdc, NULL, fdc->write_enabled, fdc->handle_write); if (event.events & (EPOLLPRI | EPOLLERR)) handle_selector_call(sel, fdc, NULL, fdc->except_enabled, fdc->handle_except); rearm: /* Rearm the event. Remember it could have been deleted in the handler. */ if (fdc->state) sel_update_fd(sel, fdc, SEL_FD_MOD); sel_fd_unlock(sel); return rv; } int sel_setup_forked_process(struct selector_s *sel) { int i; /* * More epoll stupidity. In a forked process we must create a new * epoll because the epoll state is shared between a parent and a * child. If it worked like it should, each epoll instance would * be independent. If you don't do this, disabling an fd in the * child disables the parent, too, and vice versa. */ close(sel->evfd); sel->evfd = epoll_create(32768); if (sel->evfd == -1) { return errno; } for (i = 0; i <= sel->maxfd; i++) { fd_control_t *fdc = sel->fds[i]; if (fdc && fdc->state) sel_update_fd(sel, fdc, SEL_FD_ADD); } return 0; } #elif defined(USE_KEVENT) static int process_fds_kevent(struct selector_s *sel, sel_wait_list_t *item, sigset_t *isigmask) { int rv, old_errno; struct kevent event; #define MAX_KEVENT_SIGS 10 struct kevent sigs[MAX_KEVENT_SIGS]; sigset_t sigmask, oldmask, pendmask; fd_control_t *fdc; unsigned long entry_fd_del_count; unsigned int i, j; bool time_fixed = false; setup_my_sigmask(&sigmask, isigmask); if (sel->wake_sig) sigdelset(&sigmask, sel->wake_sig); sel_fd_lock(sel); entry_fd_del_count = sel->fd_del_count; sel_fd_unlock(sel); /* * kevent doesn't have a pwait version. From what I can tell, * BSDs all have broken pselect. See comments in process_fds() * about this. */ rv = sel_set_sigmask(NULL, &oldmask); if (rv < 0) return rv; if (sel->wake_sig) { sigpending(&pendmask); if (!item->signalled && sigismember(&pendmask, sel->wake_sig)) { pre_signal(item); time_fixed = true; } } /* * If a signal is blocked in the running thread but would be * unblocked by the setmask, leave it blocked for the thread and * return it from kevent. */ for (i = 0, j = 0; handle_set && handle_set[i]; i++) { assert(j < MAX_KEVENT_SIGS); if (!sigismember(&oldmask, handle_set[i])) { sigaddset(&oldmask, handle_set[i]); item->wait_time.tv.tv_sec = 0; item->wait_time.tv.tv_usec = 0; time_fixed = true; } if (!sigismember(&sigmask, handle_set[i])) { EV_SET(&sigs[j], handle_set[i], EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, 0); j++; sigaddset(&sigmask, handle_set[i]); } } rv = sel_set_sigmask(&sigmask, NULL); if (rv < 0) return rv; /* If we don't have the wake sig blocked, fix it. */ if (sel->wake_sig && !sigismember(&oldmask, sel->wake_sig)) { sigaddset(&oldmask, sel->wake_sig); /* * Make sure this returns immediately, just in case we * were signalled. */ item->wait_time.tv.tv_sec = 0; item->wait_time.tv.tv_usec = 0; time_fixed = true; } rv = kevent(sel->evfd, sigs, j, &event, 1, (struct timespec *) &item->wait_time.ts); if (time_fixed && rv == 0) { rv = -1; errno = EINTR; } old_errno = errno; sel_set_sigmask(&oldmask, NULL); errno = old_errno; if (rv <= 0) return rv; if (event.filter == EVFILT_SIGNAL) { handle_sig(event.ident, handle_sig_data); errno = EINTR; return -1; } sel_fd_lock(sel); valid_fd(sel, event.ident, &fdc); if (entry_fd_del_count != sel->fd_del_count) /* Something was deleted from the FD set, don't process this as it may be from the old fd wakeup. */ goto rearm; if (event.filter == EVFILT_READ) { handle_selector_call(sel, fdc, NULL, fdc->read_enabled, fdc->handle_read); } else if (event.filter == EVFILT_WRITE) { handle_selector_call(sel, fdc, NULL, fdc->write_enabled, fdc->handle_write); } else if (event.filter == EVFILT_EXCEPT) { handle_selector_call(sel, fdc, NULL, fdc->except_enabled, fdc->handle_except); } rearm: /* Rearm the event. Remember it could have been deleted in the handler. */ if (fdc->state) sel_update_fd(sel, fdc, SEL_FD_MOD); sel_fd_unlock(sel); return rv; } int sel_setup_forked_process(struct selector_s *sel) { int i; /* * More epoll stupidity. In a forked process we must create a new * epoll because the epoll state is shared between a parent and a * child. If it worked like it should, each epoll instance would * be independent. If you don't do this, disabling an fd in the * child disables the parent, too, and vice versa. */ close(sel->evfd); sel->evfd = kqueue(); if (sel->evfd == -1) { return errno; } for (i = 0; i <= sel->maxfd; i++) { fd_control_t *fdc = sel->fds[i]; if (fdc && fdc->state) sel_update_fd(sel, fdc, SEL_FD_ADD); } return 0; } #else int sel_setup_forked_process(struct selector_s *sel) { /* Nothing to do. */ return 0; } #endif int sel_select_intr_sigmask(struct selector_s *sel, sel_send_sig_cb send_sig, long thread_id, void *cb_data, struct timeval *timeout, sigset_t *sigmask) { int err = 0, old_errno; struct timeval wake_time, tmp_timeout; sel_wait_list_t wait_entry; unsigned int count; struct timeval end = { 0, 0 }, now; int user_timeout = 0; if (timeout) { sel_get_monotonic_time(&now); add_timeval(&end, &now, timeout); } sel_timer_lock(sel); count = process_runners(sel); process_timers(sel, &count, &tmp_timeout, &wake_time); if (count == 0 && !sel->runner_head) { /* Didn't do anything and no runners waiting, wait for something. */ if (timeout) { if (cmp_timeval(&tmp_timeout, timeout) >= 0) { tmp_timeout = *timeout; user_timeout = 1; } } memset(&wait_entry, 0, sizeof(wait_entry)); #ifdef BROKEN_PSELECT if (sel->evfd >= 0) { wait_entry.wait_time.ts.tv_sec = tmp_timeout.tv_sec; wait_entry.wait_time.ts.tv_nsec = tmp_timeout.tv_usec * 1000; } else { wait_entry.wait_time.tv = tmp_timeout; } #else wait_entry.wait_time.ts.tv_sec = tmp_timeout.tv_sec; wait_entry.wait_time.ts.tv_nsec = tmp_timeout.tv_usec * 1000; #endif add_sel_wait_list(sel, &wait_entry, send_sig, cb_data, thread_id, &wake_time); sel_timer_unlock(sel); #ifdef HAVE_EPOLL_PWAIT if (sel->evfd >= 0) err = process_fds_epoll(sel, &wait_entry, sigmask); else #endif #ifdef USE_KEVENT if (sel->evfd >= 0) err = process_fds_kevent(sel, &wait_entry, sigmask); else #endif err = process_fds(sel, &wait_entry, sigmask); old_errno = errno; sel_timer_lock(sel); #ifdef BROKEN_PSELECT if (wait_entry.signalled && !err) { err = -1; old_errno = EINTR; } #endif if (err == 0) { if (!user_timeout) { /* * Only return a timeout if we waited on the user's timeout * Otherwise there is a timer to process. */ count++; } } remove_sel_wait_list(sel, &wait_entry); /* * Process runners before and after the wait. This way any * runners added while waiting will get processed. Otherwise * we would have to wake up other threads so the runners get * handled immediately. Do not add to the count, though, if * we timed out we want to alert the user of that. */ process_runners(sel); } sel_timer_unlock(sel); if (timeout) { sel_get_monotonic_time(&now); diff_timeval(timeout, &end, &now); } if (err < 0) { errno = old_errno; return err; } return err + count; } int sel_select_intr(struct selector_s *sel, sel_send_sig_cb send_sig, long thread_id, void *cb_data, struct timeval *timeout) { return sel_select_intr_sigmask(sel, send_sig, thread_id, cb_data, timeout, NULL); } int sel_select(struct selector_s *sel, sel_send_sig_cb send_sig, long thread_id, void *cb_data, struct timeval *timeout) { int err; err = sel_select_intr_sigmask(sel, send_sig, thread_id, cb_data, timeout, NULL); if (err < 0 && errno == EINTR) /* * If we get an EINTR, we don't want to report a timeout. Just * return that we did something. */ return 1; return err; } /* The main loop for the program. This will select on the various sets, then scan for any available I/O to process. It also monitors the time and call the timeout handlers periodically. */ int sel_select_loop(struct selector_s *sel, sel_send_sig_cb send_sig, long thread_id, void *cb_data) { for (;;) { int err = sel_select(sel, send_sig, thread_id, cb_data, NULL); if ((err < 0) && (errno != EINTR)) { err = errno; /* An error occurred. */ /* An error is bad, we need to abort. */ syslog(LOG_ERR, "select_loop() - select: %m"); return err; } } } /* Initialize the select code. */ int sel_alloc_selector_thread(struct selector_s **new_selector, int wake_sig, sel_lock_t *(*sel_lock_alloc)(void *cb_data), void (*sel_lock_free)(sel_lock_t *), void (*sel_lock)(sel_lock_t *), void (*sel_unlock)(sel_lock_t *), void *cb_data) { struct selector_s *sel; int rv; sigset_t sigset; sel = sel_alloc(sizeof(*sel)); if (!sel) return ENOMEM; memset(sel, 0, sizeof(*sel)); sel->sel_lock_alloc = sel_lock_alloc; sel->sel_lock_free = sel_lock_free; sel->sel_lock = sel_lock; sel->sel_unlock = sel_unlock; /* The list is initially empty. */ sel->wait_list.next = &sel->wait_list; sel->wait_list.prev = &sel->wait_list; sel->wake_sig = wake_sig; FD_ZERO((fd_set *) (fd_set *) &sel->read_set); FD_ZERO((fd_set *) (fd_set *) &sel->write_set); FD_ZERO((fd_set *) (fd_set *) &sel->except_set); memset(sel->fds, 0, sizeof(sel->fds)); theap_init(&sel->timer_heap); if (sel->sel_lock_alloc) { sel->timer_lock = sel->sel_lock_alloc(cb_data); if (!sel->timer_lock) { free(sel); return ENOMEM; } sel->fd_lock = sel->sel_lock_alloc(cb_data); if (!sel->fd_lock) { sel->sel_lock_free(sel->fd_lock); free(sel); return ENOMEM; } } sigemptyset(&sigset); sigaddset(&sigset, wake_sig); rv = sel_set_sigmask(&sigset, NULL); if (rv) { if (sel->sel_lock_alloc) { sel->sel_lock_free(sel->fd_lock); sel->sel_lock_free(sel->timer_lock); } free(sel); return rv; } sel->evfd = -1; #ifdef HAVE_EPOLL_PWAIT sel->evfd = epoll_create(32768); if (sel->evfd == -1) syslog(LOG_ERR, "Unable to set up epoll, falling back to select: %m"); #endif #ifdef USE_KEVENT sel->evfd = kqueue(); if (sel->evfd == -1) syslog(LOG_ERR, "Unable to set up kevent, falling back to select: %m"); #endif *new_selector = sel; return 0; } int sel_alloc_selector_nothread(struct selector_s **new_selector) { return sel_alloc_selector_thread(new_selector, 0, NULL, NULL, NULL, NULL, NULL); } int sel_free_selector(struct selector_s *sel) { sel_timer_t *elem; unsigned int i; elem = theap_get_top(&(sel->timer_heap)); while (elem) { theap_remove(&(sel->timer_heap), elem); elem->val.in_heap = 0; free(elem); elem = theap_get_top(&(sel->timer_heap)); } if (sel->evfd >= 0) close(sel->evfd); for (i = 0; i < FD_SETSIZE; i++) { while (sel->fds[i]) { fd_control_t *fdc = sel->fds[i]; sel->fds[i] = fdc->next; if (fdc->state) free(fdc->state); free(fdc); } } if (sel->fd_lock) sel->sel_lock_free(sel->fd_lock); if (sel->timer_lock) sel->sel_lock_free(sel->timer_lock); free(sel); return 0; } gensio-3.0.0/lib/heap.h0000664000175000017500000003334214731537702010333 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* * This is a heap C "generic", it allows you to define a heap for a * given type. To us this, create a file with something like: * * typedef struct heap_val_s { int a; } heap_val_t; -- The included element * * #define heap_node_s test_heap_node_s -- This is the name of the heap * element's structure. * #define heap_s test_heap_s -- This is the name of the heap type. * #define HEAP_EXPORT_NAME(s) test_ ## s -- This will prepend all the * names with a string, here * "test_". * #define HEAP_NAMES_LOCAL static -- This is only if you want the symbols * defined here to be local * static int * heap_cmp_key(heap_t val1, heap_t val2) * { * if (val1.a < val2.a) { * return -1; * } else if (val1.a > val2.a) { * return 1; * } else { * return 0; * } * } * #include * * The included element heap_val_t and the comparison function * heap_cmp_key may be #define's if you desire. * * The heap.h code will create a structure with the name defined by * heap_node_s that contains the element "val", which is heap_val_t. * It also contains other items you should not touch. The heap_node_s * structure is what you deal with. * * It will also create a structure with the named defined by heap_s * for the heap itself. * * The following functions are created, where xxx_ is the value you * give to HEAP_EXPORT_NAME(): * * void xxx_init(sruct heap_s *heap); * struct heap_node_s *xxx_get_top(sruct heap_s *heap); * void xxx_add(struct heap_s *heap, struct heap_node_s *elem); * void xxx_remove(struct heap_s *heap, struct heap_node_s *elem); * * To use the heap, first define or allocate a struct heap_s, and call * xxx_init() with it. * * To add an element to the heap, allocate a struct heap_node_s, fill * in your values, and then call xxx_add(heap, elem). You can only add * an element to the heap once. * * To remove an element, pass it in to xxx_remove(heap, elem). Then * you may free the element. * * The heap does not track membership, so be sure that the element * belongs to the proper heap. * * If you define HEAP_DEBUG, you also need to define the following: * * #define HEAP_OUTPUT_PRINTF "(%d)" * #define HEAP_OUTPUT_DATA pos->val.a * */ struct heap_node_s { heap_val_t val; /* Links for the heap. */ struct heap_node_s *left, *right, *up; }; struct heap_s { struct heap_node_s *top, *last; }; #ifndef HEAP_NAMES_LOCAL #define HEAP_NAMES_LOCAL #endif #ifdef HEAP_DEBUG #include static FILE **HEAP_EXPORT_NAME(debug_out) = &stderr; static void HEAP_EXPORT_NAME(print_item)(struct heap_node_s *pos, int indent) { int i; for (i = 0; i < indent; i++) fprintf(*HEAP_EXPORT_NAME(debug_out), " "); fprintf(*HEAP_EXPORT_NAME(debug_out), " %p: %p %p %p " HEAP_OUTPUT_PRINTF "\n", pos, pos->left, pos->right, pos->up, HEAP_OUTPUT_DATA); if (pos->left) HEAP_EXPORT_NAME(print_item)(pos->left, indent + 1); if (pos->right) HEAP_EXPORT_NAME(print_item)(pos->right, indent + 1); } static void HEAP_EXPORT_NAME(print)(struct heap_s *heap) { fprintf(*HEAP_EXPORT_NAME(debug_out), "top=%p\n", heap->top); if (heap->top) HEAP_EXPORT_NAME(print_item)(heap->top, 0); fprintf(*HEAP_EXPORT_NAME(debug_out), "last=%p\n", heap->last); fflush(*HEAP_EXPORT_NAME(debug_out)); } static void HEAP_EXPORT_NAME(check_item)(struct heap_node_s *curr, unsigned int *depth, unsigned int max_depth, struct heap_node_s **real_last, int *found_last) { if (! curr->left) { if (curr->right) { fprintf(*HEAP_EXPORT_NAME(debug_out), "Tree corrupt B\n"); *((int *) NULL) = 0; } else if (*depth > max_depth) { fprintf(*HEAP_EXPORT_NAME(debug_out), "Tree corrupt C\n"); *((int *) NULL) = 0; } else if ((*depth + 1) < max_depth) { fprintf(*HEAP_EXPORT_NAME(debug_out), "Tree corrupt D\n"); *((int *) NULL) = 0; } else if ((*found_last) && (*depth == max_depth)) { fprintf(*HEAP_EXPORT_NAME(debug_out), "Tree corrupt E\n"); *((int *) NULL) = 0; } else if (*depth == max_depth) { *real_last = curr; } else { *found_last = 1; } } else { if (curr->left->up != curr) { fprintf(*HEAP_EXPORT_NAME(debug_out), "Tree corrupt I\n"); *((int *) NULL) = 0; } if (heap_cmp_key(&(curr->left->val), &(curr->val)) < 0) { fprintf(*HEAP_EXPORT_NAME(debug_out), "Tree corrupt K\n"); *((int *) NULL) = 0; } (*depth)++; HEAP_EXPORT_NAME(check_item)(curr->left, depth, max_depth, real_last, found_last); (*depth)--; if (! curr->right) { if (*depth != (max_depth - 1)) { fprintf(*HEAP_EXPORT_NAME(debug_out), "Tree corrupt F\n"); *((int *) NULL) = 0; } if (*found_last) { fprintf(*HEAP_EXPORT_NAME(debug_out), "Tree corrupt G\n"); *((int *) NULL) = 0; } *found_last = 1; } else { if (curr->right->up != curr) { fprintf(*HEAP_EXPORT_NAME(debug_out), "Tree corrupt H\n"); *((int *) NULL) = 0; } if (heap_cmp_key(&(curr->right->val), &(curr->val)) < 0) { fprintf(*HEAP_EXPORT_NAME(debug_out), "Tree corrupt L\n"); *((int *) NULL) = 0; } (*depth)++; HEAP_EXPORT_NAME(check_item)(curr->right, depth, max_depth, real_last, found_last); (*depth)--; } } } static void HEAP_EXPORT_NAME(check)(struct heap_s *heap) { unsigned int depth = 0, max_depth = 0; int found_last = 0; struct heap_node_s *real_last; if (!heap->top) { if (heap->last) { fprintf(*HEAP_EXPORT_NAME(debug_out), "Tree corrupt A\n"); *((int *) NULL) = 0; } return; } real_last = heap->top; while (real_last->left) { real_last = real_last->left; max_depth++; } real_last = NULL; HEAP_EXPORT_NAME(check_item)(heap->top, &depth, max_depth, &real_last, &found_last); if (real_last != heap->last) { fprintf(*HEAP_EXPORT_NAME(debug_out), "Tree corrupt J\n"); *((int *) NULL) = 0; } fflush(*HEAP_EXPORT_NAME(debug_out)); } #endif static void HEAP_EXPORT_NAME(find_next_pos)(struct heap_node_s *curr, struct heap_node_s ***next, struct heap_node_s **parent) { unsigned int upcount = 0; if (curr->up && (curr->up->left == curr)) { /* We are a left node, the next node is just my right partner. */ *next = &(curr->up->right); *parent = curr->up; return; } /* While we are a right node, go up. */ while (curr->up && (curr->up->right == curr)) { upcount++; curr = curr->up; } if (curr->up) { /* Now we are a left node, trace up then back down. */ curr = curr->up->right; upcount--; } while (upcount) { curr = curr->left; upcount--; } *next = &(curr->left); *parent = curr; } static void HEAP_EXPORT_NAME(find_prev_elem)(struct heap_node_s *curr, struct heap_node_s **prev) { unsigned int upcount = 0; if (curr->up && (curr->up->right == curr)) { /* We are a right node, the previous node is just my left partner. */ *prev = curr->up->left; return; } /* While we are a left node, go up. */ while (curr->up && (curr->up->left == curr)) { upcount++; curr = curr->up; } if (curr->up) { /* Now we are a right node, trace up then back down. */ curr = curr->up->left; } else { /* We are going to the previous "row". */ upcount--; } while (upcount) { curr = curr->right; upcount--; } *prev = curr; } static void HEAP_EXPORT_NAME(send_up)(struct heap_node_s *elem, struct heap_node_s **top, struct heap_node_s **last) { struct heap_node_s *tmp1, *tmp2, *parent; parent = elem->up; while (parent && (heap_cmp_key(&elem->val, &parent->val) < 0)) { tmp1 = elem->left; tmp2 = elem->right; if (parent->left == elem) { elem->left = parent; elem->right = parent->right; if (elem->right) elem->right->up = elem; } else { elem->right = parent; elem->left = parent->left; if (elem->left) elem->left->up = elem; } elem->up = parent->up; if (parent->up) { if (parent->up->left == parent) { parent->up->left = elem; } else { parent->up->right = elem; } } else { *top = elem; } parent->up = elem; parent->left = tmp1; if (parent->left) parent->left->up = parent; parent->right = tmp2; if (parent->right) parent->right->up = parent; if (*last == elem) *last = parent; parent = elem->up; } } static void HEAP_EXPORT_NAME(send_down)(struct heap_node_s *elem, struct heap_node_s **top, struct heap_node_s **last) { struct heap_node_s *tmp1, *tmp2, *left, *right; left = elem->left; while (left) { right = elem->right; /* Choose the smaller of the two below me to swap with. */ if ((right) && (heap_cmp_key(&left->val, &right->val) > 0)) { if (heap_cmp_key(&elem->val, &right->val) > 0) { /* Swap with the right element. */ tmp1 = right->left; tmp2 = right->right; if (elem->up) { if (elem->up->left == elem) { elem->up->left = right; } else { elem->up->right = right; } } else { *top = right; } right->up = elem->up; elem->up = right; right->left = elem->left; right->right = elem; elem->left = tmp1; elem->right = tmp2; if (right->left) right->left->up = right; if (elem->left) elem->left->up = elem; if (elem->right) elem->right->up = elem; if (*last == right) *last = elem; } else goto done; } else { /* The left element is smaller, or the right doesn't exist. */ if (heap_cmp_key(&elem->val, &left->val) > 0) { /* Swap with the left element. */ tmp1 = left->left; tmp2 = left->right; if (elem->up) { if (elem->up->left == elem) { elem->up->left = left; } else { elem->up->right = left; } } else { *top = left; } left->up = elem->up; elem->up = left; left->left = elem; left->right = elem->right; elem->left = tmp1; elem->right = tmp2; if (left->right) left->right->up = left; if (elem->left) elem->left->up = elem; if (elem->right) elem->right->up = elem; if (*last == left) *last = elem; } else goto done; } left = elem->left; } done: return; } HEAP_NAMES_LOCAL void HEAP_EXPORT_NAME(add)(struct heap_s *heap, struct heap_node_s *elem) { struct heap_node_s **next; struct heap_node_s *parent; #ifdef HEAP_MASSIVE_DEBUG fprintf(*HEAP_EXPORT_NAME(debug_out), "HEAP_EXPORT_NAME(add_to_heap) entry\n"); HEAP_EXPORT_NAME(print)(heap->top, heap->last); HEAP_EXPORT_NAME(check)(heap->top, heap->last); #endif elem->left = NULL; elem->right = NULL; elem->up = NULL; if (heap->top == NULL) { heap->top = elem; heap->last = elem; goto out; } HEAP_EXPORT_NAME(find_next_pos)(heap->last, &next, &parent); *next = elem; elem->up = parent; heap->last = elem; if (heap_cmp_key(&elem->val, &parent->val) < 0) { HEAP_EXPORT_NAME(send_up)(elem, &(heap->top), &(heap->last)); } out: #ifdef HEAP_MASSIVE_DEBUG fprintf(*HEAP_EXPORT_NAME(debug_out), "HEAP_EXPORT_NAME(add_to_heap) exit\n"); HEAP_EXPORT_NAME(print)(heap->top, heap->last); HEAP_EXPORT_NAME(check)(heap->top, heap->last); #endif return; } HEAP_NAMES_LOCAL void HEAP_EXPORT_NAME(remove)(struct heap_s *heap, struct heap_node_s *elem) { struct heap_node_s *to_insert; #ifdef HEAP_MASSIVE_DEBUG fprintf(*HEAP_EXPORT_NAME(debug_out), "HEAP_EXPORT_NAME(remove_from_heap) entry\n"); HEAP_EXPORT_NAME(print)(heap->top, heap->last); HEAP_EXPORT_NAME(check)(heap->top, heap->last); #endif /* First remove the last element from the tree, if it's not what's being removed, we will use it for insertion into the removal place. */ to_insert = heap->last; if (! to_insert->up) { /* This is the only element in the heap. */ heap->top = NULL; heap->last = NULL; goto out; } else { /* Set the new last position, and remove the item we will insert. */ HEAP_EXPORT_NAME(find_prev_elem)(to_insert, &(heap->last)); if (to_insert->up->left == to_insert) { to_insert->up->left = NULL; } else { to_insert->up->right = NULL; } } if (elem == to_insert) { /* We got lucky and removed the last element. We are done. */ goto out; } /* Now stick the formerly last element into the removed element's position. */ if (elem->up) { if (elem->up->left == elem) { elem->up->left = to_insert; } else { elem->up->right = to_insert; } } else { /* The head of the tree is being replaced. */ heap->top = to_insert; } to_insert->up = elem->up; if (elem->left) elem->left->up = to_insert; if (elem->right) elem->right->up = to_insert; to_insert->left = elem->left; to_insert->right = elem->right; if (heap->last == elem) heap->last = to_insert; elem = to_insert; /* Now propigate it to the right place in the tree. */ if (elem->up && heap_cmp_key(&elem->val, &elem->up->val) < 0) { HEAP_EXPORT_NAME(send_up)(elem, &(heap->top), &(heap->last)); } else { HEAP_EXPORT_NAME(send_down)(elem, &(heap->top), &(heap->last)); } out: #ifdef HEAP_MASSIVE_DEBUG fprintf(*HEAP_EXPORT_NAME(debug_out), "remove_from_head exit\n"); HEAP_EXPORT_NAME(print)(heap->top, heap->last); HEAP_EXPORT_NAME(check)(heap->top, heap->last); #endif return; } HEAP_NAMES_LOCAL struct heap_node_s * HEAP_EXPORT_NAME(get_top)(struct heap_s *heap) { return heap->top; } HEAP_NAMES_LOCAL void HEAP_EXPORT_NAME(init)(struct heap_s *heap) { heap->top = NULL; heap->last = NULL; } gensio-3.0.0/lib/gensio_base.c0000664000175000017500000017027515060677132011674 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #ifdef DEBUG_DATA #define ENABLE_PRBUF 1 #include "utils.h" #endif #include "gensio_base_parms.h" /* * Events: * ll_write_ready * ll_read * ll_open_done * ll_close_done * write * open * close * free */ enum basen_state { /* * gensio is closed, either at initial startup after close is * complete. * * open && ll open deferred -> BASEN_IN_LL_OPEN * open && ll open success && filter open deferred -> BASEN_IN_FILTER_OPEN * open && ll open success && filter open success -> BASEN_OPEN */ BASEN_CLOSED, /* * We have requested that our ll open, but have not received the * confirmation yet. * * ll open done (err) -> BASEN_CLOSED * ll open done && filter open deferred -> BASEN_IN_FILTER_OPEN * ll open done && filter open success -> BASEN_OPEN * close -> BASEN_IN_LL_CLOSE * io err should not be possible */ BASEN_IN_LL_OPEN, /* * We have requested that the filter open (if we have a filter) * but it has not yet been confirmed. * * filter open done -> BASEN_OPEN * close -> BASEN_IN_LL_CLOSE * io err -> BASEN_IN_LL_IO_ERR_CLOSE */ BASEN_IN_FILTER_OPEN, /* * gensio is operational * * close && write data pending -> BASEN_CLOSE_WAIT_DRAIN * close && no write data pending && filter close deferred -> * BASEN_IN_FILTER_CLOSE * close && no write data pending && filter close complete -> BASEN_IN_LL_CLOSE * io err -> BASEN_IN_LL_IO_ERR_CLOSE */ BASEN_OPEN, /* * A close has been requested, but we have write data to deliver. * * All data written && filter close deferred -> BASEN_IN_FILTER_CLOSE * All data written && filter close complete -> BASEN_IN_LL_CLOSE * io err -> BASEN_IN_LL_CLOSE */ BASEN_CLOSE_WAIT_DRAIN, /* * A close has been requested and all data is delivered. The * filter close has been requested but it has not yet reported * closed. * * filter close done -> BASEN_IN_LL_CLOSE * io err -> BASEN_IN_LL_CLOSE */ BASEN_IN_FILTER_CLOSE, /* * A close has been requested and the filter is closed. The ll * close has been requested but it has not yet reported closed. * * ll close done && all writes finished -> BASEN_CLOSE * finish all writes -> BASEN_CLOSE * io err -> ignore */ BASEN_IN_LL_CLOSE, /* * An I/O error happened on BASEN_OPEN, waiting for the LL to close. * * close -> BASEN_IN_LL_CLOSE * ll close done && all writes finished -> BASEN_IO_ERR_CLOSE * finish all writes -> BASEN_IO_ERR_CLOSE * io err -> ignore */ BASEN_IN_LL_IO_ERR_CLOSE, /* * An I/O error happened on BASEN_OPEN or before, waiting close call. * * close -> BASEN_CLOSE * io err should not be possible */ BASEN_IO_ERR_CLOSE }; #ifdef ENABLE_INTERNAL_TRACE #define DEBUG_STATE #endif #ifdef DEBUG_STATE struct basen_state_trace { enum basen_state old_state; enum basen_state new_state; int line; }; #define STATE_TRACE_LEN 256 struct basen_data; static void i_basen_add_trace(struct basen_data *ndata, enum basen_state new_state, int line); #else #define i_basen_add_trace(ndata, new_state, line) #endif struct basen_data { struct gensio *io; struct gensio *child; struct gensio_os_funcs *o; struct gensio_filter *filter; struct gensio_ll *ll; struct gensio_lock *lock; struct gensio_timer *timer; bool timer_start_pending; gensio_time pending_timer; struct gensio_timer *drain_timer; int drain_timeout; unsigned int refcount; enum basen_state state; gensio_done_err open_done; void *open_data; gensio_done close_done; void *close_data; bool close_requested; bool ll_want_close; unsigned int in_write_count; bool read_enabled; bool in_read; bool xmit_enabled; bool in_xmit_ready; bool redo_xmit_ready; bool ll_can_write; /* * We got an error from the lower layer, it's probably not working * any more. */ int ll_err; /* * Transfer data to the deferred open. */ int open_err; /* * Used to run user callbacks from the selector to avoid running * it directly from user calls. */ bool deferred_op_pending; struct gensio_runner *deferred_op_runner; bool deferred_read; bool deferred_write; bool deferred_open; bool deferred_close; #ifdef DEBUG_STATE struct basen_state_trace state_trace[STATE_TRACE_LEN]; unsigned int state_trace_pos; #endif }; struct gensio_ll { struct gensio_os_funcs *o; struct basen_data *ndata; gensio_ll_func func; void *user_data; }; struct gensio_filter { struct gensio_os_funcs *o; struct basen_data *ndata; gensio_filter_func func; void *user_data; }; static void i_handle_ioerr(struct basen_data *ndata, int err, int line); static void basen_filter_try_close(struct basen_data *ndata, bool was_timeout); static void basen_check_open_close_ops(struct basen_data *ndata); #define handle_ioerr(n, e) i_handle_ioerr(n, e, __LINE__) static void i_basen_lock(struct basen_data *ndata) { ndata->o->lock(ndata->lock); } #define basen_lock(ndata) do { \ i_basen_lock((ndata)); \ i_basen_add_trace(ndata, 1800 + ndata->refcount, __LINE__); \ } while(false) static void i_basen_unlock(struct basen_data *ndata) { ndata->o->unlock(ndata->lock); } #define basen_unlock(ndata) do { \ i_basen_add_trace(ndata, 1900 + ndata->refcount, __LINE__); \ i_basen_unlock((ndata)); \ } while(false) static void basen_finish_free(struct basen_data *ndata) { if (ndata->io) gensio_data_free(ndata->io); if (ndata->lock) ndata->o->free_lock(ndata->lock); if (ndata->timer) ndata->o->free_timer(ndata->timer); if (ndata->drain_timer) ndata->o->free_timer(ndata->drain_timer); if (ndata->deferred_op_runner) ndata->o->free_runner(ndata->deferred_op_runner); if (ndata->filter) gensio_filter_free(ndata->filter); if (ndata->ll) gensio_ll_free(ndata->ll); ndata->o->free(ndata->o, ndata); } static void i_basen_ref(struct basen_data *ndata, int line) { assert(ndata->refcount > 0); ndata->refcount++; i_basen_add_trace(ndata, 1000 + ndata->refcount, line); } #define basen_ref(ndata) i_basen_ref((ndata), __LINE__) static void i_basen_lock_and_ref(struct basen_data *ndata, int line) { i_basen_lock(ndata); i_basen_ref(ndata, line); } #define basen_lock_and_ref(ndata) i_basen_lock_and_ref((ndata), __LINE__) /* * This can *only* be called if the refcount is guaranteed not to reach * zero. */ static void i_basen_deref(struct basen_data *ndata, int line) { assert(ndata->refcount > 1); i_basen_add_trace(ndata, 1000 + ndata->refcount, line); ndata->refcount--; } #define basen_deref(ndata) i_basen_deref((ndata), __LINE__) static void i_basen_deref_and_unlock(struct basen_data *ndata, int line) { unsigned int count; assert(ndata->refcount > 0); i_basen_add_trace(ndata, 1000 + ndata->refcount, line); count = --ndata->refcount; i_basen_unlock(ndata); if (count == 0) basen_finish_free(ndata); } #define basen_deref_and_unlock(ndata) i_basen_deref_and_unlock((ndata), __LINE__) static void basen_start_timer(struct basen_data *ndata, gensio_time *timeout) { if (ndata->o->start_timer(ndata->timer, timeout) == 0) basen_ref(ndata); } static void basen_stop_timer(struct basen_data *ndata) { if (ndata->o->stop_timer(ndata->timer) == 0) basen_deref(ndata); } #ifdef DEBUG_STATE static void i_basen_add_trace(struct basen_data *ndata, enum basen_state new_state, int line) { ndata->state_trace[ndata->state_trace_pos].old_state = ndata->state; ndata->state_trace[ndata->state_trace_pos].new_state = new_state; ndata->state_trace[ndata->state_trace_pos].line = line; if (ndata->state_trace_pos == STATE_TRACE_LEN - 1) ndata->state_trace_pos = 0; else ndata->state_trace_pos++; } static void i_basen_set_state(struct basen_data *ndata, enum basen_state state, int line) { i_basen_add_trace(ndata, state, line); ndata->state = state; } #define basen_set_state(ndata, state) \ i_basen_set_state(ndata, state, __LINE__) #else static void basen_set_state(struct basen_data *ndata, enum basen_state state) { ndata->state = state; } #endif static bool filter_ul_read_pending(struct basen_data *ndata) { if (ndata->filter) return gensio_filter_ul_read_pending(ndata->filter); return false; } static bool filter_ll_write_pending(struct basen_data *ndata) { if (ndata->filter) return gensio_filter_ll_write_pending(ndata->filter); return false; } static bool filter_ll_write_queued(struct basen_data *ndata) { if (ndata->filter) return gensio_filter_ll_write_queued(ndata->filter); return false; } static void filter_io_err(struct basen_data *ndata, int err) { if (ndata->filter) gensio_filter_io_err(ndata->filter, err); } static bool filter_ul_can_write(struct basen_data *ndata) { if (ndata->filter) return gensio_filter_ul_can_write(ndata->filter); return ndata->ll_can_write; } static bool filter_ll_read_needed(struct basen_data *ndata) { if (ndata->filter) return gensio_filter_ll_read_needed(ndata->filter); return false; } /* Provides a way to verify keys and such. */ static int filter_check_open_done(struct basen_data *ndata) { if (ndata->filter) return gensio_filter_check_open_done(ndata->filter, ndata->io); return 0; } static int filter_try_connect(struct basen_data *ndata, gensio_time *timeout, bool was_timeout) { if (ndata->filter) return gensio_filter_try_connect(ndata->filter, timeout, was_timeout); return 0; } static int filter_try_disconnect(struct basen_data *ndata, gensio_time *timeout, bool was_timeout) { if (ndata->filter) return gensio_filter_try_disconnect(ndata->filter, timeout, was_timeout); return 0; } static int filter_ul_write(struct basen_data *ndata, gensio_ul_filter_data_handler handler, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { if (ndata->filter) return gensio_filter_ul_write(ndata->filter, handler, ndata, rcount, sg, sglen, auxdata); return handler(ndata, rcount, sg, sglen, auxdata); } static int filter_ll_write(struct basen_data *ndata, gensio_ll_filter_data_handler handler, gensiods *rcount, unsigned char *buf, gensiods buflen, const char *const *auxdata) { if (ndata->filter) return gensio_filter_ll_write(ndata->filter, handler, ndata, rcount, buf, buflen, auxdata); if (buflen) return handler(ndata, rcount, buf, buflen, auxdata); return 0; } static int filter_setup(struct basen_data *ndata) { if (ndata->filter) return gensio_filter_setup(ndata->filter, ndata->io); return 0; } static void filter_cleanup(struct basen_data *ndata) { if (ndata->filter) gensio_filter_cleanup(ndata->filter); } static int ll_write(struct basen_data *ndata, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { int rv; #ifdef DEBUG_DATA printf("LL write:"); do { unsigned int i; for (i = 0; i < sglen; i++) prbuf(sg[i].buf, sg[i].buflen); } while (false); #endif rv = gensio_ll_write(ndata->ll, rcount, sg, sglen, auxdata); #ifdef DEBUG_DATA printf("LL write returned %d accepted %ld\n", rv, rcount ? *rcount : 0); #endif return rv; } /* * Returns 0 if the open was immediate, GE_INPROGRESS if it was deferred, * and an errno otherwise. */ static int ll_open(struct basen_data *ndata, gensio_ll_open_done done, void *open_data) { return gensio_ll_open(ndata->ll, done, open_data); } static void basen_sched_deferred_op(struct basen_data *ndata); static void basen_ll_close_done(void *cb_data, void *close_data) { struct basen_data *ndata = cb_data; basen_lock(ndata); i_basen_add_trace(ndata, 1100, __LINE__); switch(ndata->state) { case BASEN_IN_LL_CLOSE: case BASEN_IO_ERR_CLOSE: /* Don't move to BASEN_CLOSED until later to avoid races. */ i_basen_add_trace(ndata, 102, __LINE__); ndata->deferred_close = true; basen_sched_deferred_op(ndata); break; case BASEN_IN_LL_IO_ERR_CLOSE: basen_set_state(ndata, BASEN_IO_ERR_CLOSE); /* * This is kind of a hack. This can come from an error two * places, either filter open or open. If it's in filter * open, we need to deliver the open failure to the user, * otherwise we will already be set to deliver a read/write * failture. So if open_done is set, we are in filter open, * and know to deliver the open failure. */ if (ndata->open_done) { ndata->deferred_open = true; basen_sched_deferred_op(ndata); } break; default: assert(0); } basen_unlock(ndata); } static int i_ll_close(struct basen_data *ndata, int line) { int rv; rv = gensio_ll_close(ndata->ll, basen_ll_close_done, ndata); return rv; } #define ll_close(n) i_ll_close(n, __LINE__); static void ll_set_read_callback_enable(struct basen_data *ndata, bool enable) { gensio_ll_set_read_callback(ndata->ll, enable); } static void ll_set_write_callback_enable(struct basen_data *ndata, bool enable) { gensio_ll_set_write_callback(ndata->ll, enable); } static void basen_set_ll_enables(struct basen_data *ndata) { bool enabled; if (ndata->state == BASEN_CLOSED || ndata->ll_err) { ll_set_write_callback_enable(ndata, false); ll_set_read_callback_enable(ndata, false); return; } ll_set_write_callback_enable(ndata, !ndata->ll_can_write); enabled = false; if (ndata->in_read) goto out_set; switch(ndata->state) { case BASEN_IN_FILTER_OPEN: case BASEN_IN_FILTER_CLOSE: enabled = filter_ll_read_needed(ndata); break; case BASEN_OPEN: if (filter_ul_read_pending(ndata) && ndata->read_enabled) { ndata->deferred_read = true; basen_sched_deferred_op(ndata); enabled = false; } else { enabled = ndata->read_enabled; } /* Fallthrough */ case BASEN_CLOSE_WAIT_DRAIN: enabled = enabled || filter_ll_read_needed(ndata); break; case BASEN_IN_LL_CLOSE: enabled = false; break; default: enabled = true; break; } out_set: ll_set_read_callback_enable(ndata, enabled); } static int basen_write_data_handler(void *cb_data, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { struct basen_data *ndata = cb_data; int rv; gensiods i, total = 0, count = 0; for (i = 0; i < sglen; i++) total += sg[i].buflen; rv = ll_write(ndata, &count, sg, sglen, auxdata); if (!rv && count < total) ndata->ll_can_write = false; if (rcount) *rcount = count; return rv; } static int basen_filter_ul_push(struct basen_data *ndata, bool check_open_close) { if (!ndata->ll_err && ndata->ll_can_write && filter_ll_write_pending(ndata)) { int err; err = filter_ul_write(ndata, basen_write_data_handler, NULL, NULL, 0, NULL); if (err) { handle_ioerr(ndata, err); return err; } if (check_open_close) basen_check_open_close_ops(ndata); } return 0; } static bool write_data_pending(struct basen_data *ndata) { return filter_ll_write_queued(ndata) || ndata->in_write_count > 0; } static void basen_timer_stopped(struct gensio_timer *t, void *cb_data) { struct basen_data *ndata = cb_data; basen_lock(ndata); basen_deref_and_unlock(ndata); } static void basen_start_drain_timer(struct basen_data *ndata) { gensio_time timeout; gensio_msecs_to_time(&timeout, ndata->drain_timeout); assert(ndata->o->start_timer(ndata->drain_timer, &timeout) == 0); basen_ref(ndata); } static void basen_stop_drain_timer(struct basen_data *ndata) { /* * This will either stop the timer and call * basen_timer_stopped which will do the deref for the timer, * or it will fail if there was no timer running (no ref) or * if the timer was in the callback (the callback will deref). */ ndata->o->stop_timer_with_done(ndata->drain_timer, basen_timer_stopped, ndata); } static int basen_write(struct basen_data *ndata, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { int err = 0; basen_lock(ndata); if (ndata->state != BASEN_OPEN) { err = GE_NOTREADY; goto out_unlock; } if (ndata->ll_err) { err = ndata->ll_err; goto out_unlock; } ndata->in_write_count++; err = filter_ul_write(ndata, basen_write_data_handler, rcount, sg, sglen, auxdata); ndata->in_write_count--; if (err) handle_ioerr(ndata, err); /* * We make sure that nothing is in a write call before starting a * close. So if anything wants to call ll_close() and * in_write_count is non-zero, it must set ll_want_close to defer * to here. */ if (ndata->in_write_count == 0 && ndata->ll_want_close) { int rv; switch (ndata->state) { case BASEN_CLOSE_WAIT_DRAIN: basen_stop_drain_timer(ndata); basen_set_state(ndata, BASEN_IN_LL_CLOSE); rv = ll_close(ndata); if (rv) { ndata->deferred_close = true; basen_sched_deferred_op(ndata); } break; case BASEN_IN_LL_IO_ERR_CLOSE: basen_set_state(ndata, BASEN_IO_ERR_CLOSE); break; case BASEN_IN_LL_CLOSE: ndata->deferred_close = true; basen_sched_deferred_op(ndata); break; default: assert(0); } } out_unlock: basen_set_ll_enables(ndata); basen_unlock(ndata); return err; } static bool basen_can_deliver_ul_data(struct basen_data *ndata) { return ndata->state == BASEN_OPEN || ndata->state == BASEN_IN_LL_IO_ERR_CLOSE || ndata->state == BASEN_IO_ERR_CLOSE; } static int basen_read_data_handler(void *cb_data, gensiods *rcount, unsigned char *buf, gensiods buflen, const char *const *auxdata) { struct basen_data *ndata = cb_data; gensiods count = 0, rval; int err = 0; basen_lock(ndata); if (!basen_can_deliver_ul_data(ndata)) { if (ndata->state != BASEN_IN_LL_OPEN && ndata->state != BASEN_IN_FILTER_OPEN) { /* * Just eat the data if we aren't open. But not on * pre-open because we can get data there on a race. */ count = buflen; } goto out_unlock; } while (basen_can_deliver_ul_data(ndata) && ndata->read_enabled && (count < buflen || ndata->ll_err)) { if (ndata->ll_err && !filter_ul_read_pending(ndata)) { basen_unlock(ndata); err = gensio_cb(ndata->io, GENSIO_EVENT_READ, ndata->ll_err, NULL, NULL, NULL); basen_lock(ndata); } else { basen_unlock(ndata); rval = buflen - count; err = gensio_cb(ndata->io, GENSIO_EVENT_READ, 0, buf + count, &rval, auxdata); #ifdef ENABLE_INTERNAL_TRACE /* Only for testing. */ assert(rval <= buflen - count); #else if (rval > buflen - count) rval = buflen - count; #endif count += rval; if (count >= buflen) goto out; /* Don't claim the lock if I don't have to. */ basen_lock(ndata); } } out_unlock: basen_unlock(ndata); out: if (rcount) *rcount = count; return err; } static void basen_close_from_wait_drain(struct basen_data *ndata) { basen_set_state(ndata, BASEN_IN_LL_CLOSE); if (ndata->in_write_count == 0) { int rv = ll_close(ndata); if (rv) { ndata->deferred_close = true; basen_sched_deferred_op(ndata); } } else { ndata->ll_want_close = true; } } static void i_handle_ioerr(struct basen_data *ndata, int err, int line) { int rv; i_basen_add_trace(ndata, 905, line); assert(err); if (ndata->ll_err) return; /* Already handled. */ ll_set_write_callback_enable(ndata, false); ll_set_read_callback_enable(ndata, false); ndata->ll_err = err; ndata->open_err = err; /* Strange looking, but don't enable ll write if we get an error. */ ndata->ll_can_write = true; switch(ndata->state) { case BASEN_CLOSED: case BASEN_IN_LL_OPEN: case BASEN_IO_ERR_CLOSE: assert(0); break; case BASEN_IN_FILTER_OPEN: filter_io_err(ndata, err); basen_set_state(ndata, BASEN_IN_LL_IO_ERR_CLOSE); /* * No need to check for in_write_count here, it can't be * pending because we can't have started a write yet. */ rv = ll_close(ndata); if (rv) basen_set_state(ndata, BASEN_IO_ERR_CLOSE); break; case BASEN_OPEN: filter_io_err(ndata, err); ndata->deferred_read = true; ndata->deferred_write = true; basen_sched_deferred_op(ndata); basen_set_state(ndata, BASEN_IN_LL_IO_ERR_CLOSE); if (ndata->in_write_count == 0) { rv = ll_close(ndata); if (rv) basen_set_state(ndata, BASEN_IO_ERR_CLOSE); } else { ndata->ll_want_close = true; } break; case BASEN_CLOSE_WAIT_DRAIN: filter_io_err(ndata, err); basen_stop_drain_timer(ndata); basen_close_from_wait_drain(ndata); break; case BASEN_IN_FILTER_CLOSE: filter_io_err(ndata, err); basen_set_state(ndata, BASEN_IN_LL_CLOSE); if (ndata->in_write_count == 0) { rv = ll_close(ndata); if (rv) { ndata->deferred_close = true; basen_sched_deferred_op(ndata); } } else { ndata->ll_want_close = true; } break; case BASEN_IN_LL_CLOSE: case BASEN_IN_LL_IO_ERR_CLOSE: break; } } /* * Note that you must be holding an extra ref when calling this, * the close_done call may free the gensio. */ static void basen_finish_close(struct basen_data *ndata) { /* * We don't have to worry about write here, write is only done in * write callbacks from the ll close, and when the ll close is * reported we are guaranteed to not be in a write callback. We * also don't need to worry about a read operation except for a * deferred one for the same reason. */ assert(!ndata->in_xmit_ready); if (ndata->deferred_op_pending) { i_basen_add_trace(ndata, 101, __LINE__); ndata->deferred_close = true; return; } assert(!ndata->in_read); filter_cleanup(ndata); basen_set_state(ndata, BASEN_CLOSED); if (ndata->close_done) { basen_unlock(ndata); ndata->close_done(ndata->io, ndata->close_data); basen_lock(ndata); } if (ndata->timer) { /* * This will either stop the timer and call * basen_timer_stopped which will do the deref for the timer, * or it will fail if there was no timer running (no ref) or * if the timer was in the callback (the callback will deref). */ ndata->o->stop_timer_with_done(ndata->timer, basen_timer_stopped, ndata); } if (ndata->drain_timer) { /* same with drain timer. */ ndata->o->stop_timer_with_done(ndata->drain_timer, basen_timer_stopped, ndata); } basen_deref(ndata); /* Lose the ref for the open. */ } static void basen_finish_open(struct basen_data *ndata, int err) { gensio_done_err open_done; void *open_data; i_basen_add_trace(ndata, 100, __LINE__); if (!err) { assert(ndata->state == BASEN_IN_FILTER_OPEN || ndata->state == BASEN_OPEN); basen_set_state(ndata, BASEN_OPEN); if (ndata->timer_start_pending) basen_start_timer(ndata, &ndata->pending_timer); } open_done = ndata->open_done; ndata->open_done = NULL; open_data = ndata->open_data; basen_unlock(ndata); open_done(ndata->io, err, open_data); basen_lock(ndata); } /* * Returns true if the open callback has been called but a close has * not been requested. We also call in ll_close, to flush out any * data we have. */ static bool basen_in_read_callbackable_state(struct basen_data *ndata) { return (ndata->state == BASEN_OPEN || ndata->state == BASEN_CLOSE_WAIT_DRAIN || ndata->state == BASEN_IN_LL_IO_ERR_CLOSE || ndata->state == BASEN_IN_LL_CLOSE || ndata->state == BASEN_IN_FILTER_CLOSE || ndata->state == BASEN_IO_ERR_CLOSE); } /* Returns true if the open callback has been called but close has not. */ static bool basen_in_write_callbackable_state(struct basen_data *ndata) { return (ndata->state == BASEN_OPEN || ndata->state == BASEN_IN_LL_IO_ERR_CLOSE || ndata->state == BASEN_IO_ERR_CLOSE); } static void basen_deferred_op(struct gensio_runner *runner, void *cbdata) { struct basen_data *ndata = cbdata; int err; basen_lock(ndata); ndata->deferred_op_pending = false; if (ndata->deferred_open) { ndata->deferred_open = false; i_basen_add_trace(ndata, 100, __LINE__); basen_finish_open(ndata, ndata->open_err); } while (ndata->deferred_read) { if (ndata->in_read || !ndata->read_enabled) goto skip_read; ndata->deferred_read = false; ndata->in_read = true; do { if (ndata->ll_err && !filter_ul_read_pending(ndata)) { /* Automatically disable read on an error. */ ndata->read_enabled = false; basen_unlock(ndata); err = gensio_cb(ndata->io, GENSIO_EVENT_READ, ndata->ll_err, NULL, NULL, NULL); basen_lock(ndata); } else { basen_unlock(ndata); err = filter_ll_write(ndata, basen_read_data_handler, NULL, NULL, 0, NULL); basen_lock(ndata); } if (err) { handle_ioerr(ndata, err); break; } } while (ndata->read_enabled && (ndata->ll_err || filter_ul_read_pending(ndata))); ndata->in_read = false; } skip_read: /* The write side is primarily for delivery when an error occurs. */ while (ndata->deferred_write) { ndata->deferred_write = false; if (ndata->in_xmit_ready) goto skip_write; ndata->in_xmit_ready = true; while (basen_in_write_callbackable_state(ndata) && (filter_ul_can_write(ndata) || ndata->ll_err) && ndata->xmit_enabled) { basen_unlock(ndata); err = gensio_cb(ndata->io, GENSIO_EVENT_WRITE_READY, 0, NULL, 0, NULL); basen_lock(ndata); if (err) { handle_ioerr(ndata, err); break; } } ndata->in_xmit_ready = false; } skip_write: if (ndata->deferred_close) { if (!(ndata->in_xmit_ready || ndata->in_read)) { ndata->deferred_close = false; i_basen_add_trace(ndata, 101, __LINE__); basen_finish_close(ndata); } } if (ndata->state != BASEN_CLOSED) { basen_filter_ul_push(ndata, true); basen_set_ll_enables(ndata); } basen_deref_and_unlock(ndata); /* Ref from basen_sched_deferred_op */ } static void basen_sched_deferred_op(struct basen_data *ndata) { if (!ndata->deferred_op_pending) { ndata->deferred_op_pending = true; basen_ref(ndata); ndata->o->run(ndata->deferred_op_runner); } } static int basen_filter_try_connect(struct basen_data *ndata, bool was_timeout) { int err; gensio_time timeout = {0, 0}; err = filter_try_connect(ndata, &timeout, was_timeout); if (err == GE_INPROGRESS || err == GE_RETRY) { /* * If we are still in progress, we may have generated data to * send. Push that out now. */ int err2 = basen_filter_ul_push(ndata, false); if (err2) return err2; /* * The push out may have changed states, retry the connect * code. This only needs to be done one, if something else * needs to happen it will be handled by normal callbacks. */ err2 = filter_try_connect(ndata, &timeout, false); if (err2 && err2 != GE_INPROGRESS && err2 != GE_RETRY) return err2; /* * We don't want to overwrite a GE_RETRY from the first call * unless we finished the connection. But if we finished the * connection or got a GE_RETRY from this call, use it. */ if (err2 != GE_INPROGRESS) err = err2; } else if (err) { return err; } /* At this point err can only be GE_INPROGRESS, GE_RETRY, or 0. */ basen_set_ll_enables(ndata); if (err == GE_INPROGRESS) return GE_INPROGRESS; basen_stop_timer(ndata); if (err == GE_RETRY) { basen_start_timer(ndata, &timeout); return GE_INPROGRESS; } /* No error, are we connected? */ return filter_check_open_done(ndata); } static void basen_filter_try_connect_finish(struct basen_data *ndata, bool was_timeout) { int err; err = basen_filter_try_connect(ndata, was_timeout); if (!err) { i_basen_add_trace(ndata, 100, __LINE__); basen_set_state(ndata, BASEN_OPEN); ndata->deferred_open = true; basen_sched_deferred_op(ndata); } else if (err != GE_INPROGRESS) handle_ioerr(ndata, err); } static void basen_ll_open_done(void *cb_data, int err, void *open_data) { struct basen_data *ndata = cb_data; basen_lock_and_ref(ndata); if (ndata->ll_err || ndata->open_err) { /* Nothing to do here, we failed the open, a close should be pending. */ } else if (err) { basen_set_state(ndata, BASEN_CLOSED); i_basen_add_trace(ndata, 100, __LINE__); basen_finish_open(ndata, err); basen_deref(ndata); } else { /* * Once the lower layer is open, propagate the traits. */ if (ndata->child) { if (gensio_is_reliable(ndata->child)) gensio_set_is_reliable(ndata->io, true); if (gensio_is_authenticated(ndata->child)) gensio_set_is_authenticated(ndata->io, true); if (gensio_is_encrypted(ndata->child)) gensio_set_is_encrypted(ndata->io, true); } basen_set_state(ndata, BASEN_IN_FILTER_OPEN); basen_filter_try_connect_finish(ndata, false); basen_set_ll_enables(ndata); } basen_deref_and_unlock(ndata); } static int basen_open(struct basen_data *ndata, gensio_done_err open_done, void *open_data) { int err = GE_INUSE; if (!open_done) return GE_INVAL; basen_lock(ndata); if (ndata->state == BASEN_CLOSED) { err = filter_setup(ndata); if (err) goto out_err; ndata->ll_err = 0; ndata->open_err = 0; ndata->in_read = false; ndata->deferred_read = false; ndata->deferred_write = false; ndata->deferred_open = false; ndata->deferred_close = false; ndata->read_enabled = false; ndata->xmit_enabled = false; ndata->ll_can_write = false; ndata->timer_start_pending = false; ndata->close_requested = false; ndata->ll_want_close = false; ndata->open_done = open_done; ndata->open_data = open_data; basen_set_state(ndata, BASEN_IN_LL_OPEN); err = ll_open(ndata, basen_ll_open_done, ndata); if (err == 0) { basen_set_state(ndata, BASEN_IN_FILTER_OPEN); err = basen_filter_try_connect(ndata, false); if (!err) { /* We are fully open, schedule it. */ basen_set_state(ndata, BASEN_OPEN); ndata->deferred_open = true; basen_sched_deferred_op(ndata); } else if (err == GE_INPROGRESS) { err = 0; } } else if (err == GE_INPROGRESS) { err = 0; } if (err) basen_set_state(ndata, BASEN_CLOSED); else basen_ref(ndata); /* Ref for open. */ } out_err: basen_unlock(ndata); return err; } static int basen_open_nochild(struct basen_data *ndata, gensio_done_err open_done, void *open_data) { int err = GE_INUSE; if (!open_done) return GE_INVAL; basen_lock(ndata); if (ndata->state == BASEN_CLOSED) { err = filter_setup(ndata); if (err) goto out_err; ndata->ll_err = 0; ndata->open_err = 0; ndata->in_read = false; ndata->deferred_read = false; ndata->deferred_write = false; ndata->deferred_open = false; ndata->deferred_close = false; ndata->read_enabled = false; ndata->xmit_enabled = false; ndata->timer_start_pending = false; ndata->open_done = open_done; ndata->open_data = open_data; basen_set_state(ndata, BASEN_IN_FILTER_OPEN); err = basen_filter_try_connect(ndata, false); if (!err) { /* We are fully open, schedule it. */ basen_set_state(ndata, BASEN_OPEN); ndata->deferred_open = true; basen_sched_deferred_op(ndata); } else if (err == GE_INPROGRESS) { err = 0; } if (err) basen_set_state(ndata, BASEN_CLOSED); else basen_ref(ndata); /* Ref for open */ basen_set_ll_enables(ndata); } out_err: basen_unlock(ndata); return err; } static void basen_filter_try_close(struct basen_data *ndata, bool was_timeout) { int err; gensio_time timeout = {0, 0}; err = filter_try_disconnect(ndata, &timeout, was_timeout); if (err == GE_INPROGRESS || err == GE_RETRY) { basen_filter_ul_push(ndata, false); if (err == GE_INPROGRESS) err = filter_try_disconnect(ndata, &timeout, was_timeout); basen_set_ll_enables(ndata); } if (err == GE_INPROGRESS) return; if (err == GE_RETRY) { basen_stop_timer(ndata); basen_start_timer(ndata, &timeout); return; } /* Ignore errors here, just go on. */ basen_set_state(ndata, BASEN_IN_LL_CLOSE); if (ndata->in_write_count == 0) { err = ll_close(ndata); if (err) { ndata->deferred_close = true; basen_sched_deferred_op(ndata); } } else { ndata->ll_want_close = true; } } static void basen_i_close(struct basen_data *ndata, gensio_done close_done, void *close_data) { int rv; ndata->read_enabled = false; ndata->xmit_enabled = false; ndata->close_done = close_done; ndata->close_data = close_data; /* * Set local close no matter what, so it get's delivered if open is * not yet complete. */ ndata->open_err = GE_LOCALCLOSED; if (ndata->state == BASEN_IN_LL_OPEN || ndata->state == BASEN_IN_FILTER_OPEN) { basen_set_state(ndata, BASEN_IN_LL_CLOSE); /* * No need to check for in_write_count here, it can't be * pending because we can't have started a write yet. */ rv = ll_close(ndata); if (rv) { ndata->deferred_close = true; basen_sched_deferred_op(ndata); } } else if (write_data_pending(ndata) && ndata->drain_timeout != 0) { basen_set_state(ndata, BASEN_CLOSE_WAIT_DRAIN); if (ndata->drain_timeout > 0) basen_start_drain_timer(ndata); } else { basen_set_state(ndata, BASEN_IN_FILTER_CLOSE); basen_filter_try_close(ndata, false); } basen_set_ll_enables(ndata); } static int basen_close(struct basen_data *ndata, gensio_done close_done, void *close_data) { int err = 0; basen_lock(ndata); if (ndata->close_requested) { err = GE_NOTREADY; goto out_unlock; } ndata->close_requested = true; i_basen_add_trace(ndata, 103, __LINE__); if (ndata->state == BASEN_OPEN || ndata->state == BASEN_IN_FILTER_OPEN || ndata->state == BASEN_IN_LL_OPEN) { basen_i_close(ndata, close_done, close_data); } else if (ndata->state == BASEN_IN_LL_IO_ERR_CLOSE) { ndata->close_done = close_done; ndata->close_data = close_data; basen_set_state(ndata, BASEN_IN_LL_CLOSE); } else if (ndata->state == BASEN_IO_ERR_CLOSE) { ndata->close_done = close_done; ndata->close_data = close_data; i_basen_add_trace(ndata, 102, __LINE__); ndata->deferred_close = true; basen_sched_deferred_op(ndata); } else { err = GE_NOTREADY; } out_unlock: basen_unlock(ndata); return err; } static void basen_free(struct basen_data *ndata) { basen_lock(ndata); i_basen_add_trace(ndata, 103, __LINE__); switch (ndata->state) { case BASEN_CLOSED: /* We can free immediately. */ break; case BASEN_IN_LL_OPEN: case BASEN_IN_FILTER_OPEN: case BASEN_OPEN: /* Need to close before we can free */ basen_i_close(ndata, NULL, NULL); break; case BASEN_IN_LL_IO_ERR_CLOSE: ndata->close_done = NULL; basen_set_state(ndata, BASEN_IN_LL_CLOSE); break; case BASEN_IO_ERR_CLOSE: ndata->close_done = NULL; ndata->deferred_close = true; basen_sched_deferred_op(ndata); break; default: /* In the close process, lose a ref so it will free when done. */ /* Don't call the done */ ndata->close_done = NULL; break; } /* Lose the initial ref so it will be freed when done. */ basen_deref_and_unlock(ndata); } static void basen_timeout(struct gensio_timer *timer, void *cb_data) { struct basen_data *ndata = cb_data; int err; basen_lock(ndata); switch (ndata->state) { case BASEN_IN_FILTER_OPEN: basen_filter_try_connect_finish(ndata, true); break; case BASEN_IN_FILTER_CLOSE: basen_filter_try_close(ndata, true); break; case BASEN_OPEN: case BASEN_CLOSE_WAIT_DRAIN: basen_unlock(ndata); err = gensio_filter_timeout(ndata->filter); basen_lock(ndata); if (err) handle_ioerr(ndata, err); break; default: break; } basen_filter_ul_push(ndata, true); basen_set_ll_enables(ndata); basen_deref_and_unlock(ndata); } static void basen_drain_timeout(struct gensio_timer *timer, void *cb_data) { struct basen_data *ndata = cb_data; basen_lock(ndata); if (ndata->state == BASEN_CLOSE_WAIT_DRAIN) basen_close_from_wait_drain(ndata); basen_deref_and_unlock(ndata); } static void basen_set_read_callback_enable(struct basen_data *ndata, bool enabled) { bool read_pending; basen_lock(ndata); i_basen_add_trace(ndata, 1100 + ndata->read_enabled * 10 + enabled, __LINE__); if (ndata->read_enabled == enabled) goto out_unlock; if (!basen_in_read_callbackable_state(ndata)) goto out_unlock; ndata->read_enabled = enabled; read_pending = filter_ul_read_pending(ndata); if (ndata->deferred_op_pending && enabled) { /* Nothing to do, let the read/open handling wake things up. */ ndata->deferred_read = true; } else if (enabled && (read_pending || ndata->ll_err) && (ndata->state == BASEN_OPEN || ndata->state == BASEN_IO_ERR_CLOSE || ndata->state == BASEN_IN_LL_IO_ERR_CLOSE)) { ndata->deferred_read = true; basen_sched_deferred_op(ndata); } else { /* * FIXME - here (and other places) we don't disable the low-level * handler, that is done in the callbacks. That's not optimal, * need to figure out a way to set this more accurately. */ basen_set_ll_enables(ndata); } out_unlock: basen_unlock(ndata); } static void basen_set_write_callback_enable(struct basen_data *ndata, bool enabled) { basen_lock(ndata); i_basen_add_trace(ndata, 1100 + ndata->xmit_enabled * 10 + enabled, __LINE__); if (ndata->xmit_enabled == enabled) goto out_unlock; if (!basen_in_write_callbackable_state(ndata)) goto out_unlock; ndata->xmit_enabled = enabled; if (enabled && (filter_ul_can_write(ndata) || ndata->ll_err)) { /* We can write, schedule the callback as a deferred op. */ ndata->deferred_write = true; basen_sched_deferred_op(ndata); } out_unlock: basen_unlock(ndata); } int basen_handle_local_control(struct basen_data *ndata, bool get, unsigned int option, char *data, gensiods *datalen) { switch(option) { case GENSIO_CONTROL_DRAIN_TIMEOUT: if (get) *datalen = snprintf(data, *datalen, "%d", ndata->drain_timeout); else ndata->drain_timeout = strtol(data, NULL, 0); return 0; default: return GE_NOTSUP; } } static int gensio_base_func(struct gensio *io, int func, gensiods *count, const void *cbuf, gensiods buflen, void *buf, const char *const *auxdata) { struct basen_data *ndata = gensio_get_gensio_data(io); int rv, rv2; switch (func) { case GENSIO_FUNC_WRITE_SG: return basen_write(ndata, count, cbuf, buflen, auxdata); case GENSIO_FUNC_OPEN: return basen_open(ndata, (void *) cbuf, buf); case GENSIO_FUNC_OPEN_NOCHILD: return basen_open_nochild(ndata, (void *) cbuf, buf); case GENSIO_FUNC_CLOSE: return basen_close(ndata, (void *) cbuf, buf); case GENSIO_FUNC_FREE: basen_free(ndata); return 0; case GENSIO_FUNC_SET_READ_CALLBACK: basen_set_read_callback_enable(ndata, buflen); return 0; case GENSIO_FUNC_SET_WRITE_CALLBACK: basen_set_write_callback_enable(ndata, buflen); return 0; case GENSIO_FUNC_CONTROL: rv = GE_NOTSUP; if (ndata->filter) { rv = gensio_filter_control(ndata->filter, *((bool *) cbuf), buflen, buf, count); if (rv && rv != GE_NOTSUP) return rv; } rv2 = gensio_ll_control(ndata->ll, *((bool *) cbuf), buflen, buf, count); if (rv2 != GE_NOTSUP) rv = rv2; if (rv == GE_NOTSUP) rv = basen_handle_local_control(ndata, *((bool *) cbuf), buflen, buf, count); return rv; case GENSIO_FUNC_ACONTROL: rv = GE_NOTSUP; if (ndata->filter) { rv = gensio_filter_acontrol(ndata->filter, *((bool *) cbuf), buflen, buf); if (rv && rv != GE_NOTSUP) return rv; } rv2 = gensio_ll_acontrol(ndata->ll, *((bool *) cbuf), buflen, buf); if (rv2 == GE_NOTSUP) return rv; return rv2; case GENSIO_FUNC_DISABLE: if (ndata->state != BASEN_CLOSED) { basen_set_state(ndata, BASEN_CLOSED); basen_deref(ndata); if (ndata->filter) gensio_filter_cleanup(ndata->filter); gensio_ll_disable(ndata->ll); if (ndata->child) gensio_disable(ndata->child); } return 0; default: return GE_NOTSUP; } } static void basen_check_open_close_ops(struct basen_data *ndata) { if (ndata->deferred_close) { if (!(ndata->in_xmit_ready || ndata->in_read)) { ndata->deferred_close = false; i_basen_add_trace(ndata, 101, __LINE__); basen_finish_close(ndata); } return; } if (ndata->state == BASEN_IN_FILTER_OPEN) basen_filter_try_connect_finish(ndata, false); if (ndata->state == BASEN_IN_FILTER_CLOSE) basen_filter_try_close(ndata, false); if (ndata->state == BASEN_CLOSE_WAIT_DRAIN) { if (!write_data_pending(ndata)) { basen_stop_drain_timer(ndata); basen_set_state(ndata, BASEN_IN_FILTER_CLOSE); basen_filter_try_close(ndata, false); } } } static gensiods basen_ll_read(void *cb_data, int readerr, unsigned char *ibuf, gensiods buflen, const char *const *auxdata) { struct basen_data *ndata = cb_data; unsigned char *buf = ibuf; int err; #ifdef DEBUG_DATA printf("LL read:"); prbuf(buf, buflen); #endif basen_lock_and_ref(ndata); if (readerr) { handle_ioerr(ndata, readerr); goto out_finish; } if (ndata->ll_err) { /* If we are handling an error, throw the data away. */ buf += buflen; goto out_finish; } while (buflen > 0 && (ndata->read_enabled || filter_ll_read_needed(ndata))) { if (ndata->in_read) { /* Currently in a deferred read, just let that handle it. */ ll_set_read_callback_enable(ndata, false); goto out_unlock; } ndata->in_read = true; do { gensiods wrlen = 0; basen_unlock(ndata); readerr = filter_ll_write(ndata, basen_read_data_handler, &wrlen, buf, buflen, auxdata); basen_lock(ndata); if (ndata->ll_err || readerr) { ndata->in_read = false; buf += buflen; if (readerr && !ndata->ll_err) handle_ioerr(ndata, readerr); else if (ndata->deferred_read) /* * Deferred op can happen while we are * unlocked. ll_err will be set, so this is the * right place to do it. */ basen_sched_deferred_op(ndata); goto out_finish; } else { #ifdef ENABLE_INTERNAL_TRACE /* Only for testing. */ assert(wrlen <= buflen); #else if (wrlen > buflen) wrlen = buflen; #endif buf += wrlen; buflen -= wrlen; } } while (ndata->read_enabled && buflen > 0); ndata->in_read = false; basen_filter_ul_push(ndata, true); basen_check_open_close_ops(ndata); while (basen_in_write_callbackable_state(ndata) && (filter_ul_can_write(ndata) || ndata->ll_err) && ndata->xmit_enabled) { basen_unlock(ndata); err = gensio_cb(ndata->io, GENSIO_EVENT_WRITE_READY, 0, NULL, 0, NULL); basen_lock(ndata); if (err) { handle_ioerr(ndata, err); break; } } } out_finish: basen_set_ll_enables(ndata); out_unlock: basen_deref_and_unlock(ndata); #ifdef DEBUG_DATA printf("LL read returns %ld\n", buf - ibuf); #endif return buf - ibuf; } static void basen_ll_write_ready(void *cb_data) { struct basen_data *ndata = cb_data; int err; basen_lock_and_ref(ndata); if (ndata->ll_err) { /* Just ignore it if we have an error. */ ll_set_write_callback_enable(ndata, false); goto out; } if (ndata->in_xmit_ready) { /* * Another thread is already in the loop, we don't allow two * callbacks at a time. Just tell the other loop to do it * again. */ ll_set_write_callback_enable(ndata, false); ndata->redo_xmit_ready = true; goto out; } ndata->ll_can_write = true; ndata->in_xmit_ready = true; retry: if (filter_ll_write_pending(ndata)) { err = filter_ul_write(ndata, basen_write_data_handler, NULL, NULL, 0, NULL); if (err) { handle_ioerr(ndata, err); goto out_setnotready; } } basen_filter_ul_push(ndata, true); basen_check_open_close_ops(ndata); while (basen_in_write_callbackable_state(ndata) && (filter_ul_can_write(ndata) || ndata->ll_err) && ndata->xmit_enabled) { basen_unlock(ndata); err = gensio_cb(ndata->io, GENSIO_EVENT_WRITE_READY, 0, NULL, 0, NULL); basen_lock(ndata); if (err) { handle_ioerr(ndata, err); goto out_setnotready; } } if (ndata->redo_xmit_ready) { /* Got another xmit ready while we were unlocked. */ ndata->redo_xmit_ready = false; if (ndata->xmit_enabled || filter_ll_write_pending(ndata)) goto retry; } out_setnotready: basen_set_ll_enables(ndata); ndata->in_xmit_ready = false; if (ndata->deferred_write) /* Could have gotten a deferred write while we were unlocked. */ basen_sched_deferred_op(ndata); out: basen_deref_and_unlock(ndata); } static gensiods gensio_ll_base_cb(void *cb_data, int op, int val, void *buf, gensiods buflen, const char *const *auxdata) { switch (op) { case GENSIO_LL_CB_READ: return basen_ll_read(cb_data, val, buf, buflen, auxdata); case GENSIO_LL_CB_WRITE_READY: basen_ll_write_ready(cb_data); return 0; default: return 0; } }; static void basen_output_ready(void *cb_data) { struct basen_data *ndata = cb_data; /* Force the lower-level callback to be enabled. */ ndata->ll_can_write = false; ll_set_write_callback_enable(ndata, true); } static void basen_start_timer_op(void *cb_data, gensio_time *timeout) { struct basen_data *ndata = cb_data; if (ndata->state == BASEN_OPEN || ndata->state == BASEN_CLOSE_WAIT_DRAIN) { basen_start_timer(ndata, timeout); } else { ndata->timer_start_pending = true; ndata->pending_timer = *timeout; } } static void basen_stop_timer_op(void *cb_data) { struct basen_data *ndata = cb_data; if (ndata->state == BASEN_OPEN || ndata->state == BASEN_CLOSE_WAIT_DRAIN) { basen_stop_timer(ndata); } } static int basen_call_child_control_op(struct basen_data *ndata, struct gensio_filter_cb_control_data *ctrl) { return gensio_control(ndata->child, ctrl->depth, ctrl->get, ctrl->option, ctrl->data, ctrl->datalen); } static void basen_filter_open_done(void *cb_data) { struct basen_data *ndata = cb_data; basen_lock(ndata); if (ndata->state == BASEN_IN_FILTER_OPEN) { basen_filter_try_connect_finish(ndata, false); basen_set_ll_enables(ndata); } basen_unlock(ndata); } static void basen_filter_input_ready(void *cb_data) { struct basen_data *ndata = cb_data; basen_lock(ndata); basen_set_ll_enables(ndata); basen_unlock(ndata); } static int gensio_base_filter_cb(void *cb_data, int op, void *data) { switch (op) { case GENSIO_FILTER_CB_OUTPUT_READY: basen_output_ready(cb_data); return 0; case GENSIO_FILTER_CB_START_TIMER: basen_start_timer_op(cb_data, data); return 0; case GENSIO_FILTER_CB_STOP_TIMER: basen_stop_timer_op(cb_data); return 0; case GENSIO_FILTER_CB_CONTROL: basen_call_child_control_op(cb_data, data); return 0; case GENSIO_FILTER_CB_OPEN_DONE: basen_filter_open_done(cb_data); return 0; case GENSIO_FILTER_CB_INPUT_READY: basen_filter_input_ready(cb_data); return 0; default: return GE_NOTSUP; } } static struct gensio * gensio_i_alloc(struct gensio_os_funcs *o, struct gensio_ll *ll, struct gensio_filter *filter, struct gensio *child, const char *typename, bool is_client, gensio_done_err open_done, void *open_data, gensio_event cb, void *user_data) { struct basen_data *ndata = o->zalloc(o, sizeof(*ndata)); if (!ndata) return NULL; ndata->o = o; ndata->refcount = 1; ndata->lock = o->alloc_lock(o); if (!ndata->lock) goto out_nomem; ndata->timer = o->alloc_timer(o, basen_timeout, ndata); if (!ndata->timer) goto out_nomem; ndata->drain_timer = o->alloc_timer(o, basen_drain_timeout, ndata); if (!ndata->drain_timer) goto out_nomem; ndata->drain_timeout = -1; /* Off by default */ ndata->deferred_op_runner = o->alloc_runner(o, basen_deferred_op, ndata); if (!ndata->deferred_op_runner) goto out_nomem; ll->ndata = ndata; ndata->io = gensio_data_alloc(o, cb, user_data, gensio_base_func, child, typename, ndata); if (!ndata->io) goto out_nomem; ndata->child = child; gensio_set_is_client(ndata->io, is_client); gensio_ll_set_callback(ll, gensio_ll_base_cb, ndata); if (filter) { filter->ndata = ndata; gensio_filter_set_callback(filter, gensio_base_filter_cb, ndata); } /* * Save this until we succeed, otherwise basen_finish_free will * free them, but we don't want them freed if we fail. */ ndata->ll = ll; ndata->filter = filter; if (is_client) { basen_set_state(ndata, BASEN_CLOSED); } else { if (filter_setup(ndata)) { ndata->filter = NULL; ndata->ll = NULL; goto out_nomem; } /* This is not ideal, it should really return GE_NOMEM. */ if (!open_done) goto out_nomem; ndata->open_done = open_done; ndata->open_data = open_data; } if (ndata->child) { if (gensio_is_reliable(ndata->child)) gensio_set_is_reliable(ndata->io, true); if (gensio_is_authenticated(ndata->child)) gensio_set_is_authenticated(ndata->io, true); if (gensio_is_encrypted(ndata->child)) gensio_set_is_encrypted(ndata->io, true); } return ndata->io; out_nomem: basen_finish_free(ndata); return NULL; } struct gensio * base_gensio_alloc(struct gensio_os_funcs *o, struct gensio_ll *ll, struct gensio_filter *filter, struct gensio *child, const char *typename, gensio_event cb, void *user_data) { return gensio_i_alloc(o, ll, filter, child, typename, true, NULL, NULL, cb, user_data); } struct gensio * base_gensio_server_alloc(struct gensio_os_funcs *o, struct gensio_ll *ll, struct gensio_filter *filter, struct gensio *child, const char *typename, gensio_done_err open_done, void *open_data) { return gensio_i_alloc(o, ll, filter, child, typename, false, open_done, open_data, NULL, NULL); } int gensio_base_parms_alloc(struct gensio_os_funcs *o, bool is_accepter, const char *typestr, struct gensio_base_parms **rparms) { struct gensio_base_parms *parms; int rv; parms = o->zalloc(o, sizeof(*parms)); if (!parms) return GE_NOMEM; parms->o = o; rv = gensio_get_default(o, typestr, "drain_timeout", false, GENSIO_DEFAULT_INT, NULL, &parms->drain_timeout); if (rv) goto out_err; *rparms = parms; return 0; out_err: o->free(o, parms); return rv; } void gensio_base_parms_free(struct gensio_base_parms **parms) { (*parms)->o->free((*parms)->o, *parms); *parms = NULL; } void i_gensio_base_parms_set(struct gensio *io, const struct gensio_base_parms *parms) { struct basen_data *ndata = gensio_get_gensio_data(io); ndata->drain_timeout = parms->drain_timeout; } int gensio_base_parms_set(struct gensio *io, struct gensio_base_parms **parms) { i_gensio_base_parms_set(io, *parms); gensio_base_parms_free(parms); return 0; } int gensio_base_parm(struct gensio_base_parms *parms, struct gensio_pparm_info *p, const char *arg) { if (gensio_pparm_int(p, arg, "drain_timeout", &parms->drain_timeout) > 0) return 1; return 0; } int base_gensio_server_start(struct gensio *io) { struct basen_data *ndata = gensio_get_gensio_data(io); int err; basen_lock(ndata); basen_set_state(ndata, BASEN_IN_FILTER_OPEN); err = basen_filter_try_connect(ndata, false); if (!err) { err = basen_filter_ul_push(ndata, true); if (!err) { /* We are fully open, schedule it. */ basen_set_state(ndata, BASEN_OPEN); ndata->deferred_open = true; basen_sched_deferred_op(ndata); } } else if (err == GE_INPROGRESS) { err = basen_filter_ul_push(ndata, true); } else { basen_set_state(ndata, BASEN_CLOSED); err = GE_NOMEM; goto out_unlock; } basen_ref(ndata); /* For the open. */ basen_set_ll_enables(ndata); out_unlock: basen_unlock(ndata); return err; } void gensio_filter_set_callback(struct gensio_filter *filter, gensio_filter_cb cb, void *cb_data) { filter->func(filter, GENSIO_FILTER_FUNC_SET_CALLBACK, cb, cb_data, NULL, NULL, NULL, 0, NULL); } bool gensio_filter_ul_read_pending(struct gensio_filter *filter) { return filter->func(filter, GENSIO_FILTER_FUNC_UL_READ_PENDING, NULL, NULL, NULL, NULL, NULL, 0, NULL); } bool gensio_filter_ll_write_pending(struct gensio_filter *filter) { return filter->func(filter, GENSIO_FILTER_FUNC_LL_WRITE_PENDING, NULL, NULL, NULL, NULL, NULL, 0, NULL); } bool gensio_filter_ul_can_write(struct gensio_filter *filter) { bool val = true; int err; /* If not implemented, this will just be ignored. */ err = filter->func(filter, GENSIO_FILTER_FUNC_UL_CAN_WRITE, NULL, &val, NULL, NULL, NULL, 0, NULL); if (err) return filter->ndata->ll_can_write; return val; } bool gensio_filter_ll_write_queued(struct gensio_filter *filter) { bool val = true; int rv; /* If not implemented, this will just be ignored. */ rv = filter->func(filter, GENSIO_FILTER_FUNC_LL_WRITE_QUEUED, NULL, &val, NULL, NULL, NULL, 0, NULL); if (rv) return gensio_filter_ll_write_pending(filter); return val; } void gensio_filter_io_err(struct gensio_filter *filter, int err) { filter->func(filter, GENSIO_FILTER_FUNC_IO_ERR, NULL, &err, NULL, NULL, NULL, 0, NULL); } bool gensio_filter_ll_read_needed(struct gensio_filter *filter) { return filter->func(filter, GENSIO_FILTER_FUNC_LL_READ_NEEDED, NULL, NULL, NULL, NULL, NULL, 0, NULL); } int gensio_filter_check_open_done(struct gensio_filter *filter, struct gensio *io) { return filter->func(filter, GENSIO_FILTER_FUNC_CHECK_OPEN_DONE, NULL, io, NULL, NULL, NULL, 0, NULL); } int gensio_filter_try_connect(struct gensio_filter *filter, gensio_time *timeout, bool was_timeout) { return filter->func(filter, GENSIO_FILTER_FUNC_TRY_CONNECT, NULL, timeout, NULL, NULL, NULL, was_timeout, NULL); } int gensio_filter_try_disconnect(struct gensio_filter *filter, gensio_time *timeout, bool was_timeout) { return filter->func(filter, GENSIO_FILTER_FUNC_TRY_DISCONNECT, NULL, timeout, NULL, NULL, NULL, was_timeout, NULL); } int gensio_filter_ul_write(struct gensio_filter *filter, gensio_ul_filter_data_handler handler, void *cb_data, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { return filter->func(filter, GENSIO_FILTER_FUNC_UL_WRITE_SG, handler, cb_data, rcount, NULL, sg, sglen, auxdata); } int gensio_filter_ll_write(struct gensio_filter *filter, gensio_ll_filter_data_handler handler, void *cb_data, gensiods *rcount, unsigned char *buf, gensiods buflen, const char *const *auxdata) { return filter->func(filter, GENSIO_FILTER_FUNC_LL_WRITE, handler, cb_data, rcount, buf, NULL, buflen, auxdata); } int gensio_filter_timeout(struct gensio_filter *filter) { return filter->func(filter, GENSIO_FILTER_FUNC_TIMEOUT, NULL, NULL, NULL, NULL, NULL, 0, NULL); } int gensio_filter_setup(struct gensio_filter *filter, struct gensio *io) { return filter->func(filter, GENSIO_FILTER_FUNC_SETUP, NULL, io, NULL, NULL, NULL, 0, NULL); } void gensio_filter_cleanup(struct gensio_filter *filter) { filter->func(filter, GENSIO_FILTER_FUNC_CLEANUP, NULL, NULL, NULL, NULL, NULL, 0, NULL); } void gensio_filter_free(struct gensio_filter *filter) { filter->func(filter, GENSIO_FILTER_FUNC_FREE, NULL, NULL, NULL, NULL, NULL, 0, NULL); } int gensio_filter_control(struct gensio_filter *filter, bool get, unsigned int option, char *data, gensiods *datalen) { return filter->func(filter, GENSIO_FILTER_FUNC_CONTROL, NULL, data, datalen, NULL, &get, option, NULL); } int gensio_filter_acontrol(struct gensio_filter *filter, bool get, unsigned int option, struct gensio_func_acontrol *data) { return filter->func(filter, GENSIO_FILTER_FUNC_ACONTROL, NULL, data, 0, NULL, &get, option, NULL); } struct gensio * gensio_filter_get_gensio(struct gensio_filter *filter) { return filter->ndata->io; } void gensio_filter_vlog(struct gensio_filter *filter, enum gensio_log_levels level, const char *log, va_list args) { gensio_gvlog(filter->ndata->io, level, log, args); } void gensio_filter_log(struct gensio_filter *filter, enum gensio_log_levels level, const char *log, ...) { va_list args; va_start(args, log); gensio_filter_vlog(filter, level, log, args); va_end(args); } int gensio_filter_do_event(struct gensio_filter *filter, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) { struct basen_data *ndata = filter->ndata; return gensio_cb(ndata->io, event, err, buf, buflen, auxdata); } struct gensio_filter * gensio_filter_alloc_data(struct gensio_os_funcs *o, gensio_filter_func func, void *user_data) { struct gensio_filter *filter = o->zalloc(o, sizeof(*filter)); if (!filter) return NULL; filter->o = o; filter->func = func; filter->user_data = user_data; return filter; } void gensio_filter_free_data(struct gensio_filter *filter) { filter->o->free(filter->o, filter); } void * gensio_filter_get_user_data(struct gensio_filter *filter) { return filter->user_data; } void gensio_ll_set_callback(struct gensio_ll *ll, gensio_ll_cb cb, void *cb_data) { ll->func(ll, GENSIO_LL_FUNC_SET_CALLBACK, NULL, cb_data, cb, 0, NULL); } int gensio_ll_write(struct gensio_ll *ll, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { return ll->func(ll, GENSIO_LL_FUNC_WRITE_SG, rcount, NULL, sg, sglen, auxdata); } int gensio_ll_open(struct gensio_ll *ll, gensio_ll_open_done done, void *open_data) { return ll->func(ll, GENSIO_LL_FUNC_OPEN, NULL, open_data, done, 0, NULL); } int gensio_ll_close(struct gensio_ll *ll, gensio_ll_close_done done, void *close_data) { return ll->func(ll, GENSIO_LL_FUNC_CLOSE, NULL, close_data, done, 0, NULL); } void gensio_ll_set_read_callback(struct gensio_ll *ll, bool enabled) { ll->func(ll, GENSIO_LL_FUNC_SET_READ_CALLBACK, NULL, NULL, NULL, enabled, NULL); } void gensio_ll_set_write_callback(struct gensio_ll *ll, bool enabled) { ll->func(ll, GENSIO_LL_FUNC_SET_WRITE_CALLBACK, NULL, NULL, NULL, enabled, NULL); } void gensio_ll_free(struct gensio_ll *ll) { ll->func(ll, GENSIO_LL_FUNC_FREE, NULL, NULL, NULL, 0, NULL); } void gensio_ll_disable(struct gensio_ll *ll) { ll->func(ll, GENSIO_LL_FUNC_DISABLE, NULL, NULL, NULL, 0, NULL); } int gensio_ll_control(struct gensio_ll *ll, bool get, int option, char *data, gensiods *datalen) { return ll->func(ll, GENSIO_LL_FUNC_CONTROL, datalen, data, &get, option, NULL); } int gensio_ll_acontrol(struct gensio_ll *ll, bool get, int option, struct gensio_func_acontrol *data) { return ll->func(ll, GENSIO_LL_FUNC_ACONTROL, 0, data, &get, option, NULL); } int gensio_ll_do_event(struct gensio_ll *ll, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) { struct basen_data *ndata = ll->ndata; return gensio_cb(ndata->io, event, err, buf, buflen, auxdata); } struct gensio_ll * gensio_ll_alloc_data(struct gensio_os_funcs *o, gensio_ll_func func, void *user_data) { struct gensio_ll *ll = o->zalloc(o, sizeof(*ll)); if (!ll) return NULL; ll->o = o; ll->func = func; ll->user_data = user_data; return ll; } void gensio_ll_free_data(struct gensio_ll *ll) { ll->o->free(ll->o, ll); } void * gensio_ll_get_user_data(struct gensio_ll *ll) { return ll->user_data; } struct gensio_ll * base_gensio_get_ll(struct gensio *io) { struct basen_data *ndata = gensio_get_gensio_data(io); return ndata->ll; } void gensio_ll_vlog(struct gensio_ll *ll, enum gensio_log_levels level, const char *log, va_list args) { gensio_gvlog(ll->ndata->io, level, log, args); } void gensio_ll_log(struct gensio_ll *ll, enum gensio_log_levels level, const char *log, ...) { va_list args; va_start(args, log); gensio_ll_vlog(ll, level, log, args); va_end(args); } gensio-3.0.0/lib/gensio_afskmdm.c0000664000175000017500000024407015060571607012377 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2022 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Add timestamps to messages. */ #define GENSIO_AFSKMDM_DEBUG_TIME 0x10 /* Dump full received/sent messages. */ #define GENSIO_AFSKMDM_DEBUG_MSG 0x08 /* Dump some state handing information. */ #define GENSIO_AFSKMDM_DEBUG_STATE 0x04 /* Dump raw bit handling information. */ #define GENSIO_AFSKMDM_DEBUG_BIT_HNDL 0x02 /* Dump raw messages */ #define GENSIO_AFSKMDM_DEBUG_RAW_MSG 0x01 /* * This filter implements a audio frequency shift keying modem per the * GAX25 spec. * * The filter processes data from the child in corrsize frame chunks. * This corrsize will be in_framerate/data_rate, so 1 corrsize frame * is a approximately a single bit. It may not be exact, so there is * adjustment logic to keep it close to alignment. A similar thing is * done for transmission with out_framerate. * * Also, the transmitter and receiver may not be exactly aligned on * bit rate. So it may drift. There is logic to detect the drift and * adjust for it automatically. * * The transmitter will send a preamble that allows the adjustment * logic to lock in with the transmitter. * * It keeps 2 * corrsize frames before the beginning of the current * chunk, and it waits until the next chunk to process the last * corrsize frames of the previous chunk. This lets the receiver * adjust backwards in time a bit if it has to. * * It is constantly looking for 1200Hz (level 1, a mark) and 2200Hz * signals (level 0, a space). If it finds a 0 in this mode, it just * then looks for 6 1's in a row. Then, if the next bit is 0, it * starts receiving data for the message. This sequence will also * terminate amessage. * * The filter keeps track of multiple possible incoming messages at a * time. If a bit is read that is uncertain (the difference between * mark and space are not significant), it will split off a new * working message for each current message, one with each bit * possibility. If a current working message is determined to be * invalid or done, it is returned to the pool. The preamble of flags * should clear out all the working messages to make it a clean slate * for a starting message. */ enum afskmdm_state { /* Looking for a '0' to start the preamble. */ AFSKMDM_STATE_PREAMBLE_SEARCH_0, /* In the preamble (01111110), found a 0, looking for a '1'. */ AFSKMDM_STATE_PREAMBLE_FIRST_0, /* In the preamble, looking for 6 1's in a row. */ AFSKMDM_STATE_PREAMBLE_1, /* In the preamble, found 0111111, looking for the last 0. */ AFSKMDM_STATE_PREAMBLE_LAST_0, /* Currently in a message. */ AFSKMDM_STATE_IN_MSG, /* Got 6 1's in a row while in msg, looking for a 0. */ AFSKMDM_STATE_POSTAMBLE_LAST_0 }; /* * This is the maximum adjust period we will allow. If it reaches * this value, we assume that the small adjustments can be handled by * the correlation code. */ #define ADJ_PERIOD 10 /* * Give the number of values on each side of the correlation to * compute another correlation for. Having values for 6 different * areas around the correlation seems to give the best bang for the * buck. */ #define CORREDGE 3 #define CORRMIDDLE (CORREDGE + 1) #define CORREXTRA ((2 * CORREDGE) + 1) /* * A working receive buffer. */ struct wmsg { bool in_use; bool new_wmsg; /* Used to handle initial processing correctly. */ float certainty; unsigned int num_uncertain; /* Counts 1's in the preamble and when receiving data. */ unsigned int num_rcv_1; enum afskmdm_state state; /* Level we received last time. */ unsigned char prev_recv_level; /* * Current byte/bit the receiver is assembling. */ unsigned char curr_byte; unsigned int curr_bit_pos; /* Current message in assembly. */ unsigned char *read_data; gensiods read_data_len; }; struct wmsgset { struct wmsg *wmsgs; bool got_flag; unsigned int curr_wmsgs; }; struct wrbuf { unsigned char *data; gensiods len; }; /* * These are the entries in a digraph used to send data. Each of * these has a data item (pointing into a sine array), a size (either * corrsize or corrsize +/- 1 for the alternate size that may be * periodically sent). * * It also has pointers to the next entry to send based upon if the * next entry is a mark or space and if the next entry is corrsize or * corrsize +/- 1. */ struct xmit_entry { float *data; unsigned int size; /* in bytes. */ bool is_mark; /* * If we just send this, the first two are the next entries to * send if the next is a space or a mark. The second two are * space and mark for alternate entries */ struct xmit_entry *next_send[4]; /* A linked list of all of the entries is kept for cleanup and searching */ struct xmit_entry *next; }; enum afskmdm_keytype { KEY_RW, /* Read and write keyon/keyoff values. */ KEY_RTS, KEY_RTSINV, KEY_DTR, KEY_DTRINV, KEY_CM108 }; struct afskmdm_filter { struct gensio_filter *filter; struct gensio_os_funcs *o; struct gensio_lock *lock; gensio_filter_cb filter_cb; void *filter_cb_data; int err; /* For reporting key errors. */ struct gensio_pparm_info p; unsigned int in_nchans; unsigned int in_chan; unsigned int out_nchans; unsigned int out_chans; unsigned int in_framesize; /* Size of a (sample * nchans) in bytes. */ unsigned int out_framesize; /* Size of a (sample * nchans) in bytes. */ unsigned int in_chunksize; /* Frame count we get from the sound gensio. */ unsigned int out_chunksize; /* Frame count we send to the sound gensio. */ bool full_duplex; unsigned int nsec_per_frame; /* * Sending parameters; */ uint64_t tx_preamble_time; uint64_t tx_postamble_time; uint64_t tx_predelay_time; /* * Frames in a single correlation. Note that the correlation may * not exactly match up with the period of the data rate. If that * is the case, then we will need to periodically adjust the * correlation window to keep it aligned. */ unsigned int in_corrsize; int in_corr_adj; /* +1, 0, or -1 */ unsigned int in_corr_period; /* How often to add in_corr_adj. */ unsigned int in_corr_counter; /* Current receive counter for in_corr_adj. */ uint64_t in_corr_time; /* Time in nsec for a corrsize to be received. */ /* * The number of frames in a transmitted bit. A similar * technique is used for sending, there are two send sizes if * out_bit_adj != 0 and corr_period says how often we use the * alternate one. */ unsigned int out_bitsize; int out_bit_adj; unsigned int max_out_bitsize; /* Largest entry we will send. */ unsigned int out_bit_counter; /* Counter for out_bit_period */ unsigned int out_bit_period; /* How often to do an alternate frame size. */ uint64_t out_bit_time; /* Time in nsec for a bitsize to be sent. */ unsigned int debug; bool check_ax25; bool do_crc; gensiods framecount; gensiods framenr; /* Previous level (mark = 1, space = 0) we received. */ unsigned int prev_recv_level; unsigned int prev_best_pos; /* Level we sent last time. */ unsigned char prev_xmit_level; /* * Data to deliver to the upper layer. We double buffer and swap * buffers when new data is ready. */ gensiods max_read_size; unsigned char *deliver_data; gensiods deliver_data_pos; gensiods deliver_data_len; /* IIR filter components. */ float coefa[2]; float coefb[3]; float iirhold[2]; /* FIR Filter components. */ float *fir_h; unsigned int fir_h_n; float *firhold; /* Filtered data. */ unsigned char *filteredbuf; /* * Correlation tables. First 2 * in_corrsize values is sine, second * 2 * in_corrsize values is cosine. */ float *hzmark; float *hzspace; /* * Use this to tell if we are receiving valid data, mostly to know if * we can transmit. If nr_in_sync is > the given value, we are in * sync. When a single sync is missed, set nr_in_sync to the given * value to hurry it being reduced. We then track how long we have * been out of sync. */ #define IN_SYNC 16 #define SYNC_RESET 32 unsigned int nr_in_sync; unsigned int nr_out_sync; unsigned int start_xmit_delay_count; /* * Certainty value that we say is a known good bit. */ float min_certainty; /* * Current position in the input, holds this value between frame * processing. Values from 0 to in_corrsize-1 are in the prevread * buffer, greater values index into the current received buffer. */ unsigned int curr_in_pos; /* * 2 * in_corrsize frames from end of the previous buffer. */ unsigned char *prevread; unsigned int prevread_size; /* * Messages we are currently working on assembling. */ struct wmsgset *wmsgsets; unsigned int wmsg_sets; /* Size of wmsgsets. */ unsigned int max_wmsgs; /* Size of wmsgs in each wmsgset. */ /* * The number of in_corrsize intervals to wait before transmitting. */ unsigned int tx_delay; /* * The number of bytes left to send in a preamble or postamble. */ unsigned int send_count; enum { NOT_SENDING, WAITING_ENDXMIT, WAITING_TRANSMIT, /* We will not transmit here and before. */ SENDING_PREAMBLE, SENDING_MSG, SENDING_POSTAMBLE } transmit_state; bool starting_output_ready; #define NR_WRITE_BUFS 2 gensiods max_write_size; struct wrbuf wrbufs[NR_WRITE_BUFS]; unsigned int curr_wrbuf; unsigned int nr_wrbufs; unsigned char wrbyte; unsigned char wrbyte_bit; unsigned int send_countdown; /* Count the message 1's transmitted to know when to bit stuff. */ unsigned int num_xmit_1; bool bitstuff; /* * Just a sine wave at the given frequencies scaled by volume. * The transmit entries point into these. */ float *mark_xmit; float *space_xmit; unsigned int mark_xmit_len; unsigned int space_xmit_len; /* The entry we just sent. */ struct xmit_entry *curr_xmit_ent; /* All the entries, for cleanup. */ struct xmit_entry *xmit_ent_list; unsigned char *xmit_buf; gensiods write_pos; gensiods xmit_buf_pos; gensiods xmit_buf_len; gensiods max_xmit_buf; unsigned int num_bytes_sent_this_xmit; enum { KEY_CLOSED, KEY_IN_OPEN, KEY_OPEN, KEY_IN_CLOSE, } key_io_state; enum afskmdm_keytype keytype; struct gensio *key_io; char *key; char *keyon; char *keyoff; int key_err; bool keyed; /* Is the transmitter keyed? */ }; #include "crc.h" #define filter_to_afskmdm(v) ((struct afskmdm_filter *) \ gensio_filter_get_user_data(v)) static void afskmdm_lock(struct afskmdm_filter *sfilter) { sfilter->o->lock(sfilter->lock); } static void afskmdm_unlock(struct afskmdm_filter *sfilter) { sfilter->o->unlock(sfilter->lock); } static void afskmdm_set_callbacks(struct gensio_filter *filter, gensio_filter_cb cb, void *cb_data) { struct afskmdm_filter *sfilter = filter_to_afskmdm(filter); sfilter->filter_cb = cb; sfilter->filter_cb_data = cb_data; } static bool afskmdm_ul_read_pending(struct gensio_filter *filter) { struct afskmdm_filter *sfilter = filter_to_afskmdm(filter); bool rv; afskmdm_lock(sfilter); rv = sfilter->deliver_data_len > 0; afskmdm_unlock(sfilter); return rv; } static bool afskmdm_ll_write_pending(struct gensio_filter *filter) { struct afskmdm_filter *sfilter = filter_to_afskmdm(filter); bool rv; afskmdm_lock(sfilter); rv = sfilter->xmit_buf_len > 0 || sfilter->starting_output_ready; afskmdm_unlock(sfilter); return rv; } static bool afskmdm_ll_read_needed(struct gensio_filter *filter) { return true; } static int afskmdm_ul_can_write(struct gensio_filter *filter, bool *val) { struct afskmdm_filter *sfilter = filter_to_afskmdm(filter); afskmdm_lock(sfilter); *val = sfilter->nr_wrbufs < NR_WRITE_BUFS; afskmdm_unlock(sfilter); return 0; } static int afskmdm_check_open_done(struct gensio_filter *filter, struct gensio *io) { return 0; } static int decode_ax25_control_field(char *str, size_t strlen, unsigned char *buf, unsigned int buflen) { static char *sname[4] = { "RR", "RNR", "REJ", "SREJ" }; static char *uname[32] = { [0x0f] = "SABME", [0x07] = "SABM", [0x08] = "DISC", [0x03] = "DM", [0x0c] = "UA", [0x11] = "FRMR", [0x00] = "UI", [0x17] = "XID", [0x1c] = "TEST" }; if ((*buf & 1) == 0) { /* I frame. */ snprintf(str, strlen, "I p=%d nr=%d ns=%d", (*buf >> 4) & 1, (*buf >> 5) & 0x7, (*buf >> 1) & 0x7); } else if ((*buf & 0x3) == 1) { /* S frame */ snprintf(str, strlen, "%s pf=%d nr=%d", sname[(*buf >> 2) & 0x3], (*buf >> 4) & 1, (*buf >> 5) & 0x7); } else { /* UI frame. */ char *n = uname[((*buf >> 2) & 0x3) | ((*buf >> 3) & 0x1c)]; if (!n) n = "?"; snprintf(str, strlen, "%s pf=%d", n, (*buf >> 4) & 1); } return 0; } static void afskmdm_ax25_prmsg(struct gensio_os_funcs *o, unsigned char *buf, unsigned int buflen) { struct gensio_ax25_addr addr; char str[100]; gensiods pos = 0, pos2 = 0; int err; if (buflen < 15) return; err = decode_ax25_addr(o, buf, &pos, buflen, 0, &addr); if (err) return; err = addr.r.funcs->addr_to_str(&addr.r, str, &pos2, sizeof(str)); if (err) return; printf(" %s", str); printf(" ch=%d", addr.dest.ch); if (pos < buflen) { err = decode_ax25_control_field(str, sizeof(str), buf + pos, buflen - pos); if (err) return; printf(" %s", str); } } static void afskmdm_print_msg(struct afskmdm_filter *sfilter, char *t, unsigned int msgn, unsigned char *buf, unsigned int buflen, bool pr_msgn) { struct gensio_os_funcs *o = sfilter->o; struct gensio_fdump h; if (sfilter->debug & GENSIO_AFSKMDM_DEBUG_TIME) { gensio_time time; o->get_monotonic_time(o, &time); printf("%lld:%6.6d: ", (long long) time.secs, (time.nsecs + 500) / 1000); } if (pr_msgn) { printf("%sMSG(%u %u):", t, msgn, buflen); } else { printf("%sMSG(%u):", t, buflen); afskmdm_ax25_prmsg(sfilter->o, buf, buflen); } printf("\n"); gensio_fdump_init(&h, 1); gensio_fdump_buf(stdout, buf, buflen, &h); gensio_fdump_buf_finish(stdout, &h); fflush(stdout); } static void keyop_done(struct gensio *io, int err, const char *buf, gensiods len, void *cb_data) { if (err) gensio_filter_log(cb_data, GENSIO_LOG_WARNING, "afskmdm: Error keying transmitter: %s\n", gensio_err_to_str(err)); } static void afskmdm_do_keyon(struct afskmdm_filter *sfilter) { int rv; if (!sfilter->key_io) return; switch (sfilter->keytype) { case KEY_RW: gensio_write(sfilter->key_io, NULL, sfilter->keyon, strlen(sfilter->keyon), NULL); break; case KEY_RTS: rv = gensio_acontrol(sfilter->key_io, GENSIO_CONTROL_DEPTH_FIRST, GENSIO_CONTROL_SET, GENSIO_ACONTROL_SER_RTS, "on", 0, keyop_done, sfilter->filter, NULL); if (rv) keyop_done(sfilter->key_io, rv, NULL, 0, sfilter->filter); break; case KEY_RTSINV: rv = gensio_acontrol(sfilter->key_io, GENSIO_CONTROL_DEPTH_FIRST, GENSIO_CONTROL_SET, GENSIO_ACONTROL_SER_RTS, "off", 0, keyop_done, sfilter->filter, NULL); if (rv) keyop_done(sfilter->key_io, rv, NULL, 0, sfilter->filter); break; case KEY_DTR: rv = gensio_acontrol(sfilter->key_io, GENSIO_CONTROL_DEPTH_FIRST, GENSIO_CONTROL_SET, GENSIO_ACONTROL_SER_DTR, "on", 0, keyop_done, sfilter->filter, NULL); if (rv) keyop_done(sfilter->key_io, rv, NULL, 0, sfilter->filter); break; case KEY_DTRINV: rv = gensio_acontrol(sfilter->key_io, GENSIO_CONTROL_DEPTH_FIRST, GENSIO_CONTROL_SET, GENSIO_ACONTROL_SER_DTR, "off", 0, keyop_done, sfilter->filter, NULL); if (rv) keyop_done(sfilter->key_io, rv, NULL, 0, sfilter->filter); break; case KEY_CM108: /* Should never happen. */ assert(0); } sfilter->keyed = true; } static void afskmdm_do_keyoff(struct afskmdm_filter *sfilter) { int rv; if (!sfilter->key_io) return; switch (sfilter->keytype) { case KEY_RW: gensio_write(sfilter->key_io, NULL, sfilter->keyoff, strlen(sfilter->keyoff), NULL); break; case KEY_RTS: rv = gensio_acontrol(sfilter->key_io, GENSIO_CONTROL_DEPTH_FIRST, GENSIO_CONTROL_SET, GENSIO_ACONTROL_SER_RTS, "off", 0, keyop_done, sfilter->filter, NULL); if (rv) keyop_done(sfilter->key_io, rv, NULL, 0, sfilter->filter); break; case KEY_RTSINV: rv = gensio_acontrol(sfilter->key_io, GENSIO_CONTROL_DEPTH_FIRST, GENSIO_CONTROL_SET, GENSIO_ACONTROL_SER_RTS, "on", 0, keyop_done, sfilter->filter, NULL); if (rv) keyop_done(sfilter->key_io, rv, NULL, 0, sfilter->filter); break; case KEY_DTR: rv = gensio_acontrol(sfilter->key_io, GENSIO_CONTROL_DEPTH_FIRST, GENSIO_CONTROL_SET, GENSIO_ACONTROL_SER_DTR, "off", 0, keyop_done, sfilter->filter, NULL); if (rv) keyop_done(sfilter->key_io, rv, NULL, 0, sfilter->filter); break; case KEY_DTRINV: rv = gensio_acontrol(sfilter->key_io, GENSIO_CONTROL_DEPTH_FIRST, GENSIO_CONTROL_SET, GENSIO_ACONTROL_SER_DTR, "on", 0, keyop_done, sfilter->filter, NULL); if (rv) keyop_done(sfilter->key_io, rv, NULL, 0, sfilter->filter); break; case KEY_CM108: /* Should never happen. */ assert(0); } sfilter->keyed = false; } static int key_cb(struct gensio *io, void *user_data, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) { struct afskmdm_filter *sfilter = user_data; switch(event) { case GENSIO_EVENT_READ: return 0; case GENSIO_EVENT_WRITE_READY: return 0; case GENSIO_EVENT_PARMLOG: { struct gensio_parmlog_data *d = (struct gensio_parmlog_data *) buf; gensio_pparm_vlog(&sfilter->p, d->log, d->args); return 0; } default: return GE_NOTSUP; } } static void key_open_done(struct gensio *io, int err, void *open_data) { struct afskmdm_filter *sfilter = open_data; if (err) { sfilter->key_io_state = KEY_CLOSED; gensio_filter_log(sfilter->filter, GENSIO_LOG_ERR, "afskmdm: Error from open key I/O '%s': %s", sfilter->key, gensio_err_to_str(err)); } else { sfilter->key_io_state = KEY_OPEN; afskmdm_do_keyoff(sfilter); } sfilter->key_err = err; /* Just turn on read and ignore what we get. */ gensio_set_read_callback_enable(io, true); sfilter->filter_cb(sfilter->filter_cb_data, GENSIO_FILTER_CB_OPEN_DONE, NULL); } static int afskmdm_try_connect(struct gensio_filter *filter, gensio_time *timeout, bool was_timeout) { struct afskmdm_filter *sfilter = filter_to_afskmdm(filter); int err = sfilter->key_err; if (err) { sfilter->key_err = 0; return err; } if (sfilter->key_io && sfilter->key_io_state != KEY_IN_OPEN && sfilter->key_io_state != KEY_OPEN) { err = gensio_open(sfilter->key_io, key_open_done, sfilter); if (err) { gensio_filter_log(sfilter->filter, GENSIO_LOG_ERR, "afskmdm: Unable to open key I/O '%s': %s", sfilter->key, gensio_err_to_str(err)); return err; } sfilter->key_io_state = KEY_IN_OPEN; } if (sfilter->key_io_state == KEY_IN_OPEN) { timeout->secs = 0; timeout->nsecs = GENSIO_MSECS_TO_NSECS(10); return GE_RETRY; } return 0; } static void key_close_done(struct gensio *io, void *close_data) { struct afskmdm_filter *sfilter = close_data; sfilter->key_io_state = KEY_CLOSED; } static int afskmdm_try_disconnect(struct gensio_filter *filter, gensio_time *timeout, bool was_timeout) { struct afskmdm_filter *sfilter = filter_to_afskmdm(filter); int err; if (sfilter->key_io_state == KEY_OPEN) { afskmdm_do_keyoff(sfilter); err = gensio_close(sfilter->key_io, key_close_done, sfilter); if (err) { sfilter->key_io_state = KEY_CLOSED; gensio_filter_log(sfilter->filter, GENSIO_LOG_WARNING, "afskmdm: Error from close key I/O '%s': %s", sfilter->key, gensio_err_to_str(err)); } else { sfilter->key_io_state = KEY_IN_CLOSE; } } if (sfilter->key_io_state == KEY_IN_CLOSE) { timeout->secs = 0; timeout->nsecs = GENSIO_MSECS_TO_NSECS(10); return GE_RETRY; } if (sfilter->transmit_state != NOT_SENDING) return GE_INPROGRESS; return 0; } static void afskmdm_start_xmit(struct afskmdm_filter *sfilter) { sfilter->num_bytes_sent_this_xmit = 0; sfilter->transmit_state = SENDING_PREAMBLE; sfilter->wrbyte = 0x7e; sfilter->wrbyte_bit = 0; sfilter->send_count = (sfilter->tx_preamble_time / sfilter->out_bit_time / 8); sfilter->bitstuff = false; sfilter->starting_output_ready = true; afskmdm_do_keyon(sfilter); } static void afskmdm_start_drain_timer(struct afskmdm_filter *sfilter) { unsigned long frames_left = 0; struct gensio_filter_cb_control_data cd; char buf[20] = "0"; gensiods buflen = sizeof(buf); uint64_t timeoutns; gensio_time timeout; cd.depth = GENSIO_CONTROL_DEPTH_FIRST; cd.get = true; cd.option = GENSIO_CONTROL_DRAIN_COUNT; cd.data = buf; cd.datalen = &buflen; sfilter->filter_cb(sfilter->filter_cb_data, GENSIO_FILTER_CB_CONTROL, &cd); frames_left = strtoul(buf, NULL, 0); /* * Set a timer to know when we are done transmitting. */ timeoutns = (uint64_t) frames_left * sfilter->nsec_per_frame; timeout.secs = timeoutns / GENSIO_NSECS_IN_SEC; timeout.nsecs = timeoutns % GENSIO_NSECS_IN_SEC; sfilter->filter_cb(sfilter->filter_cb_data, GENSIO_FILTER_CB_START_TIMER, &timeout); } static int afskmdm_timeout_done(struct gensio_filter *filter) { struct afskmdm_filter *sfilter = filter_to_afskmdm(filter); afskmdm_lock(sfilter); if (sfilter->nr_wrbufs > 0) { sfilter->transmit_state = WAITING_TRANSMIT; } else { sfilter->transmit_state = NOT_SENDING; } if (sfilter->keyed) afskmdm_do_keyoff(sfilter); afskmdm_unlock(sfilter); return 0; } static void afskmdm_check_start_xmit(struct afskmdm_filter *sfilter) { unsigned int randv; /* Some primitive randomness. Could be improved. */ sfilter->o->get_random(sfilter->o, &randv, sizeof(randv)); randv %= 10; if (sfilter->start_xmit_delay_count + 1 > randv) { sfilter->start_xmit_delay_count = 0; afskmdm_start_xmit(sfilter); } else { sfilter->start_xmit_delay_count++; if (sfilter->curr_in_pos < sfilter->tx_delay / 10) sfilter->curr_in_pos = 0; else sfilter->curr_in_pos -= sfilter->tx_delay / 10; } } static void afskmdm_send_buffer(struct afskmdm_filter *sfilter, gensio_ul_filter_data_handler handler, void *cb_data) { int rv; gensiods count; struct gensio_sg sg; sg.buf = (sfilter->xmit_buf + (sfilter->xmit_buf_pos * sfilter->out_framesize)); sg.buflen = ((sfilter->xmit_buf_len - sfilter->xmit_buf_pos) * sfilter->out_framesize); rv = handler(cb_data, &count, &sg, 1, NULL); if (rv) { sfilter->err = rv; sfilter->xmit_buf_len = 0; sfilter->xmit_buf_pos = 0; sfilter->nr_wrbufs = 0; } else { if (count >= sg.buflen) { sfilter->xmit_buf_len = 0; sfilter->xmit_buf_pos = 0; } else { sfilter->xmit_buf_pos += count / sfilter->out_framesize; } } } static void afskmdm_add_wrbit(struct afskmdm_filter *sfilter) { unsigned char bit = sfilter->wrbyte & 1; unsigned char level = sfilter->prev_xmit_level; struct xmit_entry *curr = sfilter->curr_xmit_ent; unsigned int send_alt = 0, i, j; float *s; if (sfilter->out_bit_adj) { sfilter->out_bit_counter++; if (sfilter->out_bit_counter == sfilter->out_bit_period) { sfilter->out_bit_counter = 0; send_alt = 2; } } if (sfilter->transmit_state == SENDING_MSG) { if (sfilter->bitstuff) { sfilter->bitstuff = false; sfilter->num_xmit_1 = 0; bit = 0; goto skip_increment; } else if (bit) { sfilter->num_xmit_1++; if (sfilter->num_xmit_1 == 5) sfilter->bitstuff = true; } else { sfilter->num_xmit_1 = 0; } } sfilter->wrbyte >>= 1; sfilter->wrbyte_bit++; skip_increment: /* If the bit is 0, change the frequency. 1 leaves it the same. */ if (!bit) level = !level; sfilter->prev_xmit_level = level; curr = curr->next_send[level + send_alt]; sfilter->curr_xmit_ent = curr; s = (float *) sfilter->xmit_buf; s += sfilter->xmit_buf_len * sfilter->out_nchans; for (i = 0; i < curr->size; i++) { for (j = 0; j < sfilter->out_nchans; j++) { if ((1 << j) & sfilter->out_chans) *s++ = curr->data[i]; else *s++ = 0.; } } sfilter->xmit_buf_len += curr->size; } static void afskmdm_handle_send(struct afskmdm_filter *sfilter, gensio_ul_filter_data_handler handler, void *cb_data) { sfilter->starting_output_ready = false; if (sfilter->xmit_buf_len > 0) { afskmdm_send_buffer(sfilter, handler, cb_data); if (sfilter->xmit_buf_len > 0) goto out; if (sfilter->transmit_state == WAITING_ENDXMIT) afskmdm_start_drain_timer(sfilter); } while (sfilter->transmit_state > WAITING_TRANSMIT) { if (sfilter->bitstuff || sfilter->wrbyte_bit < 8) { afskmdm_add_wrbit(sfilter); if (sfilter->xmit_buf_len >= sfilter->max_xmit_buf - sfilter->max_out_bitsize) { afskmdm_send_buffer(sfilter, handler, cb_data); if (sfilter->err) goto out; if (sfilter->xmit_buf_len > 0) goto out; } } /* Make sure to send the last bitstuff. */ if (!sfilter->bitstuff && sfilter->wrbyte_bit >= 8) { sfilter->wrbyte_bit = 0; switch (sfilter->transmit_state) { case NOT_SENDING: case WAITING_TRANSMIT: case WAITING_ENDXMIT: goto out; /* Should not happen. */ case SENDING_PREAMBLE: sfilter->send_count--; if (sfilter->send_count > 0) { sfilter->wrbyte = 0x7e; } else { unsigned int cbuf = sfilter->curr_wrbuf; sfilter->num_bytes_sent_this_xmit++; sfilter->wrbyte = sfilter->wrbufs[cbuf].data[0]; sfilter->write_pos = 1; sfilter->num_xmit_1 = 0; sfilter->transmit_state = SENDING_MSG; /* All messages are at least 3 bytes, no check for done. */ } break; case SENDING_MSG: { unsigned int cbuf = sfilter->curr_wrbuf; if (sfilter->write_pos >= sfilter->wrbufs[cbuf].len) { sfilter->write_pos = 0; sfilter->curr_wrbuf = (cbuf + 1) % NR_WRITE_BUFS; sfilter->nr_wrbufs--; if (sfilter->nr_wrbufs > 0 && sfilter->num_bytes_sent_this_xmit < 128) { /* * We haven't sent too many bytes, and we have * another message. Just throw in a couple of * flags and start it. */ sfilter->transmit_state = SENDING_PREAMBLE; sfilter->wrbyte = 0x7e; sfilter->send_count = 2; } else { sfilter->transmit_state = SENDING_POSTAMBLE; sfilter->wrbyte = 0x7e; sfilter->send_count = (sfilter->tx_postamble_time / sfilter->out_bit_time / 8); } } else { unsigned int pos = sfilter->write_pos++; sfilter->num_bytes_sent_this_xmit++; sfilter->wrbyte = sfilter->wrbufs[cbuf].data[pos]; } break; } case SENDING_POSTAMBLE: sfilter->send_count--; if (sfilter->send_count > 0) { sfilter->wrbyte = 0x7e; } else { sfilter->nr_out_sync = 0; sfilter->transmit_state = WAITING_ENDXMIT; if (sfilter->xmit_buf_len == 0) /* * No more data to send, start the timer now. */ afskmdm_start_drain_timer(sfilter); /* * Otherwise, start the timer when all * the data has been sent. */ goto out; } break; } } } out: return; } static int afskmdm_ul_write(struct gensio_filter *filter, gensio_ul_filter_data_handler handler, void *cb_data, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { struct afskmdm_filter *sfilter = filter_to_afskmdm(filter); gensiods i, count = 0, len; unsigned int cbuf; uint16_t crc; int rv = 0; afskmdm_lock(sfilter); if (sfilter->err) { rv = sfilter->err; goto out; } if (sfilter->nr_wrbufs >= NR_WRITE_BUFS || sglen == 0) goto out_process; cbuf = (sfilter->curr_wrbuf + sfilter->nr_wrbufs) % NR_WRITE_BUFS; sfilter->wrbufs[cbuf].len = 0; for (i = 0; i < sglen; i++) { len = sg[i].buflen; if (sfilter->wrbufs[cbuf].len + len > sfilter->max_write_size) len = sfilter->max_write_size - sfilter->wrbufs[cbuf].len; memcpy(sfilter->wrbufs[cbuf].data + sfilter->wrbufs[cbuf].len, sg[i].buf, len); sfilter->wrbufs[cbuf].len += len; count += len; } if (count == 0) goto out_process; if (sfilter->debug & GENSIO_AFSKMDM_DEBUG_MSG) { afskmdm_print_msg(sfilter, "W", 0, sfilter->wrbufs[cbuf].data, sfilter->wrbufs[cbuf].len, false); } if (sfilter->do_crc) { /* We have two extra bytes on the end for the CRC, no check needed. */ crc = 0xffff; len = sfilter->wrbufs[cbuf].len; crc16_ccitt(sfilter->wrbufs[cbuf].data, len, &crc); crc ^= 0xffff; sfilter->wrbufs[cbuf].data[len++] = crc & 0xff; sfilter->wrbufs[cbuf].data[len++] = (crc >> 8) & 0xff; sfilter->wrbufs[cbuf].len = len; } sfilter->nr_wrbufs++; if (sfilter->transmit_state != NOT_SENDING) goto out_process; if (sfilter->full_duplex || sfilter->nr_out_sync >= sfilter->tx_delay) { afskmdm_start_xmit(sfilter); } else { sfilter->transmit_state = WAITING_TRANSMIT; goto out; } out_process: afskmdm_handle_send(sfilter, handler, cb_data); out: afskmdm_unlock(sfilter); if (!rv && rcount) *rcount = count; return rv; } #if 0 static float afskmdm_measure_power(struct afskmdm_filter *sfilter, unsigned int curpos, unsigned char *buf1, unsigned char *buf2) { float *s1 = (float *) buf1 + sfilter->chan; float *s2 = (float *) buf2 + sfilter->chan; float power = 0, v; unsigned int i; if (curpos < sfilter->prevread_size) s1 += curpos * sfilter->in_nchans; else s2 += (curpos - sfilter->prevread_size) * sfilter->in_nchans; for (i = 0; i < sfilter->in_corrsize; i++, curpos++) { if (curpos < sfilter->prevread_size) { v = *s1; s1 += sfilter->in_nchans; } else { v = *s2; s2 += sfilter->in_nchans; } power += v * v; } return power; } #endif /* * Do a double correlation. You generally do this against a sine and * cosine table, this lets you measure the power (and phase) of a signal * against the frequency of the sine/cosine. * * corrdata is the sine/cosine table to correlate against, the first 2 * * in_corrsize floats are the sine table, the second 2 * in_corrsize floats * are the cosine table. * * The data comes in two chunks, buf1 is 2 * in_corrsize frames at the * beginning, buf2 is chunksize frames after that. * * The input has extra data on both edges, the actually currently * aligned signal is in the middle. We start at the data past the * left edges and process that data. Then we store the data and * subtract off each frame from the left edge and add on the next data * until we have processed the whole right edge. This gives is values * in the "p" array where the middle value is the currently aligned * value, but we have power measurements assuming we move the alignment * point left and right. This lets us measure how well we are aligned * on a transition from a mark to a space. * * buf is an array of floats. So we have to cast it. The data may be * interleaved, meaning that frames from multiple channels may be in * it. We only care about one channel. So we have to multiply by the * number of channels and add the channel offset. * * Each correlation is done on in_corrsize frames of data. The first * in_corrsize bytes is processed and put into p[0] (power at the given * frequency). If edge > 0, then frames 1-(in_corrsize+1) are processed * and put into p[1], and so on. (This is done more efficiently by * tracking some values, subtracting off the beginning, and adding on * the end). * * You can think of edge as the number of values on each side of the * main signal. * * Multiple values lets you scan for data or align data. * * dummyp must be [edge * 4]. p must be [(edge * 2) + 1]. The input * data size must be bigger than edge * 2. */ static void afskmdm_dcorr(struct afskmdm_filter *sfilter, float *corrdata, unsigned int edge, unsigned int curpos, unsigned char *buf1, unsigned char *buf2, float p[], float dummyp[]) { /* There will always be one byte before the data, so the -1 ok. */ float *s1 = (float *) buf1 + sfilter->in_chan; float *s2 = (float *) buf2 + sfilter->in_chan; float *csin = corrdata; float *ccos = corrdata + 2 * sfilter->in_corrsize; float v; float psin = 0, pcos = 0; unsigned int i, ppos = 0, spos; if (curpos < sfilter->prevread_size) s1 += curpos * sfilter->in_nchans; else s2 += (curpos - sfilter->prevread_size) * sfilter->in_nchans; for (i = 0; i < sfilter->in_corrsize; i++, curpos++) { if (curpos < sfilter->prevread_size) { v = *s1; s1 += sfilter->in_nchans; } else { v = *s2; s2 += sfilter->in_nchans; } psin += *csin * v; pcos += *ccos * v; if (i < edge * 2) { dummyp[i * 2] = *csin * v; dummyp[i * 2 + 1] = *ccos * v; } csin++; ccos++; } p[ppos++] = psin * psin + pcos * pcos; for (spos = 0; i < sfilter->in_corrsize + (edge * 2); i++, curpos++, spos++) { /* Make sure we don't go past the end of the buffer. */ assert(curpos <= sfilter->prevread_size || curpos - sfilter->prevread_size < sfilter->in_chunksize); if (curpos < sfilter->prevread_size) { v = *s1; s1 += sfilter->in_nchans; } else { v = *s2; s2 += sfilter->in_nchans; } psin -= dummyp[spos * 2]; pcos -= dummyp[spos * 2 + 1]; psin += *csin++ * v; pcos += *ccos++ * v; p[ppos++] = psin * psin + pcos * pcos; } } static void afskmdm_drop_wmsg(struct afskmdm_filter *sfilter, unsigned int wset, unsigned int msgn, struct wmsg *w, bool at_flag) { struct wmsgset *ws = &sfilter->wmsgsets[wset]; if (at_flag && !ws->got_flag) { /* * If we get a flag, and no other flags have been detected in * this set, then we keep this particular data stream. * Otherwise, if we have an error in the flag before the * beginning of a message, we will split and then retire this * message. */ ws->got_flag = true; w->read_data_len = 0; w->num_uncertain = 0; w->certainty = 0.0; } else if (ws->curr_wmsgs == 1) { /* Always have one working message. */ if (sfilter->debug & GENSIO_AFSKMDM_DEBUG_STATE) printf("WMSG: restart\n"); w->read_data_len = 0; w->num_uncertain = 0; w->certainty = 0.0; w->state = AFSKMDM_STATE_PREAMBLE_SEARCH_0; } else { if (sfilter->debug & GENSIO_AFSKMDM_DEBUG_STATE) printf("WMSG: retire %u\n", msgn); ws->curr_wmsgs--; w->in_use = false; } } static void afskmdm_handle_new_byte(struct afskmdm_filter *sfilter, unsigned int wset, unsigned int msgn, struct wmsg *w) { if (sfilter->debug & GENSIO_AFSKMDM_DEBUG_BIT_HNDL) printf("BYTE(%d): %2.2x\n", msgn, w->curr_byte); if (w->read_data_len >= sfilter->max_read_size) { afskmdm_drop_wmsg(sfilter, wset, msgn, w, false); return; } w->read_data[w->read_data_len] = w->curr_byte; w->curr_byte = 0; w->curr_bit_pos = 0; w->read_data_len++; } static void afskmdm_handle_new_message(struct afskmdm_filter *sfilter, unsigned int pos, unsigned int wset, unsigned int msgn, struct wmsg *w) { uint16_t crc, msgcrc; unsigned int i; if (w->read_data_len < 3) goto bad_msg; if (sfilter->debug & GENSIO_AFSKMDM_DEBUG_RAW_MSG) { afskmdm_print_msg(sfilter, "", msgn, w->read_data, w->read_data_len, true); printf(" bitpos %d endframe %lu\n", w->curr_bit_pos, sfilter->framenr + pos - sfilter->prevread_size); } /* * If the bit position is 6, that means there was no extra data * bits data left after the last flag. Also, allow 5 in case the * sender didn't stuff the last bit in a message. */ if (w->curr_bit_pos != 6 && w->curr_bit_pos != 5) goto bad_msg; if (sfilter->do_crc) { crc = 0xffff; crc16_ccitt(w->read_data, w->read_data_len - 2, &crc); crc ^= 0xffff; msgcrc = ((w->read_data[w->read_data_len - 1] << 8) | w->read_data[w->read_data_len - 2]); if (sfilter->debug & GENSIO_AFSKMDM_DEBUG_RAW_MSG) printf(" CRC %4.4x, MSGCRC %4.4x\n", crc, msgcrc); if (crc != msgcrc) goto bad_msg; w->read_data_len -= 2; if (sfilter->check_ax25) { struct gensio_ax25_addr iaddr; gensiods ipos; int err; if (w->read_data_len < 16) goto bad_msg; ipos = 0; err = decode_ax25_addr(sfilter->o, w->read_data, &ipos, w->read_data_len, 0, &iaddr); if (err) goto bad_msg; } } if (sfilter->debug & GENSIO_AFSKMDM_DEBUG_MSG) { afskmdm_print_msg(sfilter, "R", 0, w->read_data, w->read_data_len, false); } if (sfilter->deliver_data_len == 0) { unsigned char *tmp; tmp = w->read_data; w->read_data = sfilter->deliver_data; sfilter->deliver_data = tmp; sfilter->deliver_data_len = w->read_data_len; sfilter->deliver_data_pos = 0; } /* Cancel all working messages. */ for (i = 0; i < sfilter->wmsg_sets; i++) { unsigned int j; for (j = 0; j < sfilter->max_wmsgs; j++) { sfilter->wmsgsets[i].wmsgs[j].read_data_len = 0; sfilter->wmsgsets[i].wmsgs[j].num_uncertain = 0; sfilter->wmsgsets[i].wmsgs[j].certainty = 0.0; } } return; bad_msg: afskmdm_drop_wmsg(sfilter, wset, msgn, w, true); } static void afskmdm_process_bit(struct afskmdm_filter *sfilter, unsigned int pos, unsigned int wset, unsigned int msgn, unsigned char level, float certainty, bool *in_sync) { unsigned int prev_num_rcv_1; unsigned char bit; struct wmsg *w = &sfilter->wmsgsets[wset].wmsgs[msgn]; if (!w->in_use) return; if (certainty > 0.0 && certainty < sfilter->min_certainty && !w->new_wmsg) { /* * We aren't sure about this bit, try both possibilities if possible. */ unsigned int i; float min_certainty = FLT_MAX; unsigned int min_cert_pos = 0; float this_certainty = (((w->certainty * w->num_uncertain) + certainty) / (w->num_uncertain + 1)); float alt_certainty = (((w->certainty * w->num_uncertain) + 1/certainty) / (w->num_uncertain + 1)); w->certainty = this_certainty; w->num_uncertain++; for (i = 0; i < sfilter->max_wmsgs; i++) { if (i == msgn) continue; if (!sfilter->wmsgsets[wset].wmsgs[i].in_use) { struct wmsg *w2; add_wmsg_at: w2 = &sfilter->wmsgsets[wset].wmsgs[i]; w2->in_use = true; w2->certainty = alt_certainty; w2->num_uncertain = w->num_uncertain; w2->num_rcv_1 = w->num_rcv_1; w2->prev_recv_level = w->prev_recv_level; w2->state = w->state; w2->curr_byte = w->curr_byte; w2->curr_bit_pos = w->curr_bit_pos; w2->read_data_len = w->read_data_len; memcpy(w2->read_data, w->read_data, w->read_data_len); if (sfilter->debug & GENSIO_AFSKMDM_DEBUG_STATE) printf("WMSG: add %u %u\n", wset, i); sfilter->wmsgsets[wset].curr_wmsgs++; w2->new_wmsg = true; if (i < msgn) { /* Process this bit, since we won't get it in the main. */ afskmdm_process_bit(sfilter, pos, wset, i, !level, certainty, in_sync); } else { /* * The bit processing will get this bit later, process * the !bit here. */ level = !level; w2->certainty = this_certainty; w->certainty = alt_certainty; } break; } if (sfilter->wmsgsets[wset].wmsgs[i].certainty < min_certainty) { /* Keep a running track of the smallest certainty value. */ min_certainty = sfilter->wmsgsets[wset].wmsgs[i].certainty; min_cert_pos = i; } } if (i == sfilter->max_wmsgs && alt_certainty > min_certainty) { /* * If the certainty of the current message is greater than * the certainty of a message in the table, kick out the * lowest certainty message and replace it with this * message. */ sfilter->wmsgsets[wset].curr_wmsgs--; i = min_cert_pos; goto add_wmsg_at; } } w->new_wmsg = false; /* * The bit is 0 if the frequency changed, 1 if the frequency * stayed the same. */ bit = level == w->prev_recv_level; w->prev_recv_level = level; if (sfilter->debug & GENSIO_AFSKMDM_DEBUG_BIT_HNDL) printf("BIT(%u %u %lu): l:%d b:%d %f (%d)\n", wset, msgn, sfilter->framenr + pos - sfilter->prevread_size, level, bit, certainty, w->state); prev_num_rcv_1 = w->num_rcv_1; if (bit) w->num_rcv_1++; else w->num_rcv_1 = 0; switch (w->state) { case AFSKMDM_STATE_PREAMBLE_SEARCH_0: if (!bit) w->state = AFSKMDM_STATE_PREAMBLE_FIRST_0; *in_sync = false; break; case AFSKMDM_STATE_PREAMBLE_FIRST_0: if (bit) w->state = AFSKMDM_STATE_PREAMBLE_1; *in_sync = false; break; case AFSKMDM_STATE_PREAMBLE_1: if (!bit) w->state = AFSKMDM_STATE_PREAMBLE_FIRST_0; else if (w->num_rcv_1 == 6) w->state = AFSKMDM_STATE_PREAMBLE_LAST_0; *in_sync = false; break; case AFSKMDM_STATE_PREAMBLE_LAST_0: if (bit) { w->state = AFSKMDM_STATE_PREAMBLE_SEARCH_0; } else { w->state = AFSKMDM_STATE_IN_MSG; w->curr_byte = 0; w->curr_bit_pos = 0; *in_sync = false; } break; case AFSKMDM_STATE_IN_MSG: if (prev_num_rcv_1 == 5) { if (bit) w->state = AFSKMDM_STATE_POSTAMBLE_LAST_0; /* Otherwise it's a bit-stuffed zero and we ignore it. */ break; } w->curr_byte |= bit << w->curr_bit_pos; if (w->curr_bit_pos == 7) afskmdm_handle_new_byte(sfilter, wset, msgn, w); else w->curr_bit_pos++; break; case AFSKMDM_STATE_POSTAMBLE_LAST_0: if (!bit) { afskmdm_handle_new_message(sfilter, pos, wset, msgn, w); w->state = AFSKMDM_STATE_IN_MSG; w->curr_byte = 0; w->curr_bit_pos = 0; } else { afskmdm_drop_wmsg(sfilter, wset, msgn, w, false); *in_sync = false; } break; default: assert(0); } } /* * We have a set of frames. Look through them all and choose the one * with the most certainty. */ static void process_powers(struct afskmdm_filter *sfilter, float pmark[CORREXTRA], float pspace[CORREXTRA], unsigned int *rbest_pos, float *rcertainty, unsigned char *rlevel) { float tcertainty; unsigned char tlevel; unsigned int i; for (i = 0; i < CORREXTRA; i++) { if (pspace[i] > pmark[i]) { tlevel = 0; tcertainty = pspace[i] / pmark[i]; } else { tlevel = 1; tcertainty = pmark[i] / pspace[i]; } if (isnan(tcertainty) || isinf(tcertainty)) tcertainty = 0.0; if (tcertainty >= *rcertainty) { *rbest_pos = i; *rlevel = tlevel; *rcertainty = tcertainty; } } } /* * Do a correlation at mark and space the data then call the bit * processing with the info extracted from the data. */ static void afskmdm_check_for_data(struct afskmdm_filter *sfilter, unsigned int *curpos, unsigned char *buf1, unsigned char *buf2, bool *in_sync) { float pmark[CORREXTRA], pspace[CORREXTRA]; float pmark2[CORREXTRA], pspace2[CORREXTRA]; float dummyp[CORREDGE * 4]; unsigned char level = sfilter->prev_recv_level; unsigned int i, best_pos = 0, wset; float certainty = 0.0, m; afskmdm_dcorr(sfilter, sfilter->hzmark, CORREDGE, (*curpos) - CORREDGE, buf1, buf2, pmark, dummyp); afskmdm_dcorr(sfilter, sfilter->hzspace, CORREDGE, (*curpos) - CORREDGE, buf1, buf2, pspace, dummyp); process_powers(sfilter, pmark, pspace, &best_pos, &certainty, &level); if (sfilter->debug & GENSIO_AFSKMDM_DEBUG_BIT_HNDL) { printf("CORR(%lu %u %lu):\n", sfilter->framecount++, *curpos, sfilter->framenr + *curpos - sfilter->prevread_size); for (i = 0; i < CORREXTRA; i++) printf(" %f", pmark[i]); printf("\n %d ", level); for (i = 0; i < CORREXTRA; i++) printf(" %f", pspace[i]); printf("\n"); } if (sfilter->prev_recv_level != level) { /* * Check re-align on a 1->0 or 0->1 level transition. You * can't align on no transition because you have to have a * boundary to check against. */ if (sfilter->prev_best_pos > CORRMIDDLE) *curpos += 1; else if (sfilter->prev_best_pos < CORRMIDDLE) *curpos -= 1; if (best_pos > CORRMIDDLE) *curpos += 1; else if (best_pos < CORRMIDDLE) *curpos -= 1; } sfilter->prev_recv_level = level; sfilter->prev_best_pos = best_pos; sfilter->wmsgsets[0].got_flag = false; for (i = 0; i < sfilter->max_wmsgs; i++) afskmdm_process_bit(sfilter, *curpos, 0, i, level, certainty, in_sync); for (wset = 1, m = 4.0; wset < sfilter->wmsg_sets; wset += 2, m += 4.0) { for (i = 0; i < CORREXTRA; i++) pmark2[i] = pmark[i] * m; certainty = 0.0; process_powers(sfilter, pmark2, pspace, &best_pos, &certainty, &level); sfilter->wmsgsets[wset].got_flag = false; for (i = 0; i < sfilter->max_wmsgs; i++) afskmdm_process_bit(sfilter, *curpos, wset, i, level, certainty, in_sync); for (i = 0; i < CORREXTRA; i++) pspace2[i] = pspace[i] * m; certainty = 0.0; process_powers(sfilter, pmark, pspace2, &best_pos, &certainty, &level); sfilter->wmsgsets[wset + 1].got_flag = false; for (i = 0; i < sfilter->max_wmsgs; i++) afskmdm_process_bit(sfilter, *curpos, wset + 1, i, level, certainty, in_sync); } } /* * Implement a basic 2nd-order IIR filter. */ static void afskmdm_iir_filter(float *inbuf, float *outbuf, unsigned int nsamples, unsigned int nchans, unsigned int chan, float coefa[2], float coefb[3], float hold[2]) { unsigned int i; float tmp; /* hold[0] = z^-1, hold[1] = z^-2 */ for (i = chan; i < nsamples * nchans; i += nchans) { tmp = inbuf[i] + coefa[0] * hold[0] + coefa[1] * hold[1]; outbuf[i] = tmp * coefb[0] + coefb[1] * hold[0] + coefb[2] * hold[1]; hold[1] = hold[0]; hold[0] = tmp; } } /* * Calculate 2nd order IIR filter coefficients for a low-pass * Butterworth filter. * * See https://www.staff.ncl.ac.uk/oliver.hinton/eee305/Chapter5.pdf * for more explaination. */ static void afskmdm_calc_iir_coefs(float samplerate, float cutoff, float coefa[], float coefb[]) { float w1 = 2 * M_PI * cutoff / samplerate; float w = tan(w1 / 2); /* omega */ float w2 = w * w; /* omega ^ 2 */ float denom = w2 + M_SQRT2 * w + 1; coefa[0] = (2 - 2 * w2) / denom; coefa[1] = - (1 - M_SQRT2 * w + w2) / denom; coefb[0] = w2 / denom; coefb[1] = 2 * coefb[0]; coefb[2] = coefb[0]; } static float get_fir_val(unsigned int i, unsigned int holdsize, float *inbuf, float *hold, unsigned int nchans, unsigned int chan) { if (i < holdsize) return hold[i]; i -= holdsize; i = (i * nchans) + chan; return inbuf[i]; } /* * Process a buffer with a fir filter. h and n come from * afskmdm_calc_fir_coefs(), hold must be of size n * 2. */ static void afskmdm_fir_filter(float *inbuf, float *outbuf, unsigned int nsamples, unsigned int nchans, unsigned int chan, unsigned int n, float *h, float *hold) { unsigned int i, j, k; unsigned int holdsize = n * 2; float tmp; for (i = 0; i < nsamples; i++) { /* Get the middle value, it's always multiplied by 1. */ tmp = get_fir_val(n + i, holdsize, inbuf, hold, nchans, chan); /* * The h array is half of a symmetric waveform. That waveform * is always an odd number of values, but we don't include the * middle value (it's always one, handled above) and h only * holds the left half of the waveform. */ for (j = 0, k = holdsize; j < n; j++, k--) { tmp += h[j] * (get_fir_val(i + j, holdsize, inbuf, hold, nchans, chan) + get_fir_val(i + k, holdsize, inbuf, hold, nchans, chan)); } outbuf[i * nchans + chan] = tmp; } for (i = 0; i < holdsize; i++) { unsigned int pos = nsamples - holdsize + i; hold[i] = inbuf[pos * nchans + chan]; } } /* * Calculate FIR filter coefficients for a lowpass filter with the * given transition band size, sample rate and cutoff frequency. * The total number of coefficients is: * * N = (n * 2) + 1 * * but the middle value is always 1 and the coefficients are symmetric * about the middle value. Thus we only really need n values because * h[n] would be 1 and h[i] == h[N - i - 1]. * * A hamming filter is applied to the coefficients. * * Adapted from http://www.labbookpages.co.uk/audio/firWindowing.html * and https://www.staff.ncl.ac.uk/oliver.hinton/eee305/Chapter4.pdf */ static float * afskmdm_calc_fir_coefs(struct gensio_os_funcs *o, double samplerate, double cutoff, double transband, unsigned int *rn) { double tba = transband / samplerate; double coa = cutoff / samplerate; double w = 2 * M_PI * (coa + .5 * tba); unsigned int i; /* For a hamming filter, transition band ~ (3.3 / N). */ double N = ceil(3.3 / tba); unsigned int n; double x = 1.0; float *h; n = (int) (N + .1); /* N should be at a whole number, add .1 to be sure. */ if (n % 2 == 0) N += 1.0; /* N must be odd. */ n /= 2; /* Here, N = n * 2 + 1 */ h = o->zalloc(o, n * sizeof(float)); if (!h) return NULL; for (i = n - 1; ; i--) { double tmp; /* h(x) = 2 * f * sinc() */ tmp = sin(x * w) / (x * M_PI); /* Hamming window */ tmp *= .54 - .46 * cos(2 * M_PI * (i + 1) / N); h[i] = tmp; if (i == 0) break; x += 1.0; } *rn = n; return h; } static int afskmdm_ll_write(struct gensio_filter *filter, gensio_ll_filter_data_handler handler, void *cb_data, gensiods *rcount, unsigned char *buf, gensiods buflen, const char *const *auxdata) { struct afskmdm_filter *sfilter = filter_to_afskmdm(filter); unsigned int pos = sfilter->curr_in_pos; int err = 0; if (gensio_str_in_auxdata(auxdata, "oob")) { /* Ignore oob data. */ if (rcount) *rcount = buflen; return 0; } afskmdm_lock(sfilter); if (sfilter->err) { err = sfilter->err; goto out_err; } if (buflen == 0) goto try_deliver; if (buflen != (gensiods) sfilter->in_chunksize * sfilter->in_framesize) return GE_INVAL; if (sfilter->filteredbuf) { if (sfilter->fir_h) { afskmdm_fir_filter((float *) buf, (float *) sfilter->filteredbuf, sfilter->in_chunksize, sfilter->in_nchans, sfilter->in_chan, sfilter->fir_h_n, sfilter->fir_h, sfilter->firhold); } else { afskmdm_iir_filter((float *) buf, (float *) sfilter->filteredbuf, sfilter->in_chunksize, sfilter->in_nchans, sfilter->in_chan, sfilter->coefa, sfilter->coefb, sfilter->iirhold); } buf = sfilter->filteredbuf; } if (sfilter->debug & GENSIO_AFSKMDM_DEBUG_BIT_HNDL) printf("Processing frame %lu %d %u\n", sfilter->framenr, sfilter->transmit_state, pos); if (!sfilter->full_duplex && sfilter->transmit_state > WAITING_TRANSMIT) { sfilter->curr_in_pos = sfilter->prevread_size; goto skip_processing; } while (pos < sfilter->in_chunksize + sfilter->in_corrsize - CORREDGE) { bool in_sync = true; afskmdm_check_for_data(sfilter, &pos, sfilter->prevread, buf, &in_sync); if (in_sync) { sfilter->nr_in_sync++; } else { if (sfilter->nr_in_sync > SYNC_RESET) sfilter->nr_in_sync = SYNC_RESET; else if (sfilter->nr_in_sync > 0) sfilter->nr_in_sync--; if (sfilter->nr_in_sync < IN_SYNC) sfilter->nr_out_sync++; } if (sfilter->nr_in_sync > IN_SYNC) { sfilter->nr_out_sync = 0; } else { sfilter->nr_out_sync++; if (!sfilter->full_duplex && sfilter->transmit_state == WAITING_TRANSMIT && sfilter->nr_out_sync >= sfilter->tx_delay) { afskmdm_check_start_xmit(sfilter); if (!sfilter->full_duplex && sfilter->transmit_state > WAITING_TRANSMIT) { sfilter->curr_in_pos = sfilter->prevread_size; goto skip_processing; } } } if (sfilter->debug & GENSIO_AFSKMDM_DEBUG_BIT_HNDL) printf("SYNC: %d %u\n", in_sync, sfilter->nr_in_sync); sfilter->in_corr_counter++; if (sfilter->in_corr_counter >= sfilter->in_corr_period) { pos += sfilter->in_corr_adj; sfilter->in_corr_counter = 0; } pos += sfilter->in_corrsize; } sfilter->curr_in_pos = pos - sfilter->in_chunksize; skip_processing: sfilter->framenr += sfilter->in_chunksize; memcpy(sfilter->prevread, buf + (sfilter->in_framesize * (sfilter->in_chunksize - sfilter->prevread_size)), (size_t) sfilter->prevread_size * sfilter->in_framesize); try_deliver: if (sfilter->deliver_data_len > 0) { gensiods count = 0; afskmdm_unlock(sfilter); err = handler(cb_data, &count, sfilter->deliver_data + sfilter->deliver_data_pos, sfilter->deliver_data_len - sfilter->deliver_data_pos, NULL); afskmdm_lock(sfilter); if (!err) { if (count + sfilter->deliver_data_pos >= sfilter->deliver_data_len) sfilter->deliver_data_len = 0; else sfilter->deliver_data_pos += count; } } out_err: afskmdm_unlock(sfilter); if (!err && rcount) *rcount = buflen; return err; } static int afskmdm_setup(struct gensio_filter *filter, struct gensio *io) { return 0; } static void afskmdm_cleanup(struct gensio_filter *filter) { struct afskmdm_filter *sfilter = filter_to_afskmdm(filter); unsigned int i, j; if (sfilter->key_io) gensio_close(sfilter->key_io, NULL, NULL); sfilter->key_io_state = KEY_CLOSED; sfilter->key_err = 0; sfilter->prev_xmit_level = -1; sfilter->prev_recv_level = 0; for (i = 0; i < sfilter->wmsg_sets; i++) { sfilter->wmsgsets[i].wmsgs[0].in_use = true; sfilter->wmsgsets[i].wmsgs[0].read_data_len = 0; sfilter->wmsgsets[i].wmsgs[0].num_uncertain = 0; sfilter->wmsgsets[i].wmsgs[0].certainty = 0.0; sfilter->wmsgsets[i].wmsgs[0].state = AFSKMDM_STATE_PREAMBLE_FIRST_0; for (j = 1; j < sfilter->max_wmsgs; j++) sfilter->wmsgsets[i].wmsgs[j].in_use = false; sfilter->wmsgsets[i].curr_wmsgs = 1; } sfilter->curr_in_pos = sfilter->prevread_size; sfilter->deliver_data_len = 0; sfilter->xmit_buf_len = 0; sfilter->xmit_buf_pos = 0; sfilter->nr_wrbufs = 0; sfilter->in_corr_counter = 0; sfilter->out_bit_counter = 0; } static void afskmdm_sfilter_free(struct afskmdm_filter *sfilter) { struct gensio_os_funcs *o = sfilter->o; unsigned int i, j; struct xmit_entry *e = sfilter->xmit_ent_list, *n; while (e) { n = e->next; o->free(o, e); e = n; } if (sfilter->mark_xmit) o->free(o, sfilter->mark_xmit); if (sfilter->space_xmit) o->free(o, sfilter->space_xmit); if (sfilter->key_io) gensio_free(sfilter->key_io); if (sfilter->key) o->free(o, sfilter->key); if (sfilter->keyon) o->free(o, sfilter->keyon); if (sfilter->keyoff) o->free(o, sfilter->keyoff); if (sfilter->lock) o->free_lock(sfilter->lock); if (sfilter->hzmark) o->free(o, sfilter->hzmark); if (sfilter->hzspace) o->free(o, sfilter->hzspace); if (sfilter->prevread) o->free(o, sfilter->prevread); if (sfilter->wmsgsets) { for (i = 0; i < sfilter->wmsg_sets; i++) { if (sfilter->wmsgsets[i].wmsgs) { for (j = 0; j < sfilter->max_wmsgs; j++) { if (sfilter->wmsgsets[i].wmsgs[j].read_data) o->free(o, sfilter->wmsgsets[i].wmsgs[j].read_data); } } o->free(o, sfilter->wmsgsets[i].wmsgs); } o->free(o, sfilter->wmsgsets); } if (sfilter->deliver_data) o->free(o, sfilter->deliver_data); if (sfilter->xmit_buf) o->free(o, sfilter->xmit_buf); for (i = 0; i < NR_WRITE_BUFS; i++) { if (sfilter->wrbufs[i].data) o->free(o, sfilter->wrbufs[i].data); } if (sfilter->filteredbuf) o->free(o, sfilter->filteredbuf); if (sfilter->fir_h) o->free(o, sfilter->fir_h); if (sfilter->firhold) o->free(o, sfilter->firhold); if (sfilter->filter) gensio_filter_free_data(sfilter->filter); o->free(o, sfilter); } static void afskmdm_free(struct gensio_filter *filter) { struct afskmdm_filter *sfilter = filter_to_afskmdm(filter); return afskmdm_sfilter_free(sfilter); } static int afskmdm_filter_control(struct gensio_filter *filter, bool get, int op, char *data, gensiods *datalen) { return GE_NOTSUP; } static int gensio_afskmdm_filter_func(struct gensio_filter *filter, int op, void *func, void *data, gensiods *count, void *buf, const void *cbuf, gensiods buflen, const char *const *auxdata) { switch (op) { case GENSIO_FILTER_FUNC_SET_CALLBACK: afskmdm_set_callbacks(filter, func, data); return 0; case GENSIO_FILTER_FUNC_TIMEOUT: return afskmdm_timeout_done(filter); case GENSIO_FILTER_FUNC_UL_READ_PENDING: return afskmdm_ul_read_pending(filter); case GENSIO_FILTER_FUNC_LL_WRITE_PENDING: return afskmdm_ll_write_pending(filter); case GENSIO_FILTER_FUNC_LL_READ_NEEDED: return afskmdm_ll_read_needed(filter); case GENSIO_FILTER_FUNC_UL_CAN_WRITE: return afskmdm_ul_can_write(filter, data); case GENSIO_FILTER_FUNC_CHECK_OPEN_DONE: return afskmdm_check_open_done(filter, data); case GENSIO_FILTER_FUNC_TRY_CONNECT: return afskmdm_try_connect(filter, data, buflen); case GENSIO_FILTER_FUNC_TRY_DISCONNECT: return afskmdm_try_disconnect(filter, data, buflen); case GENSIO_FILTER_FUNC_UL_WRITE_SG: return afskmdm_ul_write(filter, func, data, count, cbuf, buflen, buf); case GENSIO_FILTER_FUNC_LL_WRITE: return afskmdm_ll_write(filter, func, data, count, buf, buflen, NULL); case GENSIO_FILTER_FUNC_SETUP: return afskmdm_setup(filter, data); case GENSIO_FILTER_FUNC_CLEANUP: afskmdm_cleanup(filter); return 0; case GENSIO_FILTER_FUNC_FREE: afskmdm_free(filter); return 0; case GENSIO_FILTER_FUNC_CONTROL: return afskmdm_filter_control(filter, *((bool *) cbuf), buflen, data, count); default: return GE_NOTSUP; } } static unsigned int afskmdm_find_wave_pos(float *wave, unsigned int wave_size, float v, bool ascend, unsigned int size) { unsigned int i; for (i = 0; i < wave_size - size; i++) { if (wave[i] <= wave[i + 1] && wave[i + 1] >= wave[i + 2]) { /* At a peak. */ if (v > wave[i + 1]) break; } if (wave[i] >= wave[i + 1] && wave[i + 1] <= wave[i + 2]) { /* At a trough */ if (v < wave[i + 1]) break; } if (ascend) { if (v >= wave[i] && v <= wave[i + 1]) { float avg = (wave[i] + wave[i + 1]) / 2; if (v > avg) i++; break; } } else { if (v <= wave[i] && v >= wave[i + 1]) { float avg = (wave[i] + wave[i + 1]) / 2; if (v < avg) i++; break; } } } return i; } static int afskmdm_setup_xmit_ent(struct afskmdm_filter *sfilter, struct xmit_entry *e); static struct xmit_entry * afskmdm_create_xmit_ent(struct afskmdm_filter *sfilter, bool is_mark, unsigned int pos, float *data, unsigned int size) { struct xmit_entry *e; e = sfilter->o->zalloc(sfilter->o, sizeof(*e)); if (!e) return NULL; e->data = data; e->size = size; e->is_mark = is_mark; e->next = sfilter->xmit_ent_list; sfilter->xmit_ent_list = e; if (afskmdm_setup_xmit_ent(sfilter, e)) return NULL; return e; } static struct xmit_entry * afskmdm_find_xmit_ent(struct afskmdm_filter *sfilter, bool is_mark, float v, bool ascend, unsigned int size) { struct xmit_entry *e = sfilter->xmit_ent_list; float *wave; unsigned int wave_size, pos; if (is_mark) { wave = sfilter->mark_xmit; wave_size = sfilter->mark_xmit_len; } else { wave = sfilter->space_xmit; wave_size = sfilter->space_xmit_len; } pos = afskmdm_find_wave_pos(wave, wave_size, v, ascend, size); if (pos >= wave_size - size) return NULL; for(; e; e = e->next) { if (is_mark != e->is_mark) continue; if (size != e->size) continue; if (wave + pos == e->data) break; } if (!e) e = afskmdm_create_xmit_ent(sfilter, is_mark, pos, wave + pos, size); return e; } static int afskmdm_setup_xmit_ent(struct afskmdm_filter *sfilter, struct xmit_entry *e) { /* * We index one of the end of e->data, but the array it points to * has entries there, and it's the next value we want. */ float v = e->data[e->size]; bool ascend = v > e->data[e->size - 1]; struct xmit_entry *ne; unsigned int size = sfilter->out_bitsize; ne = afskmdm_find_xmit_ent(sfilter, false, v, ascend, size); if (!ne) return GE_NOMEM; e->next_send[0] = ne; ne = afskmdm_find_xmit_ent(sfilter, true, v, ascend, size); if (!ne) return GE_NOMEM; e->next_send[1] = ne; if (sfilter->out_bit_adj == 0) return 0; size += sfilter->out_bit_adj; ne = afskmdm_find_xmit_ent(sfilter, false, v, ascend, size); if (!ne) return GE_NOMEM; e->next_send[2] = ne; ne = afskmdm_find_xmit_ent(sfilter, true, v, ascend, size); if (!ne) return GE_NOMEM; e->next_send[3] = ne; return 0; } struct gensio_afskmdm_data { unsigned int in_nchans; unsigned int in_chan; unsigned int out_nchans; unsigned int out_chans; gensiods max_read_size; gensiods max_write_size; float mark_freq; float space_freq; unsigned int data_rate; unsigned int debug; bool check_ax25; bool do_crc; unsigned int in_framerate; unsigned int out_framerate; unsigned int in_chunksize; unsigned int out_chunksize; unsigned int max_wmsgs; unsigned int wmsg_sets; float min_certainty; int filt_type; #define NO_FILT 0 #define IIR_FILT 1 #define FIR_FILT 2 bool filt_type_set; unsigned int lpcutoff; unsigned int transition_freq; unsigned int tx_preamble_time; unsigned int tx_postamble_time; unsigned int tx_predelay_time; float volume; const char *key; int keytype; unsigned int keybit; const char *keyon; const char *keyoff; bool full_duplex; }; static int afskmdm_setup_transmit(struct afskmdm_filter *sfilter, struct gensio_afskmdm_data *data, float fbitsize) { struct gensio_os_funcs *o = sfilter->o; unsigned int i; struct xmit_entry *e; sfilter->mark_xmit_len = data->out_framerate / data->mark_freq * 2 + 2; if (sfilter->mark_xmit_len < 2 * sfilter->out_bitsize + 1) sfilter->mark_xmit_len = 2 * sfilter->out_bitsize + 1; sfilter->mark_xmit = o->zalloc(o, sizeof(float) * sfilter->mark_xmit_len); if (!sfilter->mark_xmit) return GE_NOMEM; for (i = 0; i < sfilter->mark_xmit_len; i++) { float v = 2 * M_PI * (data->mark_freq / data->data_rate) * ((float) i); sfilter->mark_xmit[i] = sin(v / fbitsize) * data->volume; } sfilter->space_xmit_len = data->out_framerate / data->space_freq * 2 + 2; if (sfilter->space_xmit_len < 2 * sfilter->out_bitsize + 1) sfilter->space_xmit_len = 2 * sfilter->out_bitsize + 1; sfilter->space_xmit = o->zalloc(o, sizeof(float) * sfilter->space_xmit_len); if (!sfilter->space_xmit) return GE_NOMEM; for (i = 0; i < sfilter->space_xmit_len; i++) { float v = 2 * M_PI * (data->space_freq / data->data_rate) * ((float) i); sfilter->space_xmit[i] = sin(v / fbitsize) * data->volume; } /* Set up the first entry, just start with a space at zero phase. */ e = o->zalloc(o, sizeof(*e)); if (!e) return GE_NOMEM; e->data = sfilter->space_xmit; e->size = sfilter->out_bitsize; e->is_mark = false; e->next = NULL; sfilter->xmit_ent_list = e; sfilter->curr_xmit_ent = e; return afskmdm_setup_xmit_ent(sfilter, e); } static struct gensio_filter * gensio_afskmdm_filter_raw_alloc(struct gensio_pparm_info *p, struct gensio_os_funcs *o, struct gensio *child, struct gensio_afskmdm_data *data) { struct afskmdm_filter *sfilter; unsigned int i, j; float fcorrsize, fbitsize; sfilter = o->zalloc(o, sizeof(*sfilter)); if (!sfilter) return NULL; sfilter->o = o; sfilter->in_nchans = data->in_nchans; sfilter->out_nchans = data->out_nchans; sfilter->in_chan = data->in_chan; sfilter->out_chans = data->out_chans; sfilter->in_framesize = sizeof(float) * data->in_nchans; sfilter->out_framesize = sizeof(float) * data->out_nchans; sfilter->max_write_size = data->max_write_size; sfilter->max_read_size = data->max_read_size + 2; /* Extra 2 for the CRC. */ sfilter->debug = data->debug; sfilter->check_ax25 = data->check_ax25; sfilter->do_crc = data->do_crc; sfilter->prev_xmit_level = -1; sfilter->prev_recv_level = 0; sfilter->in_chunksize = data->in_chunksize; sfilter->out_chunksize = data->out_chunksize; sfilter->max_wmsgs = data->max_wmsgs; sfilter->wmsg_sets = data->wmsg_sets; sfilter->min_certainty = data->min_certainty; sfilter->tx_preamble_time = GENSIO_MSECS_TO_NSECS(data->tx_preamble_time); sfilter->tx_postamble_time = GENSIO_MSECS_TO_NSECS(data->tx_postamble_time); sfilter->tx_predelay_time = GENSIO_MSECS_TO_NSECS(data->tx_predelay_time); sfilter->full_duplex = data->full_duplex; if (data->key) { sfilter->key = gensio_strdup(o, data->key); if (!sfilter->key) goto out_nomem; } sfilter->keytype = data->keytype; if (data->keyon) { sfilter->keyon = gensio_strdup(o, data->keyon); if (!sfilter->keyon) goto out_nomem; } if (data->keyoff) { sfilter->keyoff = gensio_strdup(o, data->keyoff); if (!sfilter->keyoff) goto out_nomem; } /* * Calculate the size of the correlation we will be doing. We * round the size to the nearest integer. We create the * correlation tables with the actual floating point value, and we * use that for adjust calculation, so get that here, too. */ sfilter->in_corrsize = ((data->in_framerate + data->data_rate / 2) / data->data_rate); if (sfilter->in_corrsize < 2 * CORREDGE) { gensio_pparm_log(p, "afskmdm: " "Correlation size is %u, but must be at least %u", sfilter->in_corrsize, 2 * CORREDGE); goto out_nomem; } sfilter->in_corr_time = (GENSIO_SECS_TO_NSECS(sfilter->in_corrsize) / data->in_framerate); fcorrsize = (float) data->in_framerate / data->data_rate; if (data->in_framerate % data->data_rate != 0) { /* * Calculate how often to adjust for the frame rate not being * evenly divisible by the data rate. If we rounded corrsize * up, then it needs to be adjusted down periodically, * otherwise we adjust up. * * Then take 1 divided by the distance from the ideal value, * and that should give how often we need to adjust. This may * not be really exact, but for all practical values it works * out well, and the auto-adjusting should keep us in sync as * long as this is close. */ float err = fcorrsize - truncf(fcorrsize); if (sfilter->in_corrsize > data->in_framerate / data->data_rate) { /* We rounded up. */ err = 1. - err; sfilter->in_corr_adj = -1; } else { sfilter->in_corr_adj = 1; } sfilter->in_corr_period = (unsigned int) ((1. / err) + 0.5); } sfilter->out_bitsize = ((data->out_framerate + data->data_rate / 2) / data->data_rate); sfilter->out_bit_time = (GENSIO_SECS_TO_NSECS(sfilter->out_bitsize) / data->out_framerate); fbitsize = (float) data->out_framerate / data->data_rate; sfilter->max_out_bitsize = sfilter->out_bitsize; if (data->out_framerate % data->data_rate != 0) { /* * Calculate how often to adjust for the frame rate not being * evenly divisible by the data rate. If we rounded corrsize * up, then it needs to be adjusted down periodically, * otherwise we adjust up. * * Then take 1 divided by the distance from the ideal value, * and that should give how often we need to adjust. This may * not be really exact, but for all practical values it works * out well, and the auto-adjusting should keep us in sync as * long as this is close. */ float err = fbitsize - truncf(fbitsize); if (sfilter->out_bitsize > data->out_framerate / data->data_rate) { /* We rounded up. */ err = 1. - err; sfilter->out_bit_adj = -1; } else { sfilter->out_bit_adj = 1; sfilter->max_out_bitsize++; } sfilter->out_bit_period = (unsigned int) ((1. / err) + 0.5); } /* * NOTE - this is in received corr periods, because it's measured * in the receive portion. */ sfilter->tx_delay = sfilter->tx_predelay_time / sfilter->in_corr_time; sfilter->lock = o->alloc_lock(o); if (!sfilter->lock) goto out_nomem; sfilter->hzmark = o->zalloc(o, sizeof(float) * 4 * sfilter->in_corrsize); if (!sfilter->hzmark) goto out_nomem; for (i = 0; i < 2 * sfilter->in_corrsize; i++) { float v = 2 * M_PI * (data->mark_freq / data->data_rate) * ((float) i); sfilter->hzmark[i] = sin(v / fcorrsize); sfilter->hzmark[i + 2 * sfilter->in_corrsize] = cos(v / fcorrsize); } sfilter->hzspace = o->zalloc(o, sizeof(float) * 4 * sfilter->in_corrsize); if (!sfilter->hzspace) goto out_nomem; for (i = 0; i < 2 * sfilter->in_corrsize; i++) { float v = 2 * M_PI * (data->space_freq / data->data_rate) * ((float) i); sfilter->hzspace[i] = sin(v / fcorrsize); sfilter->hzspace[i + 2 * sfilter->in_corrsize] = cos(v / fcorrsize); } if (data->lpcutoff && data->filt_type != NO_FILT) { if (data->filt_type == IIR_FILT) { afskmdm_calc_iir_coefs(data->in_framerate, data->lpcutoff, sfilter->coefa, sfilter->coefb); } else { sfilter->fir_h = afskmdm_calc_fir_coefs(o, data->in_framerate, data->lpcutoff, data->transition_freq, &sfilter->fir_h_n); if (!sfilter->fir_h) goto out_nomem; sfilter->firhold = o->zalloc(o, 2 * sfilter->fir_h_n * sizeof(float)); if (!sfilter->firhold) goto out_nomem; } sfilter->filteredbuf = o->zalloc(o, (gensiods) sfilter->in_framesize * sfilter->in_chunksize); if (!sfilter->filteredbuf) goto out_nomem; } sfilter->prevread_size = sfilter->in_corrsize * 2 + CORREDGE; sfilter->prevread = o->zalloc(o, (gensiods) sfilter->in_framesize * sfilter->prevread_size); if (!sfilter->prevread) goto out_nomem; sfilter->curr_in_pos = sfilter->prevread_size; sfilter->wmsgsets = o->zalloc(o, (sizeof(struct wmsgset) * sfilter->wmsg_sets)); for (i = 0; i < sfilter->wmsg_sets; i++) { sfilter->wmsgsets[i].wmsgs = o->zalloc(o, sizeof(struct wmsg) * sfilter->max_wmsgs); if (!sfilter->wmsgsets[i].wmsgs) goto out_nomem; for (j = 0; j < sfilter->max_wmsgs; j++) { sfilter->wmsgsets[i].wmsgs[j].read_data = o->zalloc(o, sfilter->max_read_size); if (!sfilter->wmsgsets[i].wmsgs[j].read_data) goto out_nomem; } sfilter->wmsgsets[i].wmsgs[0].in_use = true; sfilter->wmsgsets[i].wmsgs[0].state = AFSKMDM_STATE_PREAMBLE_FIRST_0; sfilter->wmsgsets[i].curr_wmsgs = 1; } sfilter->deliver_data = o->zalloc(o, sfilter->max_read_size); if (!sfilter->deliver_data) goto out_nomem; for (i = 0; i < NR_WRITE_BUFS; i++) { gensiods wrsz = sfilter->max_write_size; if (sfilter->do_crc) /* Add 2 to allow for the CRC to be added. */ wrsz += 2; sfilter->wrbufs[i].data = o->zalloc(o, wrsz); if (!sfilter->wrbufs[i].data) goto out_nomem; } sfilter->max_xmit_buf = sfilter->out_chunksize; sfilter->xmit_buf = o->zalloc(o, (gensiods) sfilter->out_chunksize * sfilter->out_framesize); if (!sfilter->xmit_buf) goto out_nomem; sfilter->filter = gensio_filter_alloc_data(o, gensio_afskmdm_filter_func, sfilter); if (!sfilter->filter) goto out_nomem; sfilter->nsec_per_frame = (((float) 1) / (float) data->out_framerate * (float) GENSIO_NSECS_IN_SEC); if (afskmdm_setup_transmit(sfilter, data, fbitsize)) goto out_nomem; sfilter->p = *p; if (sfilter->keytype == KEY_CM108) { char name[100]; gensiods len = sizeof(name); int err; strcpy(name, "out"); err = gensio_control(child, 0, true, GENSIO_CONTROL_LADDR, name, &len); if (err) { gensio_pparm_log(p, "Unable to get the output sound card name for" " fetching the cm108 parameter: %s.", gensio_err_to_str(err)); goto out_nomem; } if (sfilter->key) o->free(o, sfilter->key); sfilter->keytype = KEY_RW; sfilter->key = gensio_alloc_sprintf(o, "cm108gpio(bit=%u),%s", data->keybit, name); if (!sfilter->key) goto out_nomem; } if (sfilter->key) { int err = str_to_gensio(sfilter->key, o, key_cb, sfilter, &sfilter->key_io); if (err) { gensio_pparm_log(p, "Could not allocate key gensio '%s': %s", sfilter->key, gensio_err_to_str(err)); goto out_nomem; } switch (sfilter->keytype) { case KEY_RTS: case KEY_RTSINV: case KEY_DTR: case KEY_DTRINV: if (!gensio_is_serial(sfilter->key_io)) { gensio_pparm_log(p, "A serial keytype was given, '%s'," " but it is not a serial gensio", sfilter->key); goto out_nomem; } break; default: break; } } return sfilter->filter; out_nomem: afskmdm_sfilter_free(sfilter); return NULL; } static int afskmdm_child_getuint(struct gensio *child, int option, unsigned int *val) { int err; char cdata[30]; gensiods cdata_len; cdata_len = sizeof(cdata); err = gensio_control(child, GENSIO_CONTROL_DEPTH_FIRST, true, option, cdata, &cdata_len); if (err) return err; *val = strtoul(cdata, NULL, 0); return 0; } static struct gensio_enum_val filttype_enums[] = { { .name = "none", .val = NO_FILT }, { .name = "iir", .val = IIR_FILT }, { .name = "fir", .val = FIR_FILT }, { } }; static struct gensio_enum_val keytype_enums[] = { { .name = "rw", .val = KEY_RW }, { .name = "rts", .val = KEY_RTS }, { .name = "rtsinv", .val = KEY_RTSINV }, { .name = "dtr", .val = KEY_DTR }, { .name = "dtrinv", .val = KEY_DTRINV }, { .name = "cm108", .val = KEY_CM108 }, { } }; static int gensio_afskmdm_filter_alloc(struct gensio_pparm_info *p, struct gensio_os_funcs *o, struct gensio *child, const char * const args[], struct gensio_base_parms *parms, struct gensio_filter **rfilter) { struct gensio_filter *filter; struct gensio_afskmdm_data data = { .in_nchans = 0, .in_chan = 0, .out_nchans = 0, .out_chans = 1, .max_read_size = 256, .max_write_size = 256, .mark_freq = 1200., .space_freq = 2200., .data_rate = 1200, .in_framerate = 0, .out_framerate = 0, .in_chunksize = 0, .out_chunksize = 0, .max_wmsgs = 32, .wmsg_sets = 3, .min_certainty = 3.5, .filt_type = IIR_FILT, .filt_type_set = false, .lpcutoff = 2500, .transition_freq = 500, .tx_preamble_time = 300, .tx_postamble_time = 100, .tx_predelay_time = 500, .volume = .75, .full_duplex = false, .keytype = KEY_RW, .keybit = 3, .keyon = "T 1\n", .keyoff = "T 0\n", .do_crc = true }; unsigned int i; int err; char cdata[30]; gensiods cdata_len; unsigned int chan; unsigned int wmsg_extra = 1; err = afskmdm_child_getuint(child, GENSIO_CONTROL_IN_BUFSIZE, &data.in_chunksize); if (err) { gensio_pparm_slog(p, "Unable to get child input buffer size," " is it a sound device?"); return GE_INCONSISTENT; } err = afskmdm_child_getuint(child, GENSIO_CONTROL_OUT_BUFSIZE, &data.out_chunksize); if (err) { gensio_pparm_slog(p, "Unable to get child output buffer size," " is it a sound device?"); return GE_INCONSISTENT; } /* Don't care if these fail, we will check later. */ afskmdm_child_getuint(child, GENSIO_CONTROL_IN_RATE, &data.in_framerate); afskmdm_child_getuint(child, GENSIO_CONTROL_OUT_RATE, &data.out_framerate); afskmdm_child_getuint(child, GENSIO_CONTROL_IN_NR_CHANS, &data.in_nchans); afskmdm_child_getuint(child, GENSIO_CONTROL_OUT_NR_CHANS, &data.out_nchans); cdata_len = sizeof(cdata); err = gensio_control(child, GENSIO_CONTROL_DEPTH_FIRST, true, GENSIO_CONTROL_IN_FORMAT, cdata, &cdata_len); if (err) { gensio_pparm_slog(p, "Unable to get child input format," " is it a sound device?"); return GE_INCONSISTENT; } if (strcmp(cdata, "float") != 0) { gensio_pparm_slog(p, "Child input format is not float"); return GE_INCONSISTENT; } cdata_len = sizeof(cdata); err = gensio_control(child, GENSIO_CONTROL_DEPTH_FIRST, true, GENSIO_CONTROL_OUT_FORMAT, cdata, &cdata_len); if (err) { gensio_pparm_slog(p, "Unable to get child output format," " is it a sound device?"); return GE_INCONSISTENT; } if (strcmp(cdata, "float") != 0) { gensio_pparm_slog(p, "Child output format is not float"); return GE_INCONSISTENT; } for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(p, args[i], "readbuf", &data.max_read_size) > 0) continue; if (gensio_pparm_ds(p, args[i], "writebuf", &data.max_write_size) > 0) continue; if (gensio_pparm_uint(p, args[i], "nchans", &data.in_nchans) > 0) { data.out_nchans = data.in_nchans; continue; } if (gensio_pparm_uint(p, args[i], "in_nchans", &data.in_nchans) > 0) continue; if (gensio_pparm_uint(p, args[i], "out_nchans", &data.out_nchans) > 0) continue; if (gensio_pparm_uint(p, args[i], "chan", &data.in_chan) > 0) { data.out_chans = 1 << data.in_chan; continue; } if (gensio_pparm_uint(p, args[i], "in_chan", &data.in_chan) > 0) continue; if (gensio_pparm_uint(p, args[i], "out_chans", &data.out_chans) > 0) continue; if (gensio_pparm_uint(p, args[i], "out_chan", &chan) > 0) { data.out_chans = 1 << chan; continue; } if (gensio_pparm_uint(p, args[i], "samplerate", &data.in_framerate) > 0) { data.out_framerate = data.in_framerate; continue; } if (gensio_pparm_uint(p, args[i], "in_samplerate", &data.in_framerate) > 0) continue; if (gensio_pparm_uint(p, args[i], "out_samplerate", &data.in_framerate) > 0) continue; if (gensio_pparm_uint(p, args[i], "wmsgs", &data.max_wmsgs) > 0) continue; if (gensio_pparm_uint(p, args[i], "wmsg-extra", &wmsg_extra) > 0) continue; if (gensio_pparm_float(p, args[i], "min-certainty", &data.min_certainty) > 0) continue; if (gensio_pparm_enum(p, args[i], "filttype", filttype_enums, &data.filt_type) > 0) { data.filt_type_set = true; continue; } if (gensio_pparm_uint(p, args[i], "lpcutoff", &data.lpcutoff) > 0) continue; if (gensio_pparm_uint(p, args[i], "trfreq", &data.transition_freq) > 0) continue; if (gensio_pparm_uint(p, args[i], "tx-preamble", &data.tx_preamble_time) > 0) continue; if (gensio_pparm_uint(p, args[i], "tx-tail", &data.tx_postamble_time) > 0) continue; if (gensio_pparm_uint(p, args[i], "tx-predelay", &data.tx_predelay_time) > 0) continue; if (gensio_pparm_float(p, args[i], "volume", &data.volume) > 0) continue; if (gensio_pparm_value(p, args[i], "key", &data.key) > 0) continue; if (gensio_pparm_enum(p, args[i], "keytype", keytype_enums, &data.keytype) > 0) continue; if (gensio_pparm_uint(p, args[i], "keybit", &data.keybit) > 0) continue; if (gensio_pparm_value(p, args[i], "keyon", &data.keyon) > 0) continue; if (gensio_pparm_value(p, args[i], "keyoff", &data.keyoff) > 0) continue; if (gensio_pparm_bool(p, args[i], "full-duplex", &data.full_duplex) > 0) continue; if (gensio_pparm_uint(p, args[i], "debug", &data.debug) > 0) continue; if (gensio_pparm_bool(p, args[i], "checkax25", &data.check_ax25) > 0) continue; if (gensio_pparm_bool(p, args[i], "crc", &data.do_crc) > 0) continue; if (gensio_base_parm(parms, p, args[i]) > 0) continue; gensio_pparm_unknown_parm(p, args[i]); return GE_INVAL; } #define MY_STRINGIZE(s) #s #define CHECK_VAL(d, cmp, v) \ if (data.d cmp v) { \ gensio_pparm_log(p, #d " cannot be " #cmp " %d\n", v); \ return GE_INVAL; \ } CHECK_VAL(in_framerate, ==, 0); CHECK_VAL(out_framerate, ==, 0); CHECK_VAL(in_chunksize, ==, 0); CHECK_VAL(out_chunksize, ==, 0); CHECK_VAL(in_nchans, ==, 0); CHECK_VAL(out_nchans, ==, 0); CHECK_VAL(in_chan, >=, data.in_nchans); CHECK_VAL(out_chans, >=, (1U << data.out_nchans)) CHECK_VAL(max_wmsgs, ==, 0); /* * For lower sample rates a FIR filter doesn't use as much CPU and * is much more effective. For higher sample rates, the IIR * filter uses a lot less CPU and works just as well. */ if (!data.filt_type_set) { if (data.in_framerate < 30000) data.filt_type = FIR_FILT; else data.filt_type = IIR_FILT; } data.wmsg_sets = wmsg_extra * 2 + 1; filter = gensio_afskmdm_filter_raw_alloc(p, o, child, &data); if (!filter) return GE_NOMEM; *rfilter = filter; return 0; } static int afskmdm_gensio_alloc(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **net) { int err; struct gensio_filter *filter; struct gensio_ll *ll; struct gensio *io; struct gensio_base_parms *parms = NULL; GENSIO_DECLARE_PPGENSIO(p, o, cb, "afskmdm", user_data); err = gensio_base_parms_alloc(o, true, "afskmdm", &parms); if (err) goto out_err; err = gensio_afskmdm_filter_alloc(&p, o, child, args, parms, &filter); if (err) goto out_err; ll = gensio_gensio_ll_alloc(o, child); if (!ll) { gensio_filter_free(filter); goto out_nomem; } gensio_ref(child); /* So gensio_ll_free doesn't free the child if fail */ io = base_gensio_alloc(o, ll, filter, child, "afskmdm", cb, user_data); if (!io) { gensio_ll_free(ll); gensio_filter_free(filter); goto out_nomem; } err = gensio_base_parms_set(io, &parms); if (err) { gensio_free(io); goto out_err; } gensio_set_is_packet(io, true); gensio_free(child); /* Lose the ref we acquired. */ *net = io; return 0; out_nomem: err = GE_NOMEM; out_err: if (parms) gensio_base_parms_free(&parms); return err; } static int str_to_afskmdm_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct gensio *io2; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio(str, o, cb, user_data, &io2); if (err) return err; err = afskmdm_gensio_alloc(io2, args, o, cb, user_data, new_gensio); if (err) gensio_free(io2); return err; } int gensio_init_afskmdm(struct gensio_os_funcs *o) { int rv; rv = register_filter_gensio(o, "afskmdm", str_to_afskmdm_gensio, afskmdm_gensio_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/ll_gensio.c0000664000175000017500000001114414747451760011366 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include struct gensio_ll_child { struct gensio_ll *ll; struct gensio_os_funcs *o; gensio_ll_cb cb; void *cb_data; struct gensio *child; gensio_ll_open_done open_done; void *open_data; gensio_ll_close_done close_done; void *close_data; }; #define ll_to_child(v) ((struct gensio_ll_child *) gensio_ll_get_user_data(v)) static void child_set_callbacks(struct gensio_ll *ll, gensio_ll_cb cb, void *cb_data) { struct gensio_ll_child *cdata = ll_to_child(ll); cdata->cb = cb; cdata->cb_data = cb_data; } static int child_write(struct gensio_ll *ll, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { struct gensio_ll_child *cdata = ll_to_child(ll); return gensio_write_sg(cdata->child, rcount, sg, sglen, auxdata); } static void child_open_handler(struct gensio *io, int err, void *open_data) { struct gensio_ll_child *cdata = open_data; cdata->open_done(cdata->cb_data, err, cdata->open_data); } static int child_open(struct gensio_ll *ll, gensio_ll_open_done done, void *open_data) { struct gensio_ll_child *cdata = ll_to_child(ll); int rv; cdata->open_done = done; cdata->open_data = open_data; rv = gensio_open(cdata->child, child_open_handler, cdata); if (rv == 0) rv = GE_INPROGRESS; /* gensios always call the open handler. */ return rv; } static void child_close_handler(struct gensio *io, void *close_data) { struct gensio_ll_child *cdata = close_data; cdata->close_done(cdata->cb_data, cdata->close_data); } static int child_close(struct gensio_ll *ll, gensio_ll_close_done done, void *close_data) { struct gensio_ll_child *cdata = ll_to_child(ll); cdata->close_done = done; cdata->close_data = close_data; return gensio_close(cdata->child, child_close_handler, cdata); } static void child_set_read_callback_enable(struct gensio_ll *ll, bool enabled) { struct gensio_ll_child *cdata = ll_to_child(ll); gensio_set_read_callback_enable(cdata->child, enabled); } static void child_set_write_callback_enable(struct gensio_ll *ll, bool enabled) { struct gensio_ll_child *cdata = ll_to_child(ll); gensio_set_write_callback_enable(cdata->child, enabled); } static void child_free(struct gensio_ll *ll) { struct gensio_ll_child *cdata = ll_to_child(ll); gensio_free(cdata->child); gensio_ll_free_data(cdata->ll); cdata->o->free(cdata->o, cdata); } static int gensio_ll_child_func(struct gensio_ll *ll, int op, gensiods *count, void *buf, const void *cbuf, gensiods buflen, const char *const *auxdata) { switch (op) { case GENSIO_LL_FUNC_SET_CALLBACK: child_set_callbacks(ll, (void *) cbuf, buf); return 0; case GENSIO_LL_FUNC_WRITE_SG: return child_write(ll, count, cbuf, buflen, buf); case GENSIO_LL_FUNC_OPEN: return child_open(ll, (void *) cbuf, buf); case GENSIO_LL_FUNC_CLOSE: return child_close(ll, (void *) cbuf, buf); case GENSIO_LL_FUNC_SET_READ_CALLBACK: child_set_read_callback_enable(ll, buflen); return 0; case GENSIO_LL_FUNC_SET_WRITE_CALLBACK: child_set_write_callback_enable(ll, buflen); return 0; case GENSIO_LL_FUNC_FREE: child_free(ll); return 0; default: return GE_NOTSUP; } } static int child_event(struct gensio *io, void *user_data, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) { struct gensio_ll_child *cdata = user_data; gensiods rv; switch (event) { case GENSIO_EVENT_READ: rv = cdata->cb(cdata->cb_data, GENSIO_LL_CB_READ, err, buf, buflen ? *buflen : 0, auxdata); if (buflen) *buflen = rv; return 0; case GENSIO_EVENT_WRITE_READY: cdata->cb(cdata->cb_data, GENSIO_LL_CB_WRITE_READY, 0, NULL, 0, NULL); return 0; default: return gensio_ll_do_event(cdata->ll, event, err, buf, buflen, auxdata); } } struct gensio_ll * gensio_gensio_ll_alloc(struct gensio_os_funcs *o, struct gensio *child) { struct gensio_ll_child *cdata; cdata = o->zalloc(o, sizeof(*cdata)); if (!cdata) return NULL; cdata->o = o; cdata->ll = gensio_ll_alloc_data(o, gensio_ll_child_func, cdata); if (!cdata->ll) { o->free(o, cdata); return NULL; } cdata->child = child; gensio_set_callback(child, child_event, cdata); return cdata->ll; } gensio-3.0.0/lib/gensio_stdio.c0000664000175000017500000011450314773077750012106 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* This code handles stdio stream I/O. */ #include "config.h" #include #include #include #include #include #include #include #include "utils.h" static int gensio_stdio_func(struct gensio *io, int func, gensiods *count, const void *cbuf, gensiods buflen, void *buf, const char *const *auxdata); struct stdiona_data; struct stdion_channel { struct stdiona_data *nadata; int ll_err; /* Set if an error occurs reading or writing. */ struct gensio_iod *in_iod; struct gensio_iod *out_iod; /* Are the above fds registered with set_fd_handlers()? */ bool in_handler_set; bool out_handler_set; struct gensio *io; gensiods max_read_size; unsigned char *read_data; gensiods data_pending_len; gensiods data_pos; struct stdiona_data *stdiona; bool read_enabled; bool xmit_enabled; bool in_read; bool deferred_read; bool in_write_ready; bool write_pending; bool deferred_write; bool in_open; gensio_done_err open_done; void *open_data; /* For the client only. */ bool in_close; /* A close is pending the running running. */ bool deferred_close; bool closed; gensio_done close_done; void *close_data; bool in_free; /* * Used to run read callbacks from the selector to avoid running * it directly from user calls. */ bool deferred_op_pending; struct gensio_runner *deferred_op_runner; }; struct stdiona_data { struct gensio_lock *lock; struct gensio_os_funcs *o; bool raw; bool stderr_to_stdout; bool noredir_stderr; unsigned int refcount; int argc; const char **argv; const char **env; char *start_dir; struct gensio_runner *connect_runner; bool in_connect_runner; struct gensio_runner *enable_done_runner; gensio_acc_done enable_done; void *enable_done_data; struct gensio_timer *waitpid_timer; /* For the accepter only. */ bool in_free; bool in_shutdown; bool enabled; bool in_startup; gensio_acc_done shutdown_done; void *shutdown_data; /* exit code from the sub-program, after close. */ int exit_code; bool exit_code_set; unsigned int waitpid_retries; /* * If not -1, this is the PID of the other process and we are * in client mode. */ intptr_t opid; struct stdion_channel io; /* stdin, stdout */ struct stdion_channel err; /* stderr */ /* If we are in a final close, this is the channel that did it. */ struct stdion_channel *closing_chan; struct gensio_accepter *acc; }; static void stdiona_lock(struct stdiona_data *nadata) { nadata->o->lock(nadata->lock); } static void stdiona_unlock(struct stdiona_data *nadata) { nadata->o->unlock(nadata->lock); } static void stdiona_finish_free(struct stdiona_data *nadata) { struct gensio_os_funcs *o = nadata->o; if (nadata->io.io) gensio_data_free(nadata->io.io); if (nadata->err.io) gensio_data_free(nadata->err.io); if (nadata->io.out_iod) o->release_iod(nadata->io.out_iod); if (nadata->io.in_iod) o->release_iod(nadata->io.in_iod); if (nadata->argv) gensio_argv_free(o, nadata->argv); if (nadata->env) gensio_argv_free(o, nadata->env); if (nadata->start_dir) o->free(o, nadata->start_dir); if (nadata->io.deferred_op_runner) o->free_runner(nadata->io.deferred_op_runner); if (nadata->err.deferred_op_runner) o->free_runner(nadata->err.deferred_op_runner); if (nadata->connect_runner) o->free_runner(nadata->connect_runner); if (nadata->enable_done_runner) o->free_runner(nadata->enable_done_runner); if (nadata->io.read_data) o->free(o, nadata->io.read_data); if (nadata->waitpid_timer) o->free_timer(nadata->waitpid_timer); if (nadata->err.read_data) o->free(o, nadata->err.read_data); if (nadata->lock) o->free_lock(nadata->lock); if (nadata->acc) gensio_acc_data_free(nadata->acc); o->free(o, nadata); } static void stdiona_ref(struct stdiona_data *nadata) { assert(nadata->refcount > 0); nadata->refcount++; } static void stdiona_deref(struct stdiona_data *nadata) { assert(nadata->refcount > 1); nadata->refcount--; } static void stdiona_deref_and_unlock(struct stdiona_data *nadata) { assert(nadata->refcount > 0); if (--nadata->refcount == 0) { stdiona_unlock(nadata); stdiona_finish_free(nadata); } else { stdiona_unlock(nadata); } } static int stdion_write(struct gensio *io, gensiods *count, const struct gensio_sg *sg, gensiods sglen) { struct stdion_channel *schan = gensio_get_gensio_data(io); struct stdiona_data *nadata = schan->nadata; int rv; stdiona_lock(nadata); if (schan->ll_err) { rv = schan->ll_err; } else { rv = nadata->o->write(schan->in_iod, sg, sglen, count); if (rv) schan->ll_err = rv; } stdiona_unlock(nadata); return rv; } /* Must be called with nadata->lock held */ static void stdion_finish_read(struct stdion_channel *schan, int err) { struct stdiona_data *nadata = schan->nadata; struct gensio_os_funcs *o = nadata->o; struct gensio *io = schan->io; gensiods count; if (err && !schan->ll_err && schan->out_iod) { schan->ll_err = err; o->set_read_handler(schan->out_iod, false); o->set_except_handler(schan->out_iod, false); } while ((schan->data_pending_len || schan->ll_err) && schan->read_enabled) { count = schan->data_pending_len; if (schan->ll_err && schan->data_pending_len == 0) { schan->read_enabled = false; stdiona_unlock(nadata); err = gensio_cb(io, GENSIO_EVENT_READ, schan->ll_err, NULL, NULL, NULL); stdiona_lock(nadata); if (err) { schan->ll_err = err; o->set_read_handler(schan->out_iod, false); o->set_except_handler(schan->out_iod, false); break; } } else { stdiona_unlock(nadata); err = gensio_cb(io, GENSIO_EVENT_READ, 0, schan->read_data + schan->data_pos, &count, NULL); stdiona_lock(nadata); if (!err) { if (count < schan->data_pending_len) { /* The user didn't consume all the data. */ schan->data_pending_len -= count; schan->data_pos += count; } else { schan->data_pending_len = 0; } } } if (err) { schan->ll_err = err; o->set_read_handler(schan->out_iod, false); o->set_except_handler(schan->out_iod, false); break; } } schan->in_read = false; if (schan->out_iod) { if (schan->closed) { o->set_read_handler(schan->out_iod, false); o->set_except_handler(schan->out_iod, false); } else if (schan->read_enabled) { o->set_read_handler(schan->out_iod, true); o->set_except_handler(schan->out_iod, true); } } } /* FIXME - This should probably be configurable. */ #define NUM_WAIT_RETRIES 1000 static void check_waitpid(struct stdion_channel *schan) { struct stdiona_data *nadata = schan->nadata; struct gensio_os_funcs *o = nadata->o; int rv; gensiods count = 0; gensio_time timeout = { 0, 10000000 }; if (nadata->closing_chan) schan = nadata->closing_chan; /* Wait for the output buffer to clear for half our allotted time. */ if (schan->out_iod) { o->bufcount(schan->out_iod, GENSIO_OUT_BUF, &count); if (count > 0 && nadata->waitpid_retries < NUM_WAIT_RETRIES / 2) goto try_again; } if (schan->in_iod) o->close(&schan->in_iod); if (schan->out_iod) o->close(&schan->out_iod); if (nadata->opid != -1 && !nadata->io.out_handler_set && !nadata->io.in_handler_set && !nadata->err.out_handler_set) { rv = o->wait_subprog(o, nadata->opid, &nadata->exit_code); if (rv == GE_INPROGRESS) { goto try_again; } else { if (rv) /* FIXME = no real way to report this. */ ; nadata->exit_code_set = true; nadata->opid = -1; } } close_anyway: if (schan->in_iod) o->close(&schan->in_iod); if (schan->out_iod) { if (count > 0) o->flush(schan->out_iod, GENSIO_OUT_BUF); o->close(&schan->out_iod); } if (schan->close_done) { gensio_done close_done = schan->close_done; void *close_data = schan->close_data; schan->in_close = false; schan->close_done = NULL; stdiona_unlock(nadata); close_done(schan->io, close_data); stdiona_lock(nadata); } if (schan->in_free && schan->io) { gensio_data_free(schan->io); schan->io = NULL; stdiona_deref(nadata); } return; try_again: /* The sub-process has not died or buffer is not clear, wait a bit and try again. */ if (nadata->waitpid_retries >= NUM_WAIT_RETRIES) goto close_anyway; nadata->waitpid_retries++; stdiona_ref(nadata); rv = o->start_timer(nadata->waitpid_timer, &timeout); assert(rv == 0); nadata->closing_chan = schan; } static void check_waitpid_timeout(struct gensio_timer *t, void *cb_data) { struct stdion_channel *schan = cb_data; struct stdiona_data *nadata = schan->nadata; stdiona_lock(nadata); check_waitpid(schan); stdiona_deref_and_unlock(nadata); } /* * Note that we do callbacks from this function, it must be called * from a handler or deferred op and not from a user call. */ static void stdion_start_close(struct stdion_channel *schan) { struct stdiona_data *nadata = schan->nadata; schan->read_enabled = false; schan->xmit_enabled = false; nadata->o->clear_fd_handlers(schan->out_iod); if (schan->in_iod) nadata->o->clear_fd_handlers(schan->in_iod); } static int stdion_do_read(struct stdiona_data *nadata, struct stdion_channel *schan) { int rv; gensiods count; rv = nadata->o->read(schan->out_iod, schan->read_data, schan->max_read_size, &count); if (!rv) { schan->data_pending_len = count; schan->data_pos = 0; } return rv; } static void stdion_deferred_op(struct gensio_runner *runner, void *cbdata) { struct stdion_channel *schan = cbdata; struct stdiona_data *nadata = schan->nadata; struct gensio_os_funcs *o = nadata->o; struct gensio *io = schan->io; stdiona_lock(nadata); restart: if (schan->in_open) { if (schan->open_done) { stdiona_unlock(nadata); schan->open_done(io, 0, schan->open_data); stdiona_lock(nadata); } schan->in_open = false; o->set_read_handler(schan->out_iod, schan->read_enabled); o->set_except_handler(schan->out_iod, schan->read_enabled); if (schan->in_iod) { o->set_write_handler(schan->in_iod, schan->xmit_enabled); o->set_except_handler(schan->in_iod, schan->xmit_enabled); } } if (schan->deferred_read) { schan->deferred_read = false; while (schan->read_enabled && schan->io && (schan->ll_err || schan->data_pending_len)) stdion_finish_read(schan, 0); } if (schan->deferred_close) { schan->deferred_close = false; stdion_start_close(schan); } if (schan->deferred_read || schan->in_open || schan->deferred_write) goto restart; schan->deferred_op_pending = false; stdiona_deref_and_unlock(nadata); } static void stdion_start_deferred_op(struct stdion_channel *schan) { if (!schan->deferred_op_pending) { /* Call the read from the selector to avoid lock nesting issues. */ schan->deferred_op_pending = true; schan->nadata->o->run(schan->deferred_op_runner); stdiona_ref(schan->nadata); } } static void i_stdion_fd_cleared(struct gensio_iod *iod, struct stdiona_data *nadata, struct stdion_channel *schan) { struct gensio_os_funcs *o = nadata->o; if (iod == schan->in_iod) { schan->in_handler_set = false; o->close(&schan->in_iod); } else if (iod == schan->out_iod) { schan->out_handler_set = false; o->close(&schan->out_iod); } else { assert(false); } if (schan->in_close && !schan->in_handler_set && !schan->out_handler_set) { if (schan == &nadata->io && !nadata->err.out_handler_set && nadata->err.out_iod) { /* The stderr channel is not open, so close the fd. */ o->close(&nadata->err.out_iod); } check_waitpid(schan); } } static void stdion_fd_cleared(struct gensio_iod *iod, void *cbdata) { struct stdion_channel *schan = cbdata; struct stdiona_data *nadata = schan->nadata; stdiona_lock(nadata); i_stdion_fd_cleared(iod, nadata, schan); stdiona_deref_and_unlock(nadata); } static void stdion_set_read_callback_enable(struct gensio *io, bool enabled) { struct stdion_channel *schan = gensio_get_gensio_data(io); struct stdiona_data *nadata = schan->nadata; stdiona_lock(nadata); if (schan->read_enabled == enabled) goto out_unlock; schan->read_enabled = enabled; if ((!schan->in_close && schan->closed) || !schan->io) goto out_unlock; if (schan->in_read || schan->in_open || (schan->data_pending_len && !enabled)) { /* Nothing to do, let the read handling wake things up. */ } else if (schan->data_pending_len) { schan->deferred_read = true; schan->in_read = true; stdion_start_deferred_op(schan); } else if (schan->out_iod) { /* Could be in the middle of close. */ nadata->o->set_read_handler(schan->out_iod, enabled); nadata->o->set_except_handler(schan->out_iod, enabled); } out_unlock: stdiona_unlock(nadata); } static void stdion_set_write_callback_enable(struct gensio *io, bool enabled) { struct stdion_channel *schan = gensio_get_gensio_data(io); struct stdiona_data *nadata = schan->nadata; stdiona_lock(nadata); if (schan->xmit_enabled == enabled) goto out_unlock; schan->xmit_enabled = enabled; if ((!schan->in_close && schan->closed) || !schan->in_iod) goto out_unlock; if (schan->in_open) goto out_unlock; if (schan->in_iod) { /* Could be in the middle of close. */ nadata->o->set_write_handler(schan->in_iod, enabled); nadata->o->set_except_handler(schan->in_iod, enabled); } out_unlock: stdiona_unlock(nadata); } static void stdion_read_ready(struct gensio_iod *iod, void *cbdata) { struct stdion_channel *schan = cbdata; struct stdiona_data *nadata = schan->nadata; stdiona_lock(nadata); nadata->o->set_read_handler(schan->out_iod, false); nadata->o->set_except_handler(schan->out_iod, false); if (!schan->read_enabled || schan->in_read || schan->data_pending_len) { stdiona_unlock(nadata); return; } if (!schan->ll_err) { schan->in_read = true; stdion_finish_read(schan, stdion_do_read(nadata, schan)); } stdiona_unlock(nadata); } static void stdion_read_except_ready(struct gensio_iod *iod, void *cbdata) { stdion_read_ready(iod, cbdata); } static void stdion_write_ready(struct gensio_iod *iod, void *cbdata) { struct stdion_channel *schan = cbdata; struct stdiona_data *nadata = schan->nadata; int err; stdiona_lock(nadata); if (schan->in_write_ready) { schan->write_pending = true; goto out; } schan->in_write_ready = true; retry: stdiona_unlock(nadata); err = gensio_cb(schan->io, GENSIO_EVENT_WRITE_READY, 0, NULL, NULL, NULL); stdiona_lock(nadata); if (err) { schan->ll_err = err; if (schan->out_iod) { nadata->o->set_read_handler(schan->out_iod, false); nadata->o->set_except_handler(schan->out_iod, false); } } else if (schan->write_pending) { schan->write_pending = false; if (schan->xmit_enabled) goto retry; } schan->in_write_ready = false; out: stdiona_unlock(nadata); } static void stdion_write_except_ready(struct gensio_iod *iod, void *cbdata) { stdion_write_ready(iod, cbdata); } static int setup_child_proc(struct stdiona_data *nadata) { struct gensio_os_funcs *o = nadata->o; int rv; rv = o->exec_subprog(o, nadata->argv, nadata->env, nadata->start_dir, nadata->stderr_to_stdout, &nadata->opid, &nadata->io.in_iod, &nadata->io.out_iod, nadata->noredir_stderr ? NULL : &nadata->err.out_iod); return rv; } static int setup_io_self(struct stdiona_data *nadata) { struct gensio_os_funcs *o = nadata->o; int rv; if (nadata->raw) { rv = o->makeraw(nadata->io.in_iod); if (rv) return rv; rv = o->makeraw(nadata->io.out_iod); if (rv) return rv; } /* * If these are not regular files, save off the old flags and turn * on non-blocking. */ rv = o->set_non_blocking(nadata->io.in_iod); if (rv) return rv; rv = o->set_non_blocking(nadata->io.out_iod); if (rv) return rv; return 0; } static void cleanup_io_self(struct stdiona_data *nadata) { if (nadata->io.out_handler_set) nadata->o->clear_fd_handlers_norpt(nadata->io.out_iod); nadata->io.out_handler_set = false; if (nadata->io.in_handler_set) nadata->o->clear_fd_handlers_norpt(nadata->io.in_iod); nadata->io.in_handler_set = false; } static int stdion_open(struct gensio *io, gensio_done_err open_done, void *open_data) { struct stdion_channel *schan = gensio_get_gensio_data(io); struct stdiona_data *nadata = schan->nadata; struct gensio_os_funcs *o = nadata->o; int err; stdiona_lock(nadata); if (!schan->closed || schan->in_close) { err = GE_NOTREADY; goto out_unlock; } if (schan == &nadata->io) { if (nadata->argv && schan == &nadata->io) err = setup_child_proc(nadata); else err = setup_io_self(nadata); if (err) goto out_err; } err = o->set_fd_handlers(schan->out_iod, schan, stdion_read_ready, NULL, stdion_read_except_ready, stdion_fd_cleared); if (err) goto out_err; schan->out_handler_set = true; stdiona_ref(nadata); if (schan->in_iod) { /* * On the write side we send an exception to the write ready * operation. */ err = o->set_fd_handlers(schan->in_iod, schan, NULL, stdion_write_ready, stdion_write_except_ready, stdion_fd_cleared); if (err) goto out_err_deref; schan->in_handler_set = true; stdiona_ref(nadata); } schan->ll_err = 0; schan->closed = false; schan->in_open = true; schan->open_done = open_done; schan->open_data = open_data; stdion_start_deferred_op(schan); stdiona_unlock(nadata); return 0; out_err_deref: stdiona_deref(nadata); out_err: cleanup_io_self(nadata); if (nadata->io.in_iod) o->close(&nadata->io.in_iod); if (nadata->err.out_iod) o->close(&nadata->err.out_iod); if (nadata->io.out_iod) o->close(&nadata->io.out_iod); out_unlock: stdiona_unlock(nadata); return err; } static int stdion_alloc_channel(struct gensio *io, const char * const args[], gensio_event cb, void *user_data, struct gensio **new_io) { struct stdion_channel *schan = gensio_get_gensio_data(io); struct stdiona_data *nadata = schan->nadata; struct gensio_os_funcs *o = nadata->o; int rv = 0; unsigned int i; gensiods max_read_size = nadata->io.max_read_size; GENSIO_DECLARE_PPGENSIO(p, o, cb, "stdio", user_data); if (!nadata->err.out_iod || io != nadata->io.io) return GE_INVAL; for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(&p, args[i], "readbuf", &max_read_size) > 0) continue; gensio_pparm_unknown_parm(&p, args[i]); return GE_INVAL; } stdiona_lock(nadata); if (nadata->err.io) { rv = GE_INUSE; goto out_err; } nadata->err.max_read_size = max_read_size; nadata->err.read_data = o->zalloc(o, max_read_size); if (!nadata->err.read_data) { rv = GE_NOMEM; goto out_err; } nadata->err.data_pending_len = 0; nadata->err.data_pos = 0; nadata->err.read_enabled = false; nadata->err.xmit_enabled = false; nadata->err.io = gensio_data_alloc(o, cb, user_data, gensio_stdio_func, NULL, "stderr", &nadata->err); if (!nadata->err.io) { o->free(o, nadata->err.read_data); nadata->err.read_data = NULL; rv = GE_NOMEM; goto out_err; } stdiona_ref(nadata); *new_io = nadata->err.io; out_err: stdiona_unlock(nadata); return rv; } static void i_stdion_close(struct stdion_channel *schan, gensio_done close_done, void *close_data) { schan->closed = true; schan->in_close = true; schan->close_done = close_done; schan->close_data = close_data; /* * Always run this in the deferred handler, it simplifies issues with * handling regular file shutdown. */ schan->deferred_close = true; stdion_start_deferred_op(schan); } static int stdion_close(struct gensio *io, gensio_done close_done, void *close_data) { struct stdion_channel *schan = gensio_get_gensio_data(io); struct stdiona_data *nadata = schan->nadata; int err = 0; stdiona_lock(nadata); if (schan->closed || schan->in_close) err = GE_NOTREADY; else i_stdion_close(schan, close_done, close_data); stdiona_unlock(nadata); return err; } static void stdion_free(struct gensio *io) { struct stdion_channel *schan = gensio_get_gensio_data(io); struct stdiona_data *nadata = schan->nadata; stdiona_lock(nadata); schan->in_free = true; if (schan->in_close) { schan->close_done = NULL; stdiona_unlock(nadata); } else if (schan->closed) { stdiona_unlock(nadata); gensio_data_free(schan->io); schan->io = NULL; stdiona_lock(nadata); stdiona_deref_and_unlock(nadata); } else { i_stdion_close(schan, NULL, NULL); stdiona_unlock(nadata); } } static int stdion_disable(struct gensio *io) { struct stdion_channel *schan = gensio_get_gensio_data(io); struct stdiona_data *nadata = schan->nadata; struct gensio_os_funcs *o = nadata->o; if (!nadata->argv) return GE_NOTSUP; stdiona_lock(nadata); schan->closed = true; schan->in_close = false; schan->in_open = false; schan->close_done = NULL; if (nadata->io.out_handler_set) o->clear_fd_handlers_norpt(nadata->io.out_iod); if (nadata->io.out_iod) o->close(&nadata->io.out_iod); if (nadata->io.in_handler_set) o->clear_fd_handlers_norpt(nadata->io.in_iod); if (nadata->io.in_iod) o->close(&nadata->io.in_iod); if (nadata->err.out_handler_set) o->clear_fd_handlers_norpt(nadata->err.out_iod); if (nadata->err.out_iod) o->close(&nadata->err.out_iod); stdiona_deref_and_unlock(nadata); return 0; } static int stdion_control(struct gensio *io, bool get, unsigned int option, char *data, gensiods *datalen) { struct stdion_channel *schan = gensio_get_gensio_data(io); struct stdiona_data *nadata = schan->nadata; struct gensio_os_funcs *o = nadata->o; const char **env, **argv; int err, status, val; gensiods pos; switch (option) { case GENSIO_CONTROL_ENVIRONMENT: if (get) return GE_NOTSUP; if (data) { err = gensio_argv_copy(o, (const char **) data, NULL, &env); if (err) return err; } else { env = NULL; } if (nadata->env) gensio_argv_free(o, nadata->env); nadata->env = env; return 0; case GENSIO_CONTROL_ARGS: if (get) return GE_NOTSUP; if (data) { err = gensio_argv_copy(o, (const char **) data, NULL, &argv); if (err) return err; } else { argv = NULL; } if (nadata->argv) gensio_argv_free(o, nadata->argv); nadata->argv = argv; return 0; case GENSIO_CONTROL_EXIT_CODE: if (!get) return GE_NOTSUP; err = 0; stdiona_lock(nadata); if (!nadata->exit_code_set) err = GE_NOTREADY; stdiona_unlock(nadata); if (!err) *datalen = snprintf(data, *datalen, "%d", nadata->exit_code); return err; case GENSIO_CONTROL_WAIT_TASK: if (!get) return GE_NOTSUP; stdiona_lock(nadata); if (nadata->opid == -1) err = GE_NOTREADY; else err = o->wait_subprog(o, nadata->opid, &status); if (!err) { nadata->opid = -1; nadata->exit_code = status; } stdiona_unlock(nadata); if (!err) *datalen = snprintf(data, *datalen, "%d", status); return err; case GENSIO_CONTROL_KILL_TASK: if (get) return GE_NOTSUP; stdiona_lock(nadata); if (nadata->opid == -1) { err = GE_NOTREADY; } else { val = strtoul(data, NULL, 0); err = o->kill_subprog(o, nadata->opid, val); } stdiona_unlock(nadata); return err; case GENSIO_CONTROL_CLOSE_OUTPUT: if (get) return GE_NOTSUP; err = 0; stdiona_lock(nadata); if (!schan->in_iod) err = GE_NOTREADY; else o->clear_fd_handlers(schan->in_iod); stdiona_unlock(nadata); return err; case GENSIO_CONTROL_RADDR: if (!get) return GE_NOTSUP; pos = 0; if (io == nadata->io.io) gensio_pos_snprintf(data, *datalen, &pos, "stdio"); else gensio_pos_snprintf(data, *datalen, &pos, "stderr"); if (nadata->argv) { gensio_pos_snprintf(data, *datalen, &pos, ","); gensio_argv_snprintf(data, *datalen, &pos, nadata->argv); } else { gensio_pos_snprintf(data, *datalen, &pos, "(self)"); } *datalen = pos; return 0; case GENSIO_CONTROL_REMOTE_ID: if (!get) return GE_NOTSUP; *datalen = snprintf(data, *datalen, "%llu", (unsigned long long) nadata->opid); return 0; case GENSIO_CONTROL_IOD: if (!get) return GE_NOTSUP; if (*datalen != sizeof(void *)) return GE_INVAL; val = strtoul(data, NULL, 0); if (val == 0) memcpy(data, &schan->out_iod, sizeof(void *)); else if (val == 1) memcpy(data, &schan->in_iod, sizeof(void *)); else return GE_INVAL; return 0; case GENSIO_CONTROL_START_DIRECTORY: if (get) { *datalen = snprintf(data, *datalen, "%s", nadata->start_dir); } else { char *dir; dir = gensio_strdup(o, (char *) data); if (!dir) return GE_NOMEM; if (nadata->start_dir) o->free(o, nadata->start_dir); nadata->start_dir = dir; } return 0; } return GE_NOTSUP; } static int gensio_stdio_func(struct gensio *io, int func, gensiods *count, const void *cbuf, gensiods buflen, void *buf, const char *const *auxdata) { switch (func) { case GENSIO_FUNC_WRITE_SG: return stdion_write(io, count, cbuf, buflen); case GENSIO_FUNC_OPEN: return stdion_open(io, (void *) cbuf, buf); case GENSIO_FUNC_CLOSE: return stdion_close(io, (void *) cbuf, buf); case GENSIO_FUNC_FREE: stdion_free(io); return 0; case GENSIO_FUNC_SET_READ_CALLBACK: stdion_set_read_callback_enable(io, buflen); return 0; case GENSIO_FUNC_SET_WRITE_CALLBACK: stdion_set_write_callback_enable(io, buflen); return 0; case GENSIO_FUNC_ALLOC_CHANNEL: { struct gensio_func_alloc_channel_data *d = buf; return stdion_alloc_channel(io, d->args, d->cb, d->user_data, &d->new_io); } case GENSIO_FUNC_DISABLE: return stdion_disable(io); case GENSIO_FUNC_CONTROL: return stdion_control(io, *((bool *) cbuf), buflen, buf, count); default: return GE_NOTSUP; } } static int stdio_nadata_setup(struct gensio_os_funcs *o, gensiods max_read_size, bool raw, struct stdiona_data **new_nadata) { struct stdiona_data *nadata; nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) return GE_NOMEM; nadata->o = o; nadata->refcount = 1; nadata->io.closed = true; nadata->err.closed = true; nadata->io.nadata = nadata; nadata->err.nadata = nadata; nadata->opid = -1; nadata->waitpid_timer = o->alloc_timer(o, check_waitpid_timeout, &nadata->io); if (!nadata->waitpid_timer) goto out_nomem; nadata->raw = raw; nadata->io.max_read_size = max_read_size; nadata->io.read_data = o->zalloc(o, max_read_size); if (!nadata->io.read_data) goto out_nomem; nadata->io.deferred_op_runner = o->alloc_runner(o, stdion_deferred_op, &nadata->io); if (!nadata->io.deferred_op_runner) goto out_nomem; nadata->err.deferred_op_runner = o->alloc_runner(o, stdion_deferred_op, &nadata->err); if (!nadata->err.deferred_op_runner) goto out_nomem; nadata->lock = o->alloc_lock(o); if (!nadata->lock) goto out_nomem; *new_nadata = nadata; return 0; out_nomem: stdiona_finish_free(nadata); return GE_NOMEM; } static int setup_self(struct stdiona_data *nadata, bool console) { struct gensio_os_funcs *o = nadata->o; int err; enum gensio_iod_type type; if (console) type = GENSIO_IOD_CONSOLE; else type = GENSIO_IOD_STDIO; err = o->add_iod(o, type, 1, &nadata->io.in_iod); if (err) return err; err = o->add_iod(o, type, 0, &nadata->io.out_iod); if (err) return err; return 0; } static int stdio_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { const char * const *argv = gdata; int err; struct stdiona_data *nadata = NULL; int i; gensiods max_read_size = GENSIO_DEFAULT_BUF_SIZE; bool self = false; bool console = false; bool stderr_to_stdout = false; bool noredir_stderr = false; bool raw = false; const char *start_dir = NULL; GENSIO_DECLARE_PPGENSIO(p, o, cb, "stdio", user_data); for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(&p, args[i], "readbuf", &max_read_size) > 0) continue; if (gensio_pparm_bool(&p, args[i], "console", &console) > 0) continue; if (gensio_pparm_bool(&p, args[i], "self", &self) > 0) continue; if (gensio_pparm_bool(&p, args[i], "raw", &raw) > 0) continue; if (gensio_pparm_value(&p, args[i], "start-dir", &start_dir) > 0) continue; if (gensio_pparm_bool(&p, args[i], "stderr-to-stdout", &stderr_to_stdout) > 0) { /* We don't want to setup stderr here. */ noredir_stderr = true; continue; } if (gensio_pparm_bool(&p, args[i], "noredir-stderr", &noredir_stderr) > 0) continue; gensio_pparm_unknown_parm(&p, args[i]); return GE_INVAL; } if (raw && !(self || console)) { gensio_pparm_slog(&p, "If raw is set, self or console must be set"); return GE_INVAL; } err = stdio_nadata_setup(o, max_read_size, raw, &nadata); if (err) return err; nadata->stderr_to_stdout = stderr_to_stdout; nadata->noredir_stderr = noredir_stderr; if (start_dir) { nadata->start_dir = gensio_strdup(o, start_dir); if (!nadata->start_dir) { err = GE_NOMEM; goto out_err; } } if (self || console) { err = setup_self(nadata, console); if (err) goto out_err; } else { err = gensio_argv_copy(o, argv, NULL, &nadata->argv); if (err) goto out_err; } nadata->io.io = gensio_data_alloc(o, cb, user_data, gensio_stdio_func, NULL, "stdio", &nadata->io); if (!nadata->io.io) goto out_nomem; gensio_set_is_client(nadata->io.io, true); gensio_set_is_reliable(nadata->io.io, true); if (!nadata->noredir_stderr) gensio_set_is_mux(nadata->io.io, true); /* stderr is a mux channel. */ *new_gensio = nadata->io.io; return 0; out_nomem: err = GE_NOMEM; out_err: stdiona_finish_free(nadata); return err; } static int str_to_stdio_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; const char **argv; err = gensio_str_to_argv(o, str, NULL, &argv, NULL); if (!err) { err = stdio_gensio_alloc(argv, args, o, cb, user_data, new_gensio); gensio_argv_free(o, argv); } return err; } static void stdiona_do_connect(struct gensio_runner *runner, void *cbdata) { struct stdiona_data *nadata = cbdata; stdiona_lock(nadata); retry: if (nadata->in_startup) { nadata->in_startup = false; stdiona_unlock(nadata); gensio_acc_cb(nadata->acc, GENSIO_ACC_EVENT_NEW_CONNECTION, nadata->io.io); stdiona_lock(nadata); } if (nadata->in_shutdown) { nadata->in_shutdown = false; stdiona_unlock(nadata); if (nadata->shutdown_done) nadata->shutdown_done(nadata->acc, nadata->shutdown_data); stdiona_lock(nadata); } if (nadata->in_startup || nadata->in_shutdown) goto retry; nadata->in_connect_runner = false; stdiona_deref_and_unlock(nadata); /* unlocks */ } /* * fd cleared for a gensio from an acceptor only. */ static void stdiona_fd_cleared(struct gensio_iod *iod, void *cbdata) { struct stdion_channel *schan = cbdata; struct stdiona_data *nadata = schan->nadata; stdiona_lock(nadata); if (iod == schan->in_iod) schan->in_handler_set = false; else schan->out_handler_set = false; if (!schan->in_handler_set && !schan->out_handler_set && schan->in_close) { schan->in_close = false; if (schan->close_done) { gensio_done close_done = schan->close_done; void *close_data = schan->close_data; schan->close_done = NULL; stdiona_unlock(nadata); close_done(schan->io, close_data); stdiona_lock(nadata); } } /* Lose the refcount we got when we added the fd handler. */ stdiona_deref_and_unlock(nadata); /* unlocks */ } static int stdiona_startup(struct gensio_accepter *accepter) { struct stdiona_data *nadata = gensio_acc_get_gensio_data(accepter); struct gensio_os_funcs *o = nadata->o; int rv = 0; stdiona_lock(nadata); if (nadata->in_free || nadata->in_shutdown) { rv = GE_NOTREADY; goto out_unlock; } if (nadata->enabled) { rv = GE_INUSE; goto out_unlock; } rv = setup_io_self(nadata); if (rv) goto out_unlock; rv = o->set_fd_handlers(nadata->io.in_iod, &nadata->io, NULL, stdion_write_ready, NULL, stdiona_fd_cleared); if (rv) goto out_err; nadata->io.in_handler_set = true; stdiona_ref(nadata); rv = o->set_fd_handlers(nadata->io.out_iod, &nadata->io, stdion_read_ready, NULL, NULL, stdiona_fd_cleared); if (rv) goto out_err; nadata->io.out_handler_set = true; stdiona_ref(nadata); nadata->io.closed = false; nadata->in_startup = true; nadata->enabled = true; if (!nadata->in_connect_runner) { stdiona_ref(nadata); nadata->in_connect_runner = true; o->run(nadata->connect_runner); } stdiona_ref(nadata); /* One for the gensio. */ out_unlock: stdiona_unlock(nadata); return rv; out_err: cleanup_io_self(nadata); goto out_unlock; } static int stdiona_shutdown(struct gensio_accepter *accepter, gensio_acc_done shutdown_done, void *shutdown_data) { struct stdiona_data *nadata = gensio_acc_get_gensio_data(accepter); int rv = 0; stdiona_lock(nadata); if (nadata->in_free) { rv = GE_NOTREADY; } else if (nadata->in_shutdown || !nadata->enabled) { rv = GE_NOTREADY; } else { nadata->in_shutdown = true; nadata->enabled = false; nadata->shutdown_done = shutdown_done; nadata->shutdown_data = shutdown_data; if (!nadata->in_connect_runner) { stdiona_ref(nadata); nadata->in_connect_runner = true; nadata->o->run(nadata->connect_runner); } } stdiona_unlock(nadata); return rv; } static void enable_done_op(struct gensio_runner *runner, void *cb_data) { struct stdiona_data *nadata = cb_data; stdiona_lock(nadata); if (nadata->enable_done) { gensio_acc_done done = nadata->enable_done; void *done_data = nadata->enable_done_data; nadata->enable_done = NULL; stdiona_unlock(nadata); done(nadata->acc, done_data); stdiona_lock(nadata); } stdiona_deref_and_unlock(nadata); } static int stdiona_set_accept_callback_enable(struct gensio_accepter *accepter, bool enabled, gensio_acc_done done, void *done_data) { struct stdiona_data *nadata = gensio_acc_get_gensio_data(accepter); int rv = 0; /* FIXME - there's no real enable for this, maybe there should be? */ if (nadata->enable_done) { rv = GE_INUSE; } else { nadata->enable_done = done; nadata->enable_done_data = done_data; stdiona_ref(nadata); nadata->o->run(nadata->enable_done_runner); } return rv; } static void stdiona_free(struct gensio_accepter *accepter) { struct stdiona_data *nadata = gensio_acc_get_gensio_data(accepter); stdiona_lock(nadata); nadata->in_free = true; stdiona_deref_and_unlock(nadata); } static int gensio_acc_stdio_func(struct gensio_accepter *acc, int func, int val, const char *addr, void *done, void *data, const void *data2, void *ret) { switch (func) { case GENSIO_ACC_FUNC_STARTUP: return stdiona_startup(acc); case GENSIO_ACC_FUNC_SHUTDOWN: return stdiona_shutdown(acc, done, data); case GENSIO_ACC_FUNC_SET_ACCEPT_CALLBACK: return stdiona_set_accept_callback_enable(acc, val, done, data); case GENSIO_ACC_FUNC_FREE: stdiona_free(acc); return 0; case GENSIO_ACC_FUNC_STR_TO_GENSIO: default: return GE_NOTSUP; } } static int stdio_gensio_accepter_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { int err; struct stdiona_data *nadata = NULL; gensiods max_read_size = GENSIO_DEFAULT_BUF_SIZE; bool raw = false; int i; GENSIO_DECLARE_PPACCEPTER(p, o, cb, "stdio", user_data); for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(&p, args[i], "readbuf", &max_read_size) > 0) continue; if (gensio_pparm_bool(&p, args[i], "raw", &raw) > 0) continue; gensio_pparm_unknown_parm(&p, args[i]); return GE_INVAL; } err = stdio_nadata_setup(o, max_read_size, raw, &nadata); if (err) return err; nadata->connect_runner = o->alloc_runner(o, stdiona_do_connect, nadata); if (!nadata->connect_runner) { stdiona_finish_free(nadata); return GE_NOMEM; } nadata->enable_done_runner = o->alloc_runner(o, enable_done_op, nadata); if (!nadata->enable_done_runner) { stdiona_finish_free(nadata); return err; } err = setup_self(nadata, false); if (err) { stdiona_finish_free(nadata); return err; } err = o->add_iod(o, GENSIO_IOD_STDIO, 0, &nadata->io.out_iod); if (err) { stdiona_finish_free(nadata); return err; } nadata->acc = gensio_acc_data_alloc(o, cb, user_data, gensio_acc_stdio_func, NULL, "stdio", nadata); if (!nadata->acc) { stdiona_finish_free(nadata); return GE_NOMEM; } gensio_acc_set_is_reliable(nadata->acc, true); nadata->io.io = gensio_data_alloc(o, NULL, NULL, gensio_stdio_func, NULL, "stdio", &nadata->io); if (!nadata->io.io) { stdiona_finish_free(nadata); return GE_NOMEM; } *accepter = nadata->acc; return 0; } static int str_to_stdio_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { return stdio_gensio_accepter_alloc(NULL, args, o, cb, user_data, acc); } int gensio_init_stdio(struct gensio_os_funcs *o) { int rv; rv = register_gensio(o, "stdio", str_to_stdio_gensio, stdio_gensio_alloc); if (rv) return rv; rv = register_gensio_accepter(o, "stdio", str_to_stdio_gensio_accepter, stdio_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/gensio_msgdelim.c0000664000175000017500000005153215055560656012563 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018-2025 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include static const uint16_t crc16_table[256] = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 }; static void crc16(const unsigned char *buf, unsigned int len, uint16_t *icrc) { unsigned int i; uint16_t crc = *icrc; for (i = 0; i < len; i++) crc = (crc << 8) ^ crc16_table[((crc >> 8) ^ buf[i]) & 0xff]; *icrc = crc; } struct msgdelim_config { gensiods max_read_size; gensiods max_write_size; bool crc; }; struct msgdelim_filter { struct gensio_filter *filter; struct gensio_os_funcs *o; struct gensio_lock *lock; struct msgdelim_config config; bool in_cmd; /* Last char was 254. */ bool in_msg; /* Currently processing message data (after a start). */ bool in_msg_complete; /* A full message is ready. */ bool out_msg_complete; /* Data waiting to be delivered to the user. */ unsigned char *read_data; gensiods read_data_pos; gensiods read_data_len; /* Data waiting to be written. */ unsigned char *write_data; gensiods buf_max_write; /* Maximum raw bytes (doubling 254s, etc.) */ gensiods write_data_pos; gensiods write_data_len; gensiods user_write_pos; /* Current user position. */ }; /* * The basic protocol is pretty simple here. A 254 is a command byte, * followed by 0 for sending a single 254, and 1 for a message * separator. There is a 16 bit CRC at the end of every message, * unless disabled. */ #define filter_to_msgdelim(v) ((struct msgdelim_filter *) \ gensio_filter_get_user_data(v)) static void msgdelim_lock(struct msgdelim_filter *mfilter) { mfilter->o->lock(mfilter->lock); } static void msgdelim_unlock(struct msgdelim_filter *mfilter) { mfilter->o->unlock(mfilter->lock); } static bool msgdelim_ul_read_pending(struct gensio_filter *filter) { struct msgdelim_filter *mfilter = filter_to_msgdelim(filter); return mfilter->in_msg_complete; } static bool msgdelim_ll_write_pending(struct gensio_filter *filter) { struct msgdelim_filter *mfilter = filter_to_msgdelim(filter); return mfilter->out_msg_complete; } static bool msgdelim_ll_read_needed(struct gensio_filter *filter) { return false; } static int msgdelim_check_open_done(struct gensio_filter *filter, struct gensio *io) { gensio_set_is_packet(io, true); return 0; } static int msgdelim_try_connect(struct gensio_filter *filter, gensio_time *timeout) { return 0; } #include static int msgdelim_try_disconnect(struct gensio_filter *filter, gensio_time *timeout) { struct msgdelim_filter *mfilter = filter_to_msgdelim(filter); if (mfilter->write_data_len == 0 || !mfilter->out_msg_complete) return 0; else return GE_INPROGRESS; } static void msgdelim_add_wrbyte(struct msgdelim_filter *mfilter, unsigned char byte) { mfilter->write_data[mfilter->write_data_len++] = byte; if (byte == 254) mfilter->write_data[mfilter->write_data_len++] = 0; } static int msgdelim_ul_write(struct gensio_filter *filter, gensio_ul_filter_data_handler handler, void *cb_data, gensiods *rcount, const struct gensio_sg *isg, gensiods sglen, const char *const *auxdata) { struct msgdelim_filter *mfilter = filter_to_msgdelim(filter); int err = 0; msgdelim_lock(mfilter); if (mfilter->out_msg_complete) { if (rcount) *rcount = 0; } else { gensiods i, j, writelen = 0; uint16_t crc = 0; for (i = 0; i < sglen; i++) { gensiods inlen = isg[i].buflen; const unsigned char *buf = isg[i].buf; crc16(buf, inlen, &crc); for (j = 0; j < inlen; j++) { if (mfilter->user_write_pos >= mfilter->config.max_write_size) { err = GE_TOOBIG; mfilter->user_write_pos = 0; mfilter->write_data_len = 0; mfilter->write_data_pos = 0; goto out_err; } mfilter->user_write_pos++; msgdelim_add_wrbyte(mfilter, buf[j]); } writelen += inlen; } if (rcount) *rcount = writelen; if (mfilter->user_write_pos > 0) { mfilter->out_msg_complete = true; if (mfilter->config.crc) { msgdelim_add_wrbyte(mfilter, crc >> 8); msgdelim_add_wrbyte(mfilter, crc & 0xff); } mfilter->write_data[mfilter->write_data_len++] = 254; mfilter->write_data[mfilter->write_data_len++] = 1; /* separator */ } } if (mfilter->out_msg_complete) { struct gensio_sg sg[1]; gensiods len = mfilter->write_data_len - mfilter->write_data_pos; gensiods count; sg[0].buflen = len; sg[0].buf = mfilter->write_data + mfilter->write_data_pos; msgdelim_unlock(mfilter); err = handler(cb_data, &count, sg, 1, NULL); msgdelim_lock(mfilter); if (err) { mfilter->out_msg_complete = false; } else { if (count >= len) { mfilter->write_data_len = 0; mfilter->write_data_pos = 0; mfilter->out_msg_complete = false; mfilter->user_write_pos = 0; } else { mfilter->write_data_pos += count; } } } out_err: msgdelim_unlock(mfilter); return err; } static int msgdelim_ll_write(struct gensio_filter *filter, gensio_ll_filter_data_handler handler, void *cb_data, gensiods *rcount, unsigned char *buf, gensiods buflen, const char *const *auxdata) { struct msgdelim_filter *mfilter = filter_to_msgdelim(filter); gensiods in_buflen = buflen; int err = 0; static const char *eomaux[2] = { "eom", NULL }; uint16_t crc; msgdelim_lock(mfilter); if (mfilter->in_msg_complete || buflen == 0) { if (rcount) *rcount = 0; } else { while (buflen && !mfilter->in_msg_complete) { unsigned char b = *buf++; buflen--; if (mfilter->in_cmd) { mfilter->in_cmd = false; switch (b) { case 0: /* 254 0 is one 254 */ b = 254; goto handle_data; case 1: /* 254 1 is message separator */ if (mfilter->in_msg) { if (mfilter->config.crc) { if (mfilter->read_data_len <= 2) break; crc = 0; crc16(mfilter->read_data, mfilter->read_data_len, &crc); if (crc != 0) break; mfilter->read_data_len -= 2; /* Remove the CRC */ } mfilter->in_msg_complete = true; } mfilter->in_msg = true; break; default: mfilter->in_msg = false; break; } } else if (b == 254) { mfilter->in_cmd = true; } else { handle_data: if (!mfilter->in_msg) continue; if (mfilter->read_data_len >= mfilter->config.max_read_size) { mfilter->in_msg = false; continue; } mfilter->read_data[mfilter->read_data_len++] = b; } } if (rcount) *rcount = in_buflen - buflen; } if (mfilter->in_msg_complete) { gensiods count = 0; msgdelim_unlock(mfilter); err = handler(cb_data, &count, mfilter->read_data + mfilter->read_data_pos, mfilter->read_data_len, eomaux); msgdelim_lock(mfilter); if (!err) { if (count >= mfilter->read_data_len) { mfilter->in_msg_complete = false; mfilter->read_data_len = 0; mfilter->read_data_pos = 0; } else { mfilter->read_data_len -= count; mfilter->read_data_pos += count; } } } msgdelim_unlock(mfilter); return err; } static int msgdelim_setup(struct gensio_filter *filter) { return 0; } static void msgdelim_filter_cleanup(struct gensio_filter *filter) { struct msgdelim_filter *mfilter = filter_to_msgdelim(filter); mfilter->read_data_len = 0; mfilter->read_data_pos = 0; mfilter->write_data_len = 0; mfilter->write_data_pos = 0; mfilter->user_write_pos = 0; mfilter->in_msg_complete = false; mfilter->in_msg = false; mfilter->out_msg_complete = false; } static void mfilter_free(struct msgdelim_filter *mfilter) { if (mfilter->lock) mfilter->o->free_lock(mfilter->lock); if (mfilter->read_data) mfilter->o->free(mfilter->o, mfilter->read_data); if (mfilter->write_data) mfilter->o->free(mfilter->o, mfilter->write_data); if (mfilter->filter) gensio_filter_free_data(mfilter->filter); mfilter->o->free(mfilter->o, mfilter); } static void msgdelim_free(struct gensio_filter *filter) { struct msgdelim_filter *mfilter = filter_to_msgdelim(filter); mfilter_free(mfilter); } static int msgdelim_control(struct gensio_filter *filter, bool get, int op, char *data, gensiods *datalen) { struct msgdelim_filter *mfilter = filter_to_msgdelim(filter); switch (op) { case GENSIO_CONTROL_MAX_WRITE_PACKET: if (!get) return GE_NOTSUP; *datalen = snprintf(data, *datalen, "%lu", (unsigned long) mfilter->config.max_write_size); return 0; default: return GE_NOTSUP; } } static int gensio_msgdelim_filter_func(struct gensio_filter *filter, int op, void *func, void *data, gensiods *count, void *buf, const void *cbuf, gensiods buflen, const char *const *auxdata) { switch (op) { case GENSIO_FILTER_FUNC_UL_READ_PENDING: return msgdelim_ul_read_pending(filter); case GENSIO_FILTER_FUNC_LL_WRITE_PENDING: return msgdelim_ll_write_pending(filter); case GENSIO_FILTER_FUNC_LL_READ_NEEDED: return msgdelim_ll_read_needed(filter); case GENSIO_FILTER_FUNC_CHECK_OPEN_DONE: return msgdelim_check_open_done(filter, data); case GENSIO_FILTER_FUNC_TRY_CONNECT: return msgdelim_try_connect(filter, data); case GENSIO_FILTER_FUNC_TRY_DISCONNECT: return msgdelim_try_disconnect(filter, data); case GENSIO_FILTER_FUNC_UL_WRITE_SG: return msgdelim_ul_write(filter, func, data, count, cbuf, buflen, auxdata); case GENSIO_FILTER_FUNC_LL_WRITE: return msgdelim_ll_write(filter, func, data, count, buf, buflen, auxdata); case GENSIO_FILTER_FUNC_SETUP: return msgdelim_setup(filter); case GENSIO_FILTER_FUNC_CLEANUP: msgdelim_filter_cleanup(filter); return 0; case GENSIO_FILTER_FUNC_FREE: msgdelim_free(filter); return 0; case GENSIO_FILTER_FUNC_CONTROL: return msgdelim_control(filter, *((bool *) cbuf), buflen, data, count); default: return GE_NOTSUP; } } static struct gensio_filter * gensio_msgdelim_filter_raw_alloc(struct gensio_os_funcs *o, struct msgdelim_config *config) { struct msgdelim_filter *mfilter; mfilter = o->zalloc(o, sizeof(*mfilter)); if (!mfilter) return NULL; mfilter->o = o; mfilter->config = *config; mfilter->config.max_read_size += 2; /* Add CRC */ /* * Room to double every byte (worst case) including the CRC and * add two separators (first one only for the first sent packet). */ mfilter->buf_max_write = ((config->max_write_size + 2) * 2) + 4; mfilter->lock = o->alloc_lock(o); if (!mfilter->lock) goto out_nomem; mfilter->read_data = o->zalloc(o, config->max_read_size); if (!mfilter->read_data) goto out_nomem; mfilter->write_data = o->zalloc(o, mfilter->buf_max_write); if (!mfilter->write_data) goto out_nomem; mfilter->filter = gensio_filter_alloc_data(o, gensio_msgdelim_filter_func, mfilter); if (!mfilter->filter) goto out_nomem; /* Add a separator at the beginning of the first message. */ mfilter->write_data[0] = 254; mfilter->write_data[1] = 1; /* message separator */ mfilter->write_data_len = 2; return mfilter->filter; out_nomem: mfilter_free(mfilter); return NULL; } static int gensio_msgdelim_config(struct gensio_pparm_info *p, struct gensio_os_funcs *o, const char * const args[], struct gensio_base_parms *parms, struct msgdelim_config *config) { unsigned int i; config->max_read_size = 128; /* FIXME - magic number. */ config->max_write_size = 128; /* FIXME - magic number. */ config->crc = true; for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(p, args[i], "writebuf", &config->max_write_size) > 0) continue; if (gensio_pparm_ds(p, args[i], "readbuf", &config->max_read_size) > 0) continue; if (gensio_pparm_bool(p, args[i], "crc", &config->crc) > 0) continue; if (gensio_base_parm(parms, p, args[i]) > 0) continue; gensio_pparm_unknown_parm(p, args[i]); return GE_INVAL; } return 0; } static int gensio_msgdelim_filter_alloc(struct gensio_os_funcs *o, struct msgdelim_config *config, struct gensio_filter **rfilter) { struct gensio_filter *filter; filter = gensio_msgdelim_filter_raw_alloc(o, config); if (!filter) return GE_NOMEM; *rfilter = filter; return 0; } static int msgdelim_gensio_alloc2(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio_base_parms **parms, struct gensio **net) { int err; struct gensio_filter *filter; struct gensio_ll *ll; struct msgdelim_config config; struct gensio *io; GENSIO_DECLARE_PPGENSIO(p, o, cb, "msgdelim", user_data); memset(&config, 0, sizeof(config)); err = gensio_msgdelim_config(&p, 0, args, *parms, &config); if (err) return err; err = gensio_msgdelim_filter_alloc(o, &config, &filter); if (err) return err; ll = gensio_gensio_ll_alloc(o, child); if (!ll) { gensio_filter_free(filter); return GE_NOMEM; } gensio_ref(child); /* So gensio_ll_free doesn't free the child if fail */ io = base_gensio_alloc(o, ll, filter, child, "msgdelim", cb, user_data); if (!io) { gensio_ll_free(ll); gensio_filter_free(filter); return GE_NOMEM; } gensio_free(child); /* Lose the ref we acquired. */ err = gensio_base_parms_set(io, parms); if (err) { gensio_free(io); return err; } gensio_set_is_packet(io, true); *net = io; return 0; } static int msgdelim_gensio_alloc(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **net) { struct gensio_base_parms *parms; int err; err = gensio_base_parms_alloc(o, true, "msgdelim", &parms); if (err) return err; err = msgdelim_gensio_alloc2(child, args, o, cb, user_data, &parms, net); if (parms) gensio_base_parms_free(&parms); return err; } static int str_to_msgdelim_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct gensio *io2; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio(str, o, cb, user_data, &io2); if (err) return err; err = msgdelim_gensio_alloc(io2, args, o, cb, user_data, new_gensio); if (err) gensio_free(io2); return err; } struct msgdelimna_data { struct gensio_accepter *acc; struct msgdelim_config config; struct gensio_os_funcs *o; gensio_accepter_event cb; void *user_data; }; static void msgdelimna_free(void *acc_data) { struct msgdelimna_data *nadata = acc_data; nadata->o->free(nadata->o, nadata); } static int msgdelimna_alloc_gensio(void *acc_data, const char * const *iargs, struct gensio *child, struct gensio **rio) { struct msgdelimna_data *nadata = acc_data; struct gensio_base_parms *parms = NULL; int err; parms = gensio_acc_base_parms_dup(nadata->acc); if (!parms) return GE_NOMEM; err = msgdelim_gensio_alloc2(child, iargs, nadata->o, NULL, NULL, &parms, rio); if (parms) gensio_base_parms_free(&parms); return err; } static int msgdelimna_new_child(void *acc_data, void **finish_data, struct gensio_filter **filter) { struct msgdelimna_data *nadata = acc_data; return gensio_msgdelim_filter_alloc(nadata->o, &nadata->config, filter); } static int msgdelimna_finish_parent(void *acc_data, void *finish_data, struct gensio *io) { struct msgdelimna_data *nadata = acc_data; int err; err = gensio_acc_base_parms_apply(nadata->acc, io); if (err) return err; gensio_set_is_packet(io, true); return 0; } static int gensio_gensio_acc_msgdelim_cb(void *acc_data, int op, void *data1, void *data2, void *data3, const void *data4) { switch (op) { case GENSIO_GENSIO_ACC_ALLOC_GENSIO: return msgdelimna_alloc_gensio(acc_data, data4, data1, data2); case GENSIO_GENSIO_ACC_NEW_CHILD: return msgdelimna_new_child(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FINISH_PARENT: return msgdelimna_finish_parent(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FREE: msgdelimna_free(acc_data); return 0; default: return GE_NOTSUP; } } static int msgdelim_gensio_accepter_alloc(struct gensio_accepter *child, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { struct msgdelimna_data *nadata = NULL; int err; struct gensio_base_parms *parms = NULL; GENSIO_DECLARE_PPACCEPTER(p, o, cb, "msgdelim", user_data); err = gensio_base_parms_alloc(o, true, "msgdelim", &parms); if (err) goto out_err; nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) goto out_nomem; err = gensio_msgdelim_config(&p, o, args, parms, &nadata->config); if (err) goto out_err; nadata->o = o; nadata->cb = cb; nadata->user_data = user_data; err = gensio_gensio_accepter_alloc(child, o, "msgdelim", cb, user_data, gensio_gensio_acc_msgdelim_cb, nadata, &nadata->acc); if (err) goto out_err; err = gensio_acc_base_parms_set(nadata->acc, &parms); if (err) goto out_err; gensio_acc_set_is_packet(nadata->acc, true); *accepter = nadata->acc; return 0; out_nomem: err = GE_NOMEM; out_err: if (nadata) { if (nadata->acc) gensio_acc_free(nadata->acc); else msgdelimna_free(nadata); } if (parms) gensio_base_parms_free(&parms); return err; } static int str_to_msgdelim_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { int err; struct gensio_accepter *acc2 = NULL; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio_accepter(str, o, cb, user_data, &acc2); if (!err) { err = msgdelim_gensio_accepter_alloc(acc2, args, o, cb, user_data, acc); if (err) gensio_acc_free(acc2); } return err; } int gensio_init_msgdelim(struct gensio_os_funcs *o) { int rv; rv = register_filter_gensio(o, "msgdelim", str_to_msgdelim_gensio, msgdelim_gensio_alloc); if (rv) return rv; rv = register_filter_gensio_accepter(o, "msgdelim", str_to_msgdelim_gensio_accepter, msgdelim_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/errtrig.c0000664000175000017500000000433214664224267011070 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2020 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "errtrig.h" #ifdef _MSC_VER #include #endif #include "pthread_handler.h" #include /* * Some memory allocation and other failure testing. If the * GENSIO_ERRTRIG_TEST environment variable is set to number N, the * Nth call to do_errtrig will return true. The program should call * gensio_osfunc_exit (below); it will cause specific values to be * returned on an exit failure. */ static lock_type errtrig_lock = LOCK_INITIALIZER; static bool errtrig_initialized; static bool errtrig_ready; static bool triggered; static unsigned int errtrig_count; static unsigned int errtrig_curr; static void *trig_caller[4]; bool do_errtrig(void) { unsigned int curr; bool triggerit = false; LOCK(&errtrig_lock); if (!errtrig_initialized) { char *s = getenv("GENSIO_ERRTRIG_TEST"); errtrig_initialized = true; if (s) { errtrig_count = strtoul(s, NULL, 0); errtrig_ready = true; } } if (errtrig_ready) { curr = errtrig_curr++; if (curr == errtrig_count) { triggered = true; triggerit = true; #if _MSC_VER trig_caller[0] = _ReturnAddress(); #else trig_caller[0] = __builtin_return_address(0); #if 0 trig_caller[1] = __builtin_return_address(1); trig_caller[2] = __builtin_return_address(2); trig_caller[3] = __builtin_return_address(3); #endif #endif } } UNLOCK(&errtrig_lock); return triggerit; } #include void errtrig_exit(int rv) { if (!errtrig_ready) exit(rv); assert (rv == 1 || rv == 0); /* Only these values are allowed. */ /* * Return an error. The values mean: * * 0 - No error occurred and the memory allocation failure didn't happen * 1 - An error occurred and the memory allocation failure happenned * 2 - No error occurred and the memory allocation failure happenned * 3 - An error occurred and the memory allocation failure didn't happen */ if (rv == 0 && triggered) rv = 2; if (rv == 0 && !triggered) rv = 0; if (rv == 1 && triggered) rv = 1; if (rv == 1 && !triggered) rv = 3; exit(rv); } gensio-3.0.0/lib/Makefile.am0000664000175000017500000003077415045153771011306 # libgensio.la can depend on iibgensiomdns if BUILTIN_MDNS is set. # Therefore it must be built after libgensiomdns, so it has to be # added after. lib_LTLIBRARIES = libgensioosh.la libgensiomdns.la libgensio.la noinst_HEADERS = telnet.h heap.h utils.h seriallock.h crc.h \ errtrig.h avahi_watcher.h gensio_net.h \ gensio_sound_alsa.h gensio_sound_win.h \ gensio_sound_portaudio.h gensio_sound_file.h \ gensio_base_parms.h libgensioosh_la_SOURCES = \ os_osops.c circbuf.c os_osops_env.c net_addrinfo.c \ net_stdsock.c net_ax25_addr.c utils.c net_addr.c if HAVE_UNIX_OS libgensioosh_la_SOURCES += os_unix.c os_unix_selector.c endif if HAVE_WINDOWS_OS libgensioosh_la_SOURCES += os_win.c endif libgensioosh_la_CPPFLAGS = -DBUILDING_GENSIOOSH_DLL \ -DPKG_LIBEXEC="\"$(gensiolibexecdir)\"" libgensioosh_la_LDFLAGS = -no-undefined -version-info $(GENSIO_LIB_VERSION) \ -fvisibility=hidden libgensioosh_la_LIBADD = @OSH_LIBS@ if ENABLE_INTERNAL_TRACE libgensioosh_la_SOURCES += errtrig.c endif libgensiomdns_la_SOURCES = mdns.c avahi_watcher.c libgensiomdns_la_CPPFLAGS = -DBUILDING_GENSIOMDNS_DLL libgensiomdns_la_LDFLAGS = -no-undefined -version-info $(GENSIO_LIB_VERSION) \ -fvisibility=hidden libgensiomdns_la_LIBADD = libgensioosh.la ${MDNS_LIBS} \ ${REGEX_LIB} libgensio_la_SOURCES = \ gensio.c gensio_base.c buffer.c \ ll_fd.c ll_gensio.c acc.c acc_gensio.c libgensio_la_CPPFLAGS = -DBUILDING_GENSIO_DLL libgensio_la_LDFLAGS = -no-undefined -version-info $(GENSIO_LIB_VERSION) \ -fvisibility=hidden libgensio_la_LIBADD = libgensioosh.la @BASE_LIBS@ if HAVE_WINDOWS_OS gensiolibexecdir = $(bindir) else gensiolibexecdir = $(moduleinstalldir)/$(PACKAGE_VERSION) endif if HAVE_OPENIPMI lib_LTLIBRARIES += libgensio_openipmi_oshandler.la libgensio_openipmi_oshandler_la_SOURCES = gensio_openipmi_oshandler.c libgensio_openipmi_oshandler_la_CPPFLAGS = $(OPENIPMI_CPPFLAGS) libgensio_openipmi_oshandler_la_LDFLAGS = -no-undefined -version-info \ $(GENSIO_LIB_VERSION) -fvisibility=hidden libgensio_openipmi_oshandler_la_LIBADD = $(OPENIPMI_LIBS) endif EXTRA_LTLIBRARIES = gensiolibexec_LTLIBRARIES = DYNAMIC_LDFLAGS = -no-undefined -module -rpath "$(gensiolibexecdir)" -avoid-version DYNAMIC_LIBS = libgensio.la libgensioosh.la if BUILTIN_NET libgensio_la_SOURCES += gensio_net.c else EXTRA_LTLIBRARIES += libgensio_net.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_NET) libgensio_net_la_SOURCES = gensio_net.c libgensio_net_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_net_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_DGRAM libgensio_la_SOURCES += gensio_dgram.c else EXTRA_LTLIBRARIES += libgensio_dgram.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_DGRAM) libgensio_dgram_la_SOURCES = gensio_dgram.c libgensio_dgram_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_dgram_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_SCTP libgensio_la_SOURCES += gensio_sctp.c else EXTRA_LTLIBRARIES += libgensio_sctp.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_SCTP) libgensio_sctp_la_SOURCES = gensio_sctp.c libgensio_sctp_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_sctp_la_LIBADD = $(DYNAMIC_LIBS) $(SCTP_LIBS) if BUILTIN_STDIO libgensio_la_SOURCES += gensio_stdio.c else EXTRA_LTLIBRARIES += libgensio_stdio.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_STDIO) libgensio_stdio_la_SOURCES = gensio_stdio.c libgensio_stdio_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_stdio_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_PTY libgensio_la_SOURCES += gensio_pty.c else EXTRA_LTLIBRARIES += libgensio_pty.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_PTY) libgensio_pty_la_SOURCES = gensio_pty.c libgensio_pty_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_pty_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_DUMMY libgensio_la_SOURCES += gensio_dummy.c else EXTRA_LTLIBRARIES += libgensio_dummy.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_DUMMY) libgensio_dummy_la_SOURCES = gensio_dummy.c libgensio_dummy_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_dummy_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_CONACC libgensio_la_SOURCES += gensio_conacc.c else EXTRA_LTLIBRARIES += libgensio_conacc.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_CONACC) libgensio_conacc_la_SOURCES = gensio_conacc.c libgensio_conacc_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_conacc_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_SERIALDEV libgensio_la_SOURCES += sergensio_serialdev.c seriallock.c else EXTRA_LTLIBRARIES += libgensio_serialdev.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_SERIALDEV) libgensio_serialdev_la_SOURCES = sergensio_serialdev.c seriallock.c libgensio_serialdev_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_serialdev_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_ECHO libgensio_la_SOURCES += gensio_echo.c else EXTRA_LTLIBRARIES += libgensio_echo.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_ECHO) libgensio_echo_la_SOURCES = gensio_echo.c libgensio_echo_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_echo_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_FILE libgensio_la_SOURCES += gensio_file.c else EXTRA_LTLIBRARIES += libgensio_file.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_FILE) libgensio_file_la_SOURCES = gensio_file.c libgensio_file_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_file_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_IPMISOL libgensio_la_SOURCES += sergensio_ipmisol.c else EXTRA_LTLIBRARIES += libgensio_ipmisol.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_IPMISOL) libgensio_ipmisol_la_SOURCES = sergensio_ipmisol.c libgensio_ipmisol_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_ipmisol_la_CFLAGS = $(OPENIPMI_CPPFLAGS) libgensio_ipmisol_la_LIBADD = $(DYNAMIC_LIBS) $(OPENIPMI_LIBS) \ libgensio_openipmi_oshandler.la if HAVE_MDNS if BUILTIN_MDNS libgensio_la_SOURCES += gensio_mdns.c libgensio_la_LIBADD += libgensiomdns.la else EXTRA_LTLIBRARIES += libgensio_mdns.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_MDNS) libgensio_mdns_la_SOURCES = gensio_mdns.c libgensio_mdns_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_mdns_la_LIBADD = $(DYNAMIC_LIBS) libgensiomdns.la endif if BUILTIN_SOUND libgensio_la_SOURCES += gensio_sound.c else EXTRA_LTLIBRARIES += libgensio_sound.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_SOUND) libgensio_sound_la_SOURCES = gensio_sound.c libgensio_sound_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_sound_la_LIBADD = $(DYNAMIC_LIBS) $(SOUND_LIBS) if BUILTIN_CM108GPIO libgensio_la_SOURCES += gensio_cm108gpio.c else EXTRA_LTLIBRARIES += libgensio_cm108gpio.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_CM108GPIO) libgensio_cm108gpio_la_SOURCES = gensio_cm108gpio.c libgensio_cm108gpio_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_cm108gpio_la_LIBADD = $(DYNAMIC_LIBS) $(CM108GPIO_LIBS) if BUILTIN_SSL libgensio_la_SOURCES += gensio_ssl.c else EXTRA_LTLIBRARIES += libgensio_ssl.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_SSL) libgensio_ssl_la_SOURCES = gensio_ssl.c libgensio_ssl_la_CPPFLAGS = $(OPENSSL_INCLUDES) libgensio_ssl_la_LDFLAGS = $(DYNAMIC_LDFLAGS) $(OPENSSL_LDFLAGS) libgensio_ssl_la_LIBADD = $(DYNAMIC_LIBS) $(OPENSSL_LIBS) if BUILTIN_CERTAUTH libgensio_la_SOURCES += gensio_certauth.c else EXTRA_LTLIBRARIES += libgensio_certauth.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_CERTAUTH) libgensio_certauth_la_SOURCES = gensio_certauth.c libgensio_certauth_la_CPPFLAGS = $(OPENSSL_INCLUDES) libgensio_certauth_la_LDFLAGS = $(DYNAMIC_LDFLAGS) $(OPENSSL_LDFLAGS) libgensio_certauth_la_LIBADD = $(DYNAMIC_LIBS) $(OPENSSL_LIBS) if BUILTIN_MUX libgensio_la_SOURCES += gensio_mux.c else EXTRA_LTLIBRARIES += libgensio_mux.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_MUX) libgensio_mux_la_SOURCES = gensio_mux.c libgensio_mux_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_mux_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_TELNET libgensio_la_SOURCES += sergensio_telnet.c telnet.c else EXTRA_LTLIBRARIES += libgensio_telnet.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_TELNET) libgensio_telnet_la_SOURCES = sergensio_telnet.c telnet.c libgensio_telnet_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_telnet_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_MSGDELIM libgensio_la_SOURCES += gensio_msgdelim.c else EXTRA_LTLIBRARIES += libgensio_msgdelim.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_MSGDELIM) libgensio_msgdelim_la_SOURCES = gensio_msgdelim.c libgensio_msgdelim_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_msgdelim_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_RELPKT libgensio_la_SOURCES += gensio_relpkt.c else EXTRA_LTLIBRARIES += libgensio_relpkt.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_RELPKT) libgensio_relpkt_la_SOURCES = gensio_relpkt.c libgensio_relpkt_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_relpkt_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_TRACE libgensio_la_SOURCES += gensio_trace.c else EXTRA_LTLIBRARIES += libgensio_trace.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_TRACE) libgensio_trace_la_SOURCES = gensio_trace.c libgensio_trace_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_trace_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_PERF libgensio_la_SOURCES += gensio_perf.c else EXTRA_LTLIBRARIES += libgensio_perf.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_PERF) libgensio_perf_la_SOURCES = gensio_perf.c libgensio_perf_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_perf_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_KISS libgensio_la_SOURCES += gensio_kiss.c else EXTRA_LTLIBRARIES += libgensio_kiss.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_KISS) libgensio_kiss_la_SOURCES = gensio_kiss.c libgensio_kiss_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_kiss_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_AX25 libgensio_la_SOURCES += gensio_ax25.c else EXTRA_LTLIBRARIES += libgensio_ax25.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_AX25) libgensio_ax25_la_SOURCES = gensio_ax25.c libgensio_ax25_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_ax25_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_XLT libgensio_la_SOURCES += gensio_xlt.c else EXTRA_LTLIBRARIES += libgensio_xlt.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_XLT) libgensio_xlt_la_SOURCES = gensio_xlt.c libgensio_xlt_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_xlt_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_KEEPOPEN libgensio_la_SOURCES += gensio_keepopen.c else EXTRA_LTLIBRARIES += libgensio_keepopen.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_KEEPOPEN) libgensio_keepopen_la_SOURCES = gensio_keepopen.c libgensio_keepopen_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_keepopen_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_SCRIPT libgensio_la_SOURCES += gensio_script.c else EXTRA_LTLIBRARIES += libgensio_script.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_SCRIPT) libgensio_script_la_SOURCES = gensio_script.c libgensio_script_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_script_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_RATELIMIT libgensio_la_SOURCES += gensio_ratelimit.c else EXTRA_LTLIBRARIES += libgensio_ratelimit.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_RATELIMIT) libgensio_ratelimit_la_SOURCES = gensio_ratelimit.c libgensio_ratelimit_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_ratelimit_la_LIBADD = $(DYNAMIC_LIBS) if BUILTIN_AFSKMDM libgensio_la_SOURCES += gensio_afskmdm.c libgensio_la_LIBADD += -lm else EXTRA_LTLIBRARIES += libgensio_afskmdm.la endif gensiolibexec_LTLIBRARIES += $(DYNAMIC_AFSKMDM) libgensio_afskmdm_la_SOURCES = gensio_afskmdm.c libgensio_afskmdm_la_LDFLAGS = $(DYNAMIC_LDFLAGS) libgensio_afskmdm_la_LIBADD = $(DYNAMIC_LIBS) -lm # We need to make sure the main libraries are compiled and ready before # doing the plugins, since the plugins link against them. $(gensiolibexec_LTLIBRARIES): $(lib_LTLIBRARIES) # Same thing as above, but for relinking on installation. We have to # have the main libraries installed before relinking. The rule as # specified below add prerequisites to the targets instead of creating # a rule. install-gensiolibexecLTLIBRARIES gensiolibexec-dummyprereq: install-libLTLIBRARIES .PHONY gensiolibexec-dummyprereq: EXTRA_DIST = README.rst libgensioosh.pc.in libgensio.pc.in libgensiomdns.pc.in DISTCLEANFILES = builtin_gensios.h # This variable must have 'exec' in its name, in order to be installed # by 'install-exec' target (instead of default 'install-data') pkgconfigexecdir = $(libdir)/pkgconfig pkgconfigexec_DATA = libgensioosh.pc libgensio.pc libgensiomdns.pc if HAVE_WINDOWS_OS xgensio_libs = $(gensiolibexec_LTLIBRARIES:.la=.dll.a) xgensio_solibs = $(gensiolibexec_LTLIBRARIES:.la=.dll) else xgensio_libs = $(gensiolibexec_LTLIBRARIES:.la=.a) xgensio_solibs = $(gensiolibexec_LTLIBRARIES:.la=.so) endif install-exec-hook: @(cd $(DESTDIR)$(gensiolibexecdir) && $(RM) -f $(gensiolibexec_LTLIBRARIES)) @(cd $(DESTDIR)$(gensiolibexecdir) && $(RM) -f $(xgensio_libs)) # Since we remove the bogus .la and .a files above at install time, # libtool will not remove the .so or .dll files since the .la file is # no longer there. We have to do that by hand. uninstall-hook: @(cd $(DESTDIR)$(gensiolibexecdir) && $(RM) -f $(xgensio_solibs)) gensio-3.0.0/lib/gensio_sound.c0000664000175000017500000013226614747451760012120 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include #include struct gensio_sound_info { const char *type; /* alsa, port, file, etc. */ const char *devname; unsigned int chans; unsigned int samplerate; bool hwrateonly; gensiods bufsize; unsigned int num_bufs; const char *format; const char *pformat; /* Format on the PCM side. */ }; enum gensio_sound_ll_state { GENSIO_SOUND_LL_CLOSED, GENSIO_SOUND_LL_IN_OPEN, GENSIO_SOUND_LL_OPEN, GENSIO_SOUND_LL_IN_CLOSE, GENSIO_SOUND_LL_IN_OPEN_CLOSE }; struct sound_ll; struct sound_info; static void gensio_sound_devices_free(char **names, char **specs, gensiods count); static int gensio_sound_devices(struct gensio_os_funcs *o, const char *type, char ***names, char ***specs, gensiods *count); enum gensio_sound_fmt_type { GENSIO_SOUND_FMT_UNKNOWN = -1, GENSIO_SOUND_FMT_DOUBLE = 0, GENSIO_SOUND_FMT_MIN_USER = GENSIO_SOUND_FMT_DOUBLE, GENSIO_SOUND_FMT_FLOAT = 1, GENSIO_SOUND_FMT_S32 = 2, GENSIO_SOUND_FMT_S24 = 3, GENSIO_SOUND_FMT_S16 = 4, GENSIO_SOUND_FMT_S8 = 5, /* * All the ones above this are supported on the user side. The * ones below are only supported on the PCM side, and only if the * hardware supports it. */ GENSIO_SOUND_FMT_MAX_USER = GENSIO_SOUND_FMT_S8, GENSIO_SOUND_FMT_U32, GENSIO_SOUND_FMT_U24, GENSIO_SOUND_FMT_U16, GENSIO_SOUND_FMT_U8, #if GENSIO_IS_BIG_ENDIAN GENSIO_SOUND_FMT_DOUBLE_BE = GENSIO_SOUND_FMT_DOUBLE, GENSIO_SOUND_FMT_FLOAT_BE = GENSIO_SOUND_FMT_FLOAT, GENSIO_SOUND_FMT_S32_BE = GENSIO_SOUND_FMT_S32, GENSIO_SOUND_FMT_U32_BE = GENSIO_SOUND_FMT_U32, GENSIO_SOUND_FMT_S24_BE = GENSIO_SOUND_FMT_S24, GENSIO_SOUND_FMT_U24_BE = GENSIO_SOUND_FMT_U24, GENSIO_SOUND_FMT_S16_BE = GENSIO_SOUND_FMT_S16, GENSIO_SOUND_FMT_U16_BE = GENSIO_SOUND_FMT_U16, GENSIO_SOUND_FMT_DOUBLE_LE, GENSIO_SOUND_FMT_FLOAT_LE, GENSIO_SOUND_FMT_S32_LE, GENSIO_SOUND_FMT_U32_LE, GENSIO_SOUND_FMT_S24_LE, GENSIO_SOUND_FMT_U24_LE, GENSIO_SOUND_FMT_S16_LE, GENSIO_SOUND_FMT_U16_LE, GENSIO_SOUND_FMT_DOUBLE_ALT = GENSIO_SOUND_FMT_DOUBLE_LE, GENSIO_SOUND_FMT_FLOAT_ALT = GENSIO_SOUND_FMT_FLOAT_LE, GENSIO_SOUND_FMT_S32_ALT = GENSIO_SOUND_FMT_S32_LE, GENSIO_SOUND_FMT_U32_ALT = GENSIO_SOUND_FMT_U32_LE, GENSIO_SOUND_FMT_S24_ALT = GENSIO_SOUND_FMT_S24_LE, GENSIO_SOUND_FMT_U24_ALT = GENSIO_SOUND_FMT_U24_LE, GENSIO_SOUND_FMT_S16_ALT = GENSIO_SOUND_FMT_S16_LE, GENSIO_SOUND_FMT_U16_ALT = GENSIO_SOUND_FMT_U16_LE, #else GENSIO_SOUND_FMT_DOUBLE_BE, GENSIO_SOUND_FMT_FLOAT_BE, GENSIO_SOUND_FMT_S32_BE, GENSIO_SOUND_FMT_U32_BE, GENSIO_SOUND_FMT_S24_BE, GENSIO_SOUND_FMT_U24_BE, GENSIO_SOUND_FMT_S16_BE, GENSIO_SOUND_FMT_U16_BE, GENSIO_SOUND_FMT_DOUBLE_ALT = GENSIO_SOUND_FMT_DOUBLE_BE, GENSIO_SOUND_FMT_FLOAT_ALT = GENSIO_SOUND_FMT_FLOAT_BE, GENSIO_SOUND_FMT_S32_ALT = GENSIO_SOUND_FMT_S32_BE, GENSIO_SOUND_FMT_U32_ALT = GENSIO_SOUND_FMT_U32_BE, GENSIO_SOUND_FMT_S24_ALT = GENSIO_SOUND_FMT_S24_BE, GENSIO_SOUND_FMT_U24_ALT = GENSIO_SOUND_FMT_U24_BE, GENSIO_SOUND_FMT_S16_ALT = GENSIO_SOUND_FMT_S16_BE, GENSIO_SOUND_FMT_U16_ALT = GENSIO_SOUND_FMT_U16_BE, GENSIO_SOUND_FMT_DOUBLE_LE = GENSIO_SOUND_FMT_DOUBLE, GENSIO_SOUND_FMT_FLOAT_LE = GENSIO_SOUND_FMT_FLOAT, GENSIO_SOUND_FMT_S32_LE = GENSIO_SOUND_FMT_S32, GENSIO_SOUND_FMT_U32_LE = GENSIO_SOUND_FMT_U32, GENSIO_SOUND_FMT_S24_LE = GENSIO_SOUND_FMT_S24, GENSIO_SOUND_FMT_U24_LE = GENSIO_SOUND_FMT_U24, GENSIO_SOUND_FMT_S16_LE = GENSIO_SOUND_FMT_S16, GENSIO_SOUND_FMT_U16_LE = GENSIO_SOUND_FMT_U16, #endif GENSIO_SOUND_FMT_COUNT }; struct sound_format_names { const char *name; enum gensio_sound_fmt_type format; }; /* Used to convert from a string to a format enum value. */ static struct sound_format_names sound_format_names[] = { { "float64", GENSIO_SOUND_FMT_DOUBLE }, { "float", GENSIO_SOUND_FMT_FLOAT }, { "s32", GENSIO_SOUND_FMT_S32 }, { "s24", GENSIO_SOUND_FMT_S24 }, { "s16", GENSIO_SOUND_FMT_S16 }, { "s8", GENSIO_SOUND_FMT_S8 }, { "u32", GENSIO_SOUND_FMT_U32 }, { "u24", GENSIO_SOUND_FMT_U24 }, { "u16", GENSIO_SOUND_FMT_U16 }, { "u8", GENSIO_SOUND_FMT_U8 }, { "float64_be", GENSIO_SOUND_FMT_DOUBLE_BE }, { "float_be", GENSIO_SOUND_FMT_FLOAT_BE }, { "int32_be", GENSIO_SOUND_FMT_S32_BE }, { "int24_be", GENSIO_SOUND_FMT_S24_BE }, { "int16_be", GENSIO_SOUND_FMT_S16_BE }, { "u32_be", GENSIO_SOUND_FMT_U32_BE }, { "u24_be", GENSIO_SOUND_FMT_U24_BE }, { "u16_be", GENSIO_SOUND_FMT_U16_BE }, { "float64_le", GENSIO_SOUND_FMT_DOUBLE_LE }, { "float_le", GENSIO_SOUND_FMT_FLOAT_LE }, { "int32_le", GENSIO_SOUND_FMT_S32_LE }, { "int24_le", GENSIO_SOUND_FMT_S24_LE }, { "int16_le", GENSIO_SOUND_FMT_S16_LE }, { "u32_le", GENSIO_SOUND_FMT_U32_LE }, { "u24_le", GENSIO_SOUND_FMT_U24_LE }, { "u16_le", GENSIO_SOUND_FMT_U16_LE }, { "FLOAT64", GENSIO_SOUND_FMT_DOUBLE }, { "FLOAT", GENSIO_SOUND_FMT_FLOAT }, { "S32", GENSIO_SOUND_FMT_S32 }, { "S24", GENSIO_SOUND_FMT_S24 }, { "S16", GENSIO_SOUND_FMT_S16 }, { "S8", GENSIO_SOUND_FMT_S8 }, { "U32", GENSIO_SOUND_FMT_U32 }, { "U24", GENSIO_SOUND_FMT_U24 }, { "U16", GENSIO_SOUND_FMT_U16 }, { "U8", GENSIO_SOUND_FMT_U8 }, { "FLOAT64_BE", GENSIO_SOUND_FMT_DOUBLE_BE }, { "FLOAT_BE", GENSIO_SOUND_FMT_FLOAT_BE }, { "INT32_BE", GENSIO_SOUND_FMT_S32_BE }, { "INT24_BE", GENSIO_SOUND_FMT_S24_BE }, { "INT16_BE", GENSIO_SOUND_FMT_S16_BE }, { "U32_BE", GENSIO_SOUND_FMT_U32_BE }, { "U24_BE", GENSIO_SOUND_FMT_U24_BE }, { "U16_BE", GENSIO_SOUND_FMT_U16_BE }, { "FLOAT64_LE", GENSIO_SOUND_FMT_DOUBLE_LE }, { "FLOAT_LE", GENSIO_SOUND_FMT_FLOAT_LE }, { "INT32_LE", GENSIO_SOUND_FMT_S32_LE }, { "INT24_LE", GENSIO_SOUND_FMT_S24_LE }, { "INT16_LE", GENSIO_SOUND_FMT_S16_LE }, { "U32_LE", GENSIO_SOUND_FMT_U32_LE }, { "U24_LE", GENSIO_SOUND_FMT_U24_LE }, { "U16_LE", GENSIO_SOUND_FMT_U16_LE }, {} }; struct sound_fmt_info { unsigned int size; /* Size, in bytes, of the sample. */ bool host_bswap; /* Is this byte-swapped with respect to the host? */ bool isfloat; uint32_t offset; /* If unsigned, convert to signed by subtracting this. */ float scale; /* Scale between offset value and float. */ }; static struct sound_fmt_info sound_fmt_info[] = { [ GENSIO_SOUND_FMT_DOUBLE_BE ] = { .size = sizeof(double), .host_bswap = GENSIO_IS_LITTLE_ENDIAN, .isfloat = true }, [ GENSIO_SOUND_FMT_FLOAT_BE ] = { .size = sizeof(float), .host_bswap = GENSIO_IS_LITTLE_ENDIAN, .isfloat = true }, [ GENSIO_SOUND_FMT_S32_BE ] = { .size = 4, .host_bswap = GENSIO_IS_LITTLE_ENDIAN, .scale = 2147483648. }, [ GENSIO_SOUND_FMT_S24_BE ] = { .size = 3, .host_bswap = GENSIO_IS_LITTLE_ENDIAN, .scale = 8388608. }, [ GENSIO_SOUND_FMT_S16_BE ] = { .size = 2, .host_bswap = GENSIO_IS_LITTLE_ENDIAN, .scale = 32768. }, [ GENSIO_SOUND_FMT_U32_BE ] = { .size = 4, .host_bswap = GENSIO_IS_LITTLE_ENDIAN, .offset = 2147483648, .scale = 2147483648. }, [ GENSIO_SOUND_FMT_U24_BE ] = { .size = 3, .host_bswap = GENSIO_IS_LITTLE_ENDIAN, .offset = 8388608, .scale = 8388608. }, [ GENSIO_SOUND_FMT_U16_BE ] = { .size = 2, .host_bswap = GENSIO_IS_LITTLE_ENDIAN, .offset = 32768, .scale = 32768. }, [ GENSIO_SOUND_FMT_S8 ] = { .size = 1, .scale = 128. }, [ GENSIO_SOUND_FMT_U8 ] = { .size = 1, .offset = 128, .scale = 128. }, [ GENSIO_SOUND_FMT_DOUBLE_LE ] = { .size = sizeof(double), .host_bswap = GENSIO_IS_BIG_ENDIAN, .isfloat = true }, [ GENSIO_SOUND_FMT_FLOAT_LE ] = { .size = sizeof(float), .host_bswap = GENSIO_IS_BIG_ENDIAN, .isfloat = true }, [ GENSIO_SOUND_FMT_S32_LE ] = { .size = 4, .host_bswap = GENSIO_IS_BIG_ENDIAN, .scale = 2147483648. }, [ GENSIO_SOUND_FMT_S24_LE ] = { .size = 3, .host_bswap = GENSIO_IS_BIG_ENDIAN, .scale = 8388608. }, [ GENSIO_SOUND_FMT_S16_LE ] = { .size = 2, .host_bswap = GENSIO_IS_BIG_ENDIAN, .scale = 32768. }, [ GENSIO_SOUND_FMT_U32_LE ] = { .size = 4, .host_bswap = GENSIO_IS_BIG_ENDIAN, .offset = 2147483648, .scale = 2147483648. }, [ GENSIO_SOUND_FMT_U24_LE ] = { .size = 3, .host_bswap = GENSIO_IS_BIG_ENDIAN, .offset = 8388608, .scale = 8388608. }, [ GENSIO_SOUND_FMT_U16_LE ] = { .size = 2, .host_bswap = GENSIO_IS_BIG_ENDIAN, .offset = 32768, .scale = 32768. } }; static int32_t get_int24(const unsigned char **in, unsigned int offset, bool host_bswap) { int32_t v = 0; bool big_endian = GENSIO_IS_BIG_ENDIAN ? !host_bswap : host_bswap; if (big_endian) { v = *(*in)++ << 16; v |= *(*in)++ << 8; v |= *(*in)++; } else { v = *(*in)++; v |= *(*in)++ << 8; v |= *(*in)++ << 16; } /* If offset is zero, that means the value is signed. */ if ((v & 0x800000) && !offset) v |= 0xff << 24; return v; } static int32_t get_int(const unsigned char **in, unsigned int size, unsigned int offset, bool host_bswap) { int32_t v = 0; switch(size) { case 4: v = *((int32_t *) *in); if (host_bswap) v = gensio_bswap_32(v); (*in) += 4; break; case 3: v = get_int24(in, offset, host_bswap); break; case 2: v = *((int16_t *) *in); if (host_bswap) v = gensio_bswap_16(v); (*in) += 2; break; case 1: v = *((int8_t *) *in); (*in) += 1; break; default: assert(0); } v -= offset; return v; } static void put_int24(int32_t v, unsigned char **out, bool host_bswap) { bool big_endian = GENSIO_IS_BIG_ENDIAN ? !host_bswap : host_bswap; if (big_endian) { *(*out)++ = v >> 16; *(*out)++ = v >> 8; *(*out)++ = v; } else { *(*out)++ = v; *(*out)++ = v >> 8; *(*out)++ = v >> 16; } } static void put_int(int32_t v, unsigned char **out, unsigned int size, unsigned int offset, bool host_bswap) { v += offset; switch(size) { case 4: if (host_bswap) v = gensio_bswap_32(v); *((int32_t *) *out) = v; (*out) += 4; break; case 3: put_int24(v, out, host_bswap); break; case 2: if (host_bswap) v = gensio_bswap_16(v); *((int16_t *) *out) = v; (*out) += 2; break; case 1: *((int8_t *) *out) = v; (*out) += 1; break; default: assert(0); } } static void put_float(double v, unsigned char **out, unsigned int size, bool host_bswap) { const void *data = *out; if (size == 4) { *((float *) data) = v; if (host_bswap) { int32_t *iv = ((int32_t *) data); *iv = gensio_bswap_32(*((int32_t *) data)); } } else if (size == 8) { *((double *) data) = v; if (host_bswap) { int64_t *iv = ((int64_t *) data); *iv = gensio_bswap_64(*((int64_t *) data)); } } else { assert(0); } *out += size; } static double get_float(const unsigned char **in, unsigned int size, bool host_bswap) { double v = 0; if (size == 4) { char d[4]; memcpy(d, *in, 4); if (host_bswap) { int32_t iv; memcpy(&iv, d, 4); iv = gensio_bswap_32(iv); memcpy(d, &iv, 4); } v = *((float *) d); } else if (size == 8) { char d[8]; memcpy(d, *in, 8); if (host_bswap) { int64_t iv; memcpy(&iv, d, 8); iv = gensio_bswap_64(iv); memcpy(d, &iv, 8); } v = *((double *) d); } else { assert(0); } *in += size; return v; } /* * This is used to convert between the user format and the format used * by the pcm side. */ struct sound_cnv_info { bool enabled; /* PCM format. Will be UNKNOWN if not set by user. */ enum gensio_sound_fmt_type pfmt; enum gensio_sound_fmt_type ufmt; gensiods pframesize; /* Size of a frame on the PCM side, in bytes. */ unsigned int usize; /* Sample size (in bytes) on the user side */ unsigned int psize; /* Sample size on the PCM side, in bytes */ /* Above values are always set. Values below are only set if enabled. */ bool host_bswap; uint32_t offset; /* Subtract/add this from/to the pcm/user to convert. */ float scale_in; /* Multiply by this to scale to -1.0 - 1.0 float, before offset. */ float scale_out; /* Multiply by this to scale from -1.0 - 1.0 float, after offset. */ void (*convin)(const unsigned char **in, unsigned char **out, struct sound_cnv_info *info); void (*convout)(const unsigned char **in, unsigned char **out, struct sound_cnv_info *info); unsigned char *buf; /* PCM buffer(s) */ }; static void conv_int_to_float_in(const unsigned char **in, unsigned char **out, struct sound_cnv_info *info) { double v = get_int(in, info->psize, info->offset, info->host_bswap); v *= info->scale_in; put_float(v, out, info->usize, false); } static void conv_float_to_int_out(const unsigned char **in, unsigned char **out, struct sound_cnv_info *info) { double v = get_float(in, info->usize, false); v *= info->scale_out; put_int(v + .5, out, info->psize, info->offset, info->host_bswap); } static void conv_float_to_int_in(const unsigned char **in, unsigned char **out, struct sound_cnv_info *info) { double v = get_float(in, info->psize, info->host_bswap); v *= info->scale_in; put_int(v + .5, out, info->usize, 0, false); } static void conv_int_to_float_out(const unsigned char **in, unsigned char **out, struct sound_cnv_info *info) { double v = get_float(in, info->usize, false); v *= info->scale_out; put_int(v, out, info->psize, info->offset, info->host_bswap); } static void conv_int_to_int_in(const unsigned char **in, unsigned char **out, struct sound_cnv_info *info) { int32_t v = get_int(in, info->psize, info->offset, info->host_bswap); put_int(v, out, info->usize, 0, false); } static void conv_int_to_int_out(const unsigned char **in, unsigned char **out, struct sound_cnv_info *info) { int32_t v = get_int(in, info->usize, 0, false); put_int(v, out, info->psize, info->offset, info->host_bswap); } static void conv_float_to_float_in(const unsigned char **in, unsigned char **out, struct sound_cnv_info *info) { double v = get_float(in, info->psize, info->host_bswap); put_float(v, out, info->usize, false); } static void conv_float_to_float_out(const unsigned char **in, unsigned char **out, struct sound_cnv_info *info) { double v = get_float(in, info->usize, false); put_float(v, out, info->psize, info->host_bswap); } struct sound_type { const char *name; int (*setup)(struct gensio_pparm_info *p, struct sound_info *si, struct gensio_sound_info *io); void (*cleanup)(struct sound_info *si); int (*open_dev)(struct sound_info *si); void (*close_dev)(struct sound_info *si); int (*sub_write)(struct sound_info *si, const unsigned char *buf, gensiods buflen, gensiods *nr_written); int (*write)(struct sound_info *si, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen); void (*next_read)(struct sound_info *si); void (*set_write_enable)(struct sound_info *si, bool enable); void (*set_read_enable)(struct sound_info *si, bool enable); unsigned int (*start_close)(struct sound_info *si); /* Return number of frames left to send. */ unsigned long (*drain_count)(struct sound_info *si); int (*devices)(struct gensio_os_funcs *o, char ***rnames, char ***rspecs, gensiods *rcount); }; struct sound_info { struct sound_ll *soundll; struct sound_type *type; char *devname; char *cardname; bool is_input; unsigned int samplerate; /* Frames per second. */ bool hwrateonly; /* Don't allow resampling. */ unsigned int framesize; /* User side sample size * number of chans, bytes */ gensiods num_bufs; /* Number of buffers on the PCM size. */ unsigned int chans; /* Number of channels, Will be 0 if disabled. */ bool ready; /* Is a frame ready to send to user, or is write ready? */ gensiods readpos; /* frame offset into buf. */ gensiods len; /* Input only, the number of frames in buf. */ gensiods bufsize; /* Size in frames of buf. */ unsigned char *buf; /* User side buffer. */ /* * The conversion buffer info. This is the pcm side of the data. * If cnv.enabled is false, don't use most of this. A few fields * are always set, see the struct definition for details. */ struct sound_cnv_info cnv; void *pinfo; /* Info for the specific I/O type (alsa, file, etc.). */ }; static void setup_convv(struct sound_info *si, enum gensio_sound_fmt_type pfmt) { enum gensio_sound_fmt_type ufmt = si->cnv.ufmt; struct sound_fmt_info *uinfo, *pinfo; si->cnv.pfmt = pfmt; uinfo = &sound_fmt_info[ufmt]; pinfo = &sound_fmt_info[pfmt]; si->cnv.usize = uinfo->size; si->cnv.psize = pinfo->size; si->cnv.offset = pinfo->offset; si->cnv.host_bswap = pinfo->host_bswap; si->cnv.pframesize = (gensiods) pinfo->size * si->chans; if (pinfo->isfloat && uinfo->isfloat) { si->cnv.convin = conv_float_to_float_in; si->cnv.convout = conv_float_to_float_out; } else if (pinfo->isfloat) { si->cnv.scale_out = 1 / pinfo->scale; si->cnv.scale_in = pinfo->scale; si->cnv.convin = conv_float_to_int_in; si->cnv.convout = conv_int_to_float_out; } else if (uinfo->isfloat) { si->cnv.scale_in = 1 / pinfo->scale; si->cnv.scale_out = pinfo->scale; si->cnv.convin = conv_int_to_float_in; si->cnv.convout = conv_float_to_int_out; } else { si->cnv.convin = conv_int_to_int_in; si->cnv.convout = conv_int_to_int_out; } si->cnv.enabled = true; } static int setup_conv(const char *ufmt, const char *pfmt, struct sound_info *si) { enum gensio_sound_fmt_type pfmtv; enum gensio_sound_fmt_type i; if (si->cnv.ufmt == GENSIO_SOUND_FMT_UNKNOWN) { /* Only do this if it hasn't been done. */ for (i = GENSIO_SOUND_FMT_MIN_USER; i <= GENSIO_SOUND_FMT_MAX_USER; i++) { if (strcmp(sound_format_names[i].name, ufmt) == 0) break; } if (i > GENSIO_SOUND_FMT_MAX_USER || i < GENSIO_SOUND_FMT_MIN_USER) return GE_INVAL; si->cnv.usize = sound_fmt_info[i].size; si->framesize = si->cnv.usize * si->chans; /* Will be overridden if pfmt is set. */ si->cnv.pframesize = si->framesize; si->cnv.ufmt = i; } si->cnv.psize = si->cnv.usize; if (!pfmt) return 0; for (i = 0; i < GENSIO_SOUND_FMT_COUNT; i++) { if (strcmp(sound_format_names[i].name, pfmt) == 0) break; } if (i >= GENSIO_SOUND_FMT_COUNT) return GE_INVAL; pfmtv = i; if (si->cnv.ufmt == pfmtv) return 0; setup_convv(si, pfmtv); return 0; } struct sound_ll { struct gensio_os_funcs *o; struct gensio_lock *lock; struct gensio_runner *runner; bool deferred_op_pending; unsigned int refcount; struct gensio_ll *ll; gensio_ll_cb cb; void *cb_data; enum gensio_sound_ll_state state; gensio_ll_open_done open_done; void *open_done_data; gensio_ll_close_done close_done; void *close_done_data; unsigned int nr_waiting_close; bool do_close_now; bool stream_running; bool read_enabled; bool write_enabled; bool in_read; bool in_write; int err; struct sound_info in; struct sound_info out; unsigned int overflows; unsigned int underflows; }; #define ll_to_sound(v) ((struct sound_ll *) gensio_ll_get_user_data(v)) static void gensio_sound_sched_deferred_op(struct sound_ll *soundll); static void gensio_sound_ll_check_read(struct sound_ll *soundll); static void gensio_sound_ll_check_write(struct sound_ll *soundll); static void gensio_sound_ll_free(struct sound_ll *soundll) { struct gensio_os_funcs *o = soundll->o; if (soundll->in.type) { soundll->in.type->close_dev(&soundll->in); soundll->in.type->cleanup(&soundll->in); } if (soundll->out.type) { soundll->out.type->close_dev(&soundll->out); soundll->out.type->cleanup(&soundll->out); } if (soundll->in.devname) o->free(o, soundll->in.devname); if (soundll->out.devname) o->free(o, soundll->out.devname); if (soundll->in.cardname) o->free(o, soundll->in.cardname); if (soundll->out.cardname) o->free(o, soundll->out.cardname); if (soundll->in.buf) o->free(o, soundll->in.buf); if (soundll->in.cnv.buf) o->free(o, soundll->in.cnv.buf); if (soundll->out.buf) o->free(o, soundll->out.buf); if (soundll->out.cnv.buf) o->free(o, soundll->out.cnv.buf); if (soundll->ll) gensio_ll_free_data(soundll->ll); if (soundll->lock) o->free_lock(soundll->lock); if (soundll->runner) o->free_runner(soundll->runner); o->free(o, soundll); } static void gensio_sound_ll_lock(struct sound_ll *soundll) { soundll->o->lock(soundll->lock); } static void gensio_sound_ll_unlock(struct sound_ll *soundll) { soundll->o->unlock(soundll->lock); } static void gensio_sound_ll_ref(struct sound_ll *soundll) { soundll->refcount++; } static void gensio_sound_ll_deref(struct sound_ll *soundll) { assert(soundll->refcount > 1); soundll->refcount--; } static void gensio_sound_ll_deref_and_unlock(struct sound_ll *soundll) { unsigned int refcount; assert(soundll->refcount > 0); refcount = --soundll->refcount; gensio_sound_ll_unlock(soundll); if (refcount == 0) gensio_sound_ll_free(soundll); } #if HAVE_ALSA || HAVE_WIN32SOUND || HAVE_PORTAUDIO static int extend_sound_devs(char ***names, char ***specs, gensiods *size) { gensiods nsize = *size + 10; char **nnames, **nspecs; nnames = calloc(sizeof(*nnames), nsize); if (!nnames) return GE_NOMEM; nspecs = calloc(sizeof(*nspecs), nsize); if (!nspecs) { free(nnames); return GE_NOMEM; } if (*names) { memcpy(nnames, *names, *size * sizeof(*nnames)); free(*names); } if (*specs) { memcpy(nspecs, *specs, *size * sizeof(*nspecs)); free(*specs); } *names = nnames; *specs = nspecs; *size = nsize; return 0; } #endif static int gensio_sound_api_default_write(struct sound_info *out, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen); #if HAVE_ALSA #include "gensio_sound_alsa.h" #else #define ALSA_INIT #endif #if HAVE_WIN32SOUND #include "gensio_sound_win.h" #else #define WIN_INIT #endif #if HAVE_PORTAUDIO #include "gensio_sound_portaudio.h" #else #define PORTAUDIO_INIT #endif #include "gensio_sound_file.h" static void gensio_sound_ll_check_read(struct sound_ll *soundll) { struct sound_info *si = &soundll->in; if (soundll->in_read) return; if (soundll->read_enabled && (si->ready || soundll->err)) { unsigned int len; gensiods count; if (soundll->err) { soundll->in_read = true; gensio_sound_ll_unlock(soundll); soundll->cb(soundll->cb_data, GENSIO_LL_CB_READ, soundll->err, NULL, 0, NULL); gensio_sound_ll_lock(soundll); soundll->in_read = false; goto out; } if (si->readpos + si->len > si->bufsize) len = si->bufsize - si->readpos; else len = si->len; soundll->in_read = true; gensio_sound_ll_unlock(soundll); count = soundll->cb(soundll->cb_data, GENSIO_LL_CB_READ, 0, si->buf + si->readpos * si->framesize, (gensiods) len * si->framesize, NULL); gensio_sound_ll_lock(soundll); soundll->in_read = false; if (soundll->state != GENSIO_SOUND_LL_OPEN) goto out; si->readpos += count / si->framesize; si->len -= count / si->framesize; if (si->len == 0) { si->readpos = 0; si->ready = false; if (si->type->next_read) si->type->next_read(&soundll->in); } } out: if (soundll->read_enabled && (si->ready || soundll->err)) gensio_sound_sched_deferred_op(soundll); } static void gensio_sound_ll_check_write(struct sound_ll *soundll) { struct sound_info *si = &soundll->out; if (soundll->in_write) return; if (soundll->write_enabled && si->ready) { soundll->in_write = true; gensio_sound_ll_unlock(soundll); soundll->cb(soundll->cb_data, GENSIO_LL_CB_WRITE_READY, 0, NULL, 0, NULL); gensio_sound_ll_lock(soundll); soundll->in_write = false; } if (soundll->write_enabled && si->ready) gensio_sound_sched_deferred_op(soundll); } static void gensio_sound_ll_do_close(struct sound_ll *soundll) { gensio_ll_close_done close_done = soundll->close_done; void *close_done_data = soundll->close_done_data; soundll->close_done = NULL; gensio_sound_ll_unlock(soundll); close_done(soundll->cb_data, close_done_data); gensio_sound_ll_lock(soundll); } static void gensio_sound_ll_do_open(struct sound_ll *soundll, int err) { gensio_ll_open_done open_done = soundll->open_done; void *open_done_data = soundll->open_done_data; soundll->open_done = NULL; gensio_sound_ll_unlock(soundll); open_done(soundll->cb_data, err, open_done_data); gensio_sound_ll_lock(soundll); } static void gensio_sound_do_read_enable(struct sound_ll *soundll) { soundll->in.type->set_read_enable(&soundll->in, true); if (soundll->in.ready || soundll->err) { gensio_sound_sched_deferred_op(soundll); } else { if (soundll->in.ready || soundll->err) gensio_sound_sched_deferred_op(soundll); } } static void gensio_sound_ll_deferred_op(struct gensio_runner *runner, void *cbdata) { struct sound_ll *soundll = cbdata; gensio_sound_ll_lock(soundll); soundll->deferred_op_pending = false; switch(soundll->state) { case GENSIO_SOUND_LL_CLOSED: break; case GENSIO_SOUND_LL_IN_OPEN: { bool oldread = soundll->read_enabled, oldwrite = soundll->write_enabled; soundll->state = GENSIO_SOUND_LL_OPEN; gensio_sound_ll_do_open(soundll, 0); if (soundll->state != GENSIO_SOUND_LL_OPEN) break; /* * These won't be activated if they were enabled before the * open callback, handle that. */ if (oldread && soundll->read_enabled) gensio_sound_do_read_enable(soundll); if (oldwrite && soundll->write_enabled) soundll->out.type->set_write_enable(&soundll->out, true); break; } case GENSIO_SOUND_LL_OPEN: gensio_sound_ll_check_read(soundll); gensio_sound_ll_check_write(soundll); break; case GENSIO_SOUND_LL_IN_OPEN_CLOSE: if (soundll->do_close_now) gensio_sound_ll_do_open(soundll, GE_LOCALCLOSED); /* Fallthrough */ case GENSIO_SOUND_LL_IN_CLOSE: if (soundll->do_close_now) { soundll->do_close_now = false; soundll->state = GENSIO_SOUND_LL_CLOSED; gensio_sound_ll_do_close(soundll); gensio_sound_ll_deref(soundll); } break; default: break; } gensio_sound_ll_deref_and_unlock(soundll); } /* Must be called with the lock held. */ static void gensio_sound_sched_deferred_op(struct sound_ll *soundll) { if (!soundll->deferred_op_pending) { gensio_sound_ll_ref(soundll); soundll->deferred_op_pending = true; soundll->o->run(soundll->runner); } } static int gensio_sound_api_default_write(struct sound_info *out, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen) { int err = 0; gensiods count = 0, i, nr_written = 0; for (i = 0; i < sglen; i++) { const unsigned char *buf, *ibuf = NULL; unsigned char *tbuf; gensiods buflen, ibuflen = 0, j; /* Size in frames. */ if (!sg[i].buflen) continue; if (out->cnv.enabled) { ibuf = sg[i].buf; ibuflen = sg[i].buflen / out->framesize; moredata: tbuf = out->cnv.buf; for (j = 0; j < ibuflen && j < out->bufsize; j++) { gensiods k; for (k = 0; k < out->chans; k++) out->cnv.convout(&ibuf, &tbuf, &out->cnv); } if (j == ibuflen) ibuf = NULL; else ibuflen -= j; buf = out->cnv.buf; buflen = j; } else { buf = sg[i].buf; buflen = sg[i].buflen / out->framesize; } err = out->type->sub_write(out, buf, buflen, &nr_written); if (err) break; count += nr_written * out->framesize; if (nr_written < buflen) /* Didn't write the whole buffer. */ break; if (ibuf) goto moredata; } if (!err && rcount) *rcount = count; return err; } static int gensio_sound_ll_write(struct sound_ll *soundll, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen) { int err = 0; gensiods i = 0; if (soundll->out.chans == 0) return GE_NOTSUP; gensio_sound_ll_lock(soundll); if (soundll->err) { err = soundll->err; goto out_unlock; } if (soundll->state != GENSIO_SOUND_LL_OPEN) { err = GE_NOTREADY; goto out_unlock; } for (i = 0; i < sglen; i++) { if (sg[i].buflen % soundll->out.framesize != 0) { err = GE_INVAL; goto out_unlock; } } err = soundll->out.type->write(&soundll->out, rcount, sg, sglen); out_unlock: gensio_sound_ll_unlock(soundll); return err; } static int gensio_sound_ll_open(struct sound_ll *soundll, gensio_ll_open_done open_done, void *open_data) { int err = 0; gensio_sound_ll_lock(soundll); if (soundll->state != GENSIO_SOUND_LL_CLOSED) { err = GE_INUSE; goto out_unlock; } if (soundll->in.chans) { err = soundll->in.type->open_dev(&soundll->in); if (err) goto out_unlock; } if (soundll->out.chans) { err = soundll->out.type->open_dev(&soundll->out); if (err) { if (soundll->in.chans) soundll->in.type->close_dev(&soundll->in); goto out_unlock; } } soundll->state = GENSIO_SOUND_LL_IN_OPEN; soundll->open_done = open_done; soundll->open_done_data = open_data; soundll->stream_running = true; gensio_sound_sched_deferred_op(soundll); out_unlock: gensio_sound_ll_unlock(soundll); return err; } static int gensio_sound_ll_close(struct sound_ll *soundll, gensio_ll_close_done close_done, void *close_data) { int err = 0; gensio_sound_ll_lock(soundll); if (soundll->state == GENSIO_SOUND_LL_IN_OPEN) soundll->state = GENSIO_SOUND_LL_IN_OPEN_CLOSE; else if (soundll->state == GENSIO_SOUND_LL_OPEN) soundll->state = GENSIO_SOUND_LL_IN_CLOSE; else err = GE_INUSE; if (!err) { gensio_sound_ll_ref(soundll); /* For the close */ soundll->close_done = close_done; soundll->close_done_data = close_data; soundll->nr_waiting_close = 0; if (soundll->in.chans) soundll->nr_waiting_close += soundll->in.type->start_close(&soundll->in); if (soundll->out.chans) soundll->nr_waiting_close += soundll->out.type->start_close(&soundll->out); if (soundll->nr_waiting_close == 0) { soundll->stream_running = false; soundll->do_close_now = true; gensio_sound_sched_deferred_op(soundll); } } gensio_sound_ll_unlock(soundll); return err; } static int gensio_sound_ll_control(struct sound_ll *soundll, bool get, unsigned int option, char *data, gensiods *datalen) { unsigned int i; struct sound_info *si; const char *s; switch(option) { case GENSIO_CONTROL_RADDR: if (!get) return GE_NOTSUP; if (strtoul(data, NULL, 0) > 0) return GE_NOTFOUND; *datalen = gensio_pos_snprintf(data, *datalen, NULL, "sound"); return 0; case GENSIO_CONTROL_LADDR: if (!get) return GE_NOTSUP; if (strcmp(data, "in") == 0) { *datalen = gensio_pos_snprintf(data, *datalen, NULL, "%s", soundll->in.cardname); } else if (strcmp(data, "out") == 0) { *datalen = gensio_pos_snprintf(data, *datalen, NULL, "%s", soundll->out.cardname); } else { return GE_NOTFOUND; } return 0; case GENSIO_CONTROL_IN_RATE: if (!get) return GE_NOTSUP; *datalen = gensio_pos_snprintf(data, *datalen, NULL, "%u", soundll->in.samplerate); return 0; case GENSIO_CONTROL_OUT_RATE: if (!get) return GE_NOTSUP; *datalen = gensio_pos_snprintf(data, *datalen, NULL, "%u", soundll->out.samplerate); return 0; case GENSIO_CONTROL_IN_BUFSIZE: if (!get) return GE_NOTSUP; *datalen = gensio_pos_snprintf(data, *datalen, NULL, "%lu", (unsigned long) soundll->in.bufsize); return 0; case GENSIO_CONTROL_OUT_BUFSIZE: if (!get) return GE_NOTSUP; *datalen = gensio_pos_snprintf(data, *datalen, NULL, "%lu", (unsigned long) soundll->out.bufsize); return 0; case GENSIO_CONTROL_IN_NR_CHANS: if (!get) return GE_NOTSUP; *datalen = gensio_pos_snprintf(data, *datalen, NULL, "%u", soundll->in.chans); return 0; case GENSIO_CONTROL_OUT_NR_CHANS: if (!get) return GE_NOTSUP; *datalen = gensio_pos_snprintf(data, *datalen, NULL, "%u", soundll->out.chans); return 0; case GENSIO_CONTROL_IN_FORMAT: if (!get) return GE_NOTSUP; si = &soundll->in; goto get_si_format; case GENSIO_CONTROL_OUT_FORMAT: if (!get) return GE_NOTSUP; si = &soundll->out; get_si_format: s = "unknown"; for (i = 0; sound_format_names[i].name; i++) { if (sound_format_names[i].format == si->cnv.ufmt) { s = sound_format_names[i].name; break; } } *datalen = gensio_pos_snprintf(data, *datalen, NULL, "%s", s); return 0; case GENSIO_CONTROL_DRAIN_COUNT: { unsigned long frames_left = 0; if (!get) return GE_NOTSUP; si = &soundll->out; if (!si->type) return GE_NOTSUP; if (si->type->drain_count) frames_left = si->type->drain_count(si); *datalen = gensio_pos_snprintf(data, *datalen, NULL, "%lu", frames_left); return 0; } default: return GE_NOTSUP; } } static int gensio_sound_ll_do_free(struct sound_ll *soundll) { gensio_sound_ll_lock(soundll); switch (soundll->state) { case GENSIO_SOUND_LL_IN_OPEN: case GENSIO_SOUND_LL_OPEN: gensio_sound_ll_close(soundll, NULL, NULL); break; default: break; } gensio_sound_ll_deref_and_unlock(soundll); return 0; } static int gensio_sound_ll_func(struct gensio_ll *ll, int op, gensiods *count, void *buf, const void *cbuf, gensiods buflen, const char *const *auxdata) { struct sound_ll *soundll = ll_to_sound(ll); switch (op) { case GENSIO_LL_FUNC_SET_CALLBACK: soundll->cb = (gensio_ll_cb) cbuf; soundll->cb_data = buf; return 0; case GENSIO_LL_FUNC_WRITE_SG: return gensio_sound_ll_write(soundll, count, cbuf, buflen); case GENSIO_LL_FUNC_OPEN: return gensio_sound_ll_open(soundll, (gensio_ll_open_done) cbuf, buf); case GENSIO_LL_FUNC_CLOSE: return gensio_sound_ll_close(soundll, (gensio_ll_close_done) cbuf, buf); case GENSIO_LL_FUNC_SET_READ_CALLBACK: { bool enable = !!buflen; /* Output only, just ignore. */ if (!soundll->in.type) return 0; gensio_sound_ll_lock(soundll); if (soundll->read_enabled != enable) { soundll->read_enabled = enable; if (soundll->state == GENSIO_SOUND_LL_OPEN) { if (enable) gensio_sound_do_read_enable(soundll); else soundll->in.type->set_read_enable(&soundll->in, false); } } gensio_sound_ll_unlock(soundll); return 0; } case GENSIO_LL_FUNC_SET_WRITE_CALLBACK: { bool enable = !!buflen; /* Input only, just ignore. */ if (!soundll->out.type) return 0; gensio_sound_ll_lock(soundll); if (soundll->write_enabled != enable) { soundll->write_enabled = enable; if (soundll->state == GENSIO_SOUND_LL_OPEN) { soundll->out.type->set_write_enable(&soundll->out, enable); if (soundll->out.ready) gensio_sound_sched_deferred_op(soundll); } } gensio_sound_ll_unlock(soundll); return 0; } case GENSIO_LL_FUNC_FREE: return gensio_sound_ll_do_free(soundll); case GENSIO_LL_FUNC_DISABLE: soundll->stream_running = false; soundll->in.type->close_dev(&soundll->in); soundll->in.type->close_dev(&soundll->out); soundll->state = GENSIO_SOUND_LL_CLOSED; return 0; case GENSIO_LL_FUNC_CONTROL: return gensio_sound_ll_control(soundll, *((bool *) cbuf), buflen, buf, count); } return GE_NOTSUP; } static struct sound_type *sound_types[] = { ALSA_INIT WIN_INIT PORTAUDIO_INIT FILE_INIT NULL }; static int setup_sound_info(struct gensio_pparm_info *p, const char *dir, struct gensio_os_funcs *o, struct sound_info *si, struct gensio_sound_info *io, bool isinput) { unsigned int i = 0; int err; if (io->type) { for (; sound_types[i]; i++) { if (strcmp(io->type, sound_types[i]->name) == 0) break; } } if (!sound_types[i]) { gensio_pparm_log(p, "%s: Unknown sound type: %s", dir, io->type); return GE_INVAL; } si->type = sound_types[i]; if (!io->devname) { gensio_pparm_log(p, "%s: No device name", dir); return GE_INVAL; } if (io->samplerate == 0) { gensio_pparm_log(p, "%s: Sample rate is 0", dir); return GE_INVAL; } if (io->chans == 0) { gensio_pparm_log(p, "%s: Number of channels is 0", dir); return GE_INVAL; } if (!io->format) { gensio_pparm_log(p, "%s: format is not set", dir); return GE_INVAL; } if (io->bufsize == 0) { gensio_pparm_log(p, "%s: Buffer size is 0", dir); return GE_INVAL; } if (io->num_bufs == 0) { gensio_pparm_log(p, "%s: Number of buffers is 0", dir); return GE_INVAL; } si->cnv.pfmt = GENSIO_SOUND_FMT_UNKNOWN; si->cnv.ufmt = GENSIO_SOUND_FMT_UNKNOWN; si->bufsize = io->bufsize; si->num_bufs = io->num_bufs; si->chans = io->chans; si->samplerate = io->samplerate; si->hwrateonly = io->hwrateonly; err = setup_conv(io->format, io->pformat, si); if (err) { gensio_pparm_log(p, "%s: Unknown format", dir); return err; } err = si->type->setup(p, si, io); if (err) return err; si->devname = gensio_strdup(o, io->devname); if (!si->devname) return GE_NOMEM; if (isinput) { /* One buffer for sending to the user. */ si->buf = o->zalloc(o, io->bufsize * si->framesize); if (!si->buf) return GE_NOMEM; } return 0; } static int gensio_sound_ll_alloc(struct gensio_pparm_info *p, struct gensio_os_funcs *o, struct gensio_sound_info *in, struct gensio_sound_info *out, struct gensio_ll **newll) { int err; struct sound_ll *soundll; if (in && in->chans == 0) in = NULL; if (out && out->chans == 0) out = NULL; if (!in && !out) { gensio_pparm_slog(p, "Must set input or output channels"); return GE_INVAL; } soundll = o->zalloc(o, sizeof(*soundll)); if (!soundll) return GE_NOMEM; soundll->refcount = 1; soundll->o = o; if (in) { soundll->in.is_input = true; soundll->in.soundll = soundll; err = setup_sound_info(p, "in", o, &soundll->in, in, true); if (err) goto out_err; } if (out) { soundll->out.is_input = false; soundll->out.soundll = soundll; err = setup_sound_info(p, "out", o, &soundll->out, out, false); if (err) goto out_err; } soundll->runner = o->alloc_runner(o, gensio_sound_ll_deferred_op, soundll); if (!soundll->runner) goto out_nomem; soundll->lock = o->alloc_lock(o); if (!soundll->lock) goto out_nomem; soundll->ll = gensio_ll_alloc_data(o, gensio_sound_ll_func, soundll); if (!soundll->ll) goto out_nomem; *newll = soundll->ll; return 0; out_nomem: err = GE_NOMEM; out_err: gensio_sound_ll_free(soundll); return err; } static void gensio_sound_devices_free(char **names, char **specs, gensiods count) { gensiods i; if (names) { for (i = 0; i < count; i++) { if (names[i]) free(names[i]); } free(names); } if (specs) { for (i = 0; i < count; i++) { if (specs[i]) free(specs[i]); } free(specs); } } static int gensio_sound_devices(struct gensio_os_funcs *o, const char *type, char ***rnames, char ***rspecs, gensiods *rcount) { unsigned int i = 0; if (type) { for (; sound_types[i]; i++) { if (strcmp(type, sound_types[i]->name) == 0) break; } } if (!sound_types[i]) return GE_INVAL; return sound_types[i]->devices(o, rnames, rspecs, rcount); } static int alloc_sound_list(struct gensio_os_funcs *o, const char *type, gensio_event cb, void *user_data, struct gensio **rio) { char **names, **specs; gensiods i, count, len = 1; int err; const char *argv[3]; char *data; err = gensio_sound_devices(o, type, &names, &specs, &count); if (err) return err; for (i = 0; i < count; i++) len += strlen(names[i]) + strlen(specs[i]) + 2; data = o->zalloc(o, 5 + len); if (!data) { err = GE_NOMEM; goto out; } memcpy(data, "data=", 5); len = 5; for (i = 0; i < count; i++) { gensiods cpysize = strlen(names[i]); memcpy(data + len, names[i], cpysize); len += cpysize; data[len++] = '\t'; cpysize = strlen(specs[i]); memcpy(data + len, specs[i], cpysize); len += cpysize; data[len++] = '\n'; } data[len] = '\0'; argv[0] = "noecho"; argv[1] = data; argv[2] = NULL; err = gensio_terminal_alloc("echo", NULL, argv, o, cb, user_data, rio); out: if (data) o->free(o, data); gensio_sound_devices_free(names, specs, count); return err; } static int sound_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **rio) { const char *devname = gdata; int err; struct gensio_sound_info in, out; struct gensio_ll *ll; struct gensio *io; gensiods dsval; unsigned int uival; bool list = false; int i; GENSIO_DECLARE_PPGENSIO(p, o, cb, "sound", user_data); memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); in.devname = devname; out.devname = devname; in.bufsize = 1024; in.num_bufs = 100; out.bufsize = 1024; out.num_bufs = 100; for (i = 0; args && args[i]; i++) { if (isdigit(args[i][0])) { const char *s = args[i]; char *n; in.samplerate = strtoul(s, &n, 0); if (n[0] != '-' || n[1] == '\0') { gensio_pparm_log(&p, "Invalid sample rate: %s\n", s); return GE_INVAL; } s = n + 1; in.chans = strtoul(s, &n, 0); if (n[0] != '-' || n[1] == '\0') { gensio_pparm_log(&p, "Invalid sample rate: %s\n", s); return GE_INVAL; } in.format = n + 1; out.samplerate = in.samplerate; out.chans = in.chans; out.format = in.format; continue; } if (gensio_pparm_ds(&p, args[i], "inbufsize", &in.bufsize) > 0) continue; if (gensio_pparm_ds(&p, args[i], "outbufsize", &out.bufsize) > 0) continue; if (gensio_pparm_ds(&p, args[i], "bufsize", &dsval) > 0) { in.bufsize = dsval; out.bufsize = dsval; continue; } if (gensio_pparm_uint(&p, args[i], "innbufs", &in.num_bufs) > 0) continue; if (gensio_pparm_uint(&p, args[i], "outnbufs", &out.num_bufs) > 0) continue; if (gensio_pparm_uint(&p, args[i], "nbufs", &uival) > 0) { in.num_bufs = uival; out.num_bufs = uival; continue; } if (gensio_pparm_uint(&p, args[i], "chans", &in.chans) > 0) { out.chans = in.chans; continue; } if (gensio_pparm_uint(&p, args[i], "inchans", &in.chans) > 0) continue; if (gensio_pparm_uint(&p, args[i], "outchans", &out.chans) > 0) continue; if (gensio_pparm_uint(&p, args[i], "inrate", &in.samplerate) > 0) continue; if (gensio_pparm_uint(&p, args[i], "outrate", &out.samplerate) > 0) continue; if (gensio_pparm_uint(&p, args[i], "rate", &uival) > 0) { in.samplerate = uival; out.samplerate = uival; continue; } if (gensio_pparm_bool(&p, args[i], "inhwrateonly", &in.hwrateonly) > 0) continue; if (gensio_pparm_bool(&p, args[i], "outhwrateonly", &out.hwrateonly) > 0) continue; if (gensio_pparm_bool(&p, args[i], "hwrateonly", &in.hwrateonly) > 0) { out.hwrateonly = in.hwrateonly; continue; } if (gensio_pparm_bool(&p, args[i], "list", &list) > 0) continue; if (gensio_pparm_value(&p, args[i], "intype", &in.type) > 0) continue; if (gensio_pparm_value(&p, args[i], "outtype", &out.type) > 0) continue; if (gensio_pparm_value(&p, args[i], "type", &out.type) > 0) { in.type = out.type; continue; } if (gensio_pparm_value(&p, args[i], "outdev", &out.devname) > 0) continue; if (gensio_pparm_value(&p, args[i], "informat", &in.format) > 0) continue; if (gensio_pparm_value(&p, args[i], "outformat", &out.format) > 0) continue; if (gensio_pparm_value(&p, args[i], "format", &out.format) > 0) { in.format = out.format; continue; } if (gensio_pparm_value(&p, args[i], "inpformat", &in.pformat) > 0) continue; if (gensio_pparm_value(&p, args[i], "outpformat", &out.pformat) > 0) continue; if (gensio_pparm_value(&p, args[i], "pformat", &out.pformat) > 0) { in.pformat = out.pformat; continue; } gensio_pparm_unknown_parm(&p, args[i]); return GE_INVAL; } if (list) return alloc_sound_list(o, in.type, cb, user_data, rio); err = gensio_sound_ll_alloc(&p, o, &in, &out, &ll); if (err) goto out_err; io = base_gensio_alloc(o, ll, NULL, NULL, "sound", cb, user_data); if (!io) { gensio_ll_free(ll); return GE_NOMEM; } *rio = io; return 0; out_err: return err; } static int str_to_sound_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { return sound_gensio_alloc(str, args, o, cb, user_data, new_gensio); } int gensio_init_sound(struct gensio_os_funcs *o) { int rv; rv = register_gensio(o, "sound", str_to_sound_gensio, sound_gensio_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/os_osops_env.c0000664000175000017500000001176014747451760012133 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2019 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include #include #include #include #include #ifdef _WIN32 #include int gensio_os_env_get(const char *name, char *rval, gensiods *len) { DWORD rv; gensiods olen = *len; rv = GetEnvironmentVariable(name, rval, olen); if (rv == 0) { if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) return GE_NOTFOUND; return GE_INVAL; } if (rv >= olen) { /* * Windows returns the length with the nil char included on not * big enough. We return without the nil char for consistency. */ *len = rv - 1; return GE_TOOBIG; } *len = rv; return 0; } int gensio_os_env_set(const char *name, const char *val) { if (!SetEnvironmentVariable(name, val)) return GE_INVAL; return 0; } int gensio_os_argvenv_alloc(struct gensio_os_funcs *o, const char ***rargv, gensiods *rargs, gensiods *rargc) { char *epos = GetEnvironmentStrings(), *spos = epos; const char **argv = NULL; gensiods args = 0, argc = 0; int rv = 0; while (*spos) { rv = gensio_argv_append(o, &argv, spos, &args, &argc, true); if (rv) break; spos += strlen(spos) + 1; } FreeEnvironmentStrings(epos); if (!rv) rv = gensio_argv_append(o, &argv, NULL, &args, &argc, true); if (rv && argv) gensio_argv_free(o, argv); if (!rv) { *rargv = argv; *rargs = args; *rargc = argc; } return rv; } #else /* _WIN32 */ #include #include int gensio_os_env_get(const char *name, char *rval, gensiods *len) { const char *tval = getenv(name); gensiods olen = *len; if (!tval) return GE_NOTFOUND; *len = strlen(tval); if (*len + 1 > olen) return GE_TOOBIG; memcpy(rval, tval, *len + 1); return 0; } int gensio_os_env_set(const char *name, const char *val) { if (val) { if (setenv(name, val, true) != 0) { if (errno == ENOMEM) return GE_NOMEM; return GE_INVAL; } } else { if (unsetenv(name) != 0) return GE_INVAL; } return 0; } extern char **environ; int gensio_os_argvenv_alloc(struct gensio_os_funcs *o, const char ***rargv, gensiods *rargs, gensiods *rargc) { char **epos; const char **argv = NULL; gensiods args = 0, argc = 0; int rv = 0; for (epos = environ; *epos != NULL; epos++) rv = gensio_argv_append(o, &argv, *epos, &args, &argc, true); if (!rv) rv = gensio_argv_append(o, &argv, NULL, &args, &argc, true); if (rv && argv) gensio_argv_free(o, argv); if (!rv) { *rargv = argv; *rargs = args; *rargc = argc; } return rv; } #endif /* _WIN32 */ int gensio_os_env_getalloc(struct gensio_os_funcs *o, const char *name, char **rval) { gensiods len = 0; char dummy[1]; char *val = dummy; int rv; rv = gensio_os_env_get(name, val, &len); if (rv != GE_TOOBIG) return rv; len++; val = o->zalloc(o, len); rv = gensio_os_env_get(name, val, &len); if (rv) { o->free(o, val); return rv; } *rval = val; return 0; } static bool argvenv_find(const char **argv, const char *name, gensiods *pos, const char **val) { gensiods i, len = strlen(name); for (i = 0; argv[i]; i++) { if (strncmp(argv[i], name, len) == 0 && argv[i][len] == '=') { if (pos) *pos = i; if (val) *val = argv[i] + len + 1; return true; } } return false; } int gensio_os_argvenv_get(struct gensio_os_funcs *o, const char **argv, const char *name, char *rval, gensiods *rlen) { gensiods olen = *rlen; const char *val; if (!argvenv_find(argv, name, NULL, &val)) return GE_NOTFOUND; *rlen = strlen(val); if (*rlen + 1 > olen) return GE_TOOBIG; memcpy(rval, val, *rlen + 1); return 0; } int gensio_os_argvenv_set(struct gensio_os_funcs *o, const char ***rargv, gensiods *args, gensiods *argc, const char *name, const char *val) { gensiods pos; const char *tval, **argv = *rargv; char *nval; bool found; found = argvenv_find(argv, name, &pos, &tval); if (!val) { if (!found) return 0; o->free(o, (void *) argv[pos]); do { argv[pos] = argv[pos + 1]; pos++; } while (argv[pos]); (*argc)--; } else { if (!found) return gensio_argv_sappend(o, rargv, args, argc, "%s=%s", name, val); nval = gensio_alloc_sprintf(o, "%s=%s", name, val); if (!nval) return GE_NOMEM; o->free(o, (void *) argv[pos]); argv[pos] = nval; } return 0; } int gensio_os_argvenv_getalloc(struct gensio_os_funcs *o, const char **argv, const char *name, char **rval) { gensiods len; const char *val; char *nval; if (!argvenv_find(argv, name, NULL, &val)) return GE_NOTFOUND; len = strlen(val) + 1; nval = o->zalloc(o, len); if (!nval) return GE_NOMEM; memcpy(nval, val, len); *rval = nval; return 0; } gensio-3.0.0/lib/libgensiomdns.pc.in0000664000175000017500000000040114664224267013025 prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libgensiomdns Description: A gensiolibrary to abstract MDNS interfaces Version: @VERSION@ Libs: -L${libdir} -lgensiomdns -lgensioosh -lgensio Libs.private: @MDNS_LIBS@ gensio-3.0.0/lib/gensio_sound_alsa.h0000664000175000017500000005340015055561024013101 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2022 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include #include struct alsa_info { snd_pcm_t *pcm; /* File descriptor info from ALSA. */ struct pollfd *fds; struct gensio_iod **iods; unsigned int nrfds; struct gensio_timer *close_timer; }; static void gensio_sound_alsa_api_close_dev(struct sound_info *si) { struct gensio_os_funcs *o = si->soundll->o; struct alsa_info *a = si->pinfo; unsigned int i; if (!a) return; for (i = 0; a->iods && i < a->nrfds; i++) { if (!a->iods[i]) continue; if (!si->soundll->stream_running) o->clear_fd_handlers_norpt(a->iods[i]); o->release_iod(a->iods[i]); } if (a->pcm) { snd_pcm_close(a->pcm); a->pcm = NULL; } if (a->fds) { o->free(o, a->fds); a->fds = NULL; } if (a->iods) { o->free(o, a->iods); a->iods = NULL; } a->nrfds = 0; } struct alsa_sound_format_cnv { enum gensio_sound_fmt_type gformat; snd_pcm_format_t format; } alsa_sound_format_cnv[] = { { GENSIO_SOUND_FMT_DOUBLE,SND_PCM_FORMAT_FLOAT64 }, { GENSIO_SOUND_FMT_FLOAT, SND_PCM_FORMAT_FLOAT }, { GENSIO_SOUND_FMT_S32, SND_PCM_FORMAT_S32 }, { GENSIO_SOUND_FMT_S24, SND_PCM_FORMAT_S24 }, { GENSIO_SOUND_FMT_S16, SND_PCM_FORMAT_S16 }, { GENSIO_SOUND_FMT_S8, SND_PCM_FORMAT_S8 }, { GENSIO_SOUND_FMT_U32, SND_PCM_FORMAT_U32 }, { GENSIO_SOUND_FMT_U24, SND_PCM_FORMAT_U24 }, { GENSIO_SOUND_FMT_U16, SND_PCM_FORMAT_U16 }, { GENSIO_SOUND_FMT_U8, SND_PCM_FORMAT_U8 }, { GENSIO_SOUND_FMT_DOUBLE_BE, SND_PCM_FORMAT_FLOAT64_BE }, { GENSIO_SOUND_FMT_FLOAT_BE, SND_PCM_FORMAT_FLOAT_BE }, { GENSIO_SOUND_FMT_S32_BE, SND_PCM_FORMAT_S32_BE }, { GENSIO_SOUND_FMT_U32_BE, SND_PCM_FORMAT_U32_BE }, { GENSIO_SOUND_FMT_S24_BE, SND_PCM_FORMAT_S24_BE }, { GENSIO_SOUND_FMT_U24_BE, SND_PCM_FORMAT_U24_BE }, { GENSIO_SOUND_FMT_S16_BE, SND_PCM_FORMAT_S16_BE }, { GENSIO_SOUND_FMT_U16_BE, SND_PCM_FORMAT_U16_BE }, { GENSIO_SOUND_FMT_DOUBLE_LE, SND_PCM_FORMAT_FLOAT64_LE }, { GENSIO_SOUND_FMT_FLOAT_LE, SND_PCM_FORMAT_FLOAT_LE }, { GENSIO_SOUND_FMT_S32_LE, SND_PCM_FORMAT_S32_LE }, { GENSIO_SOUND_FMT_U32_LE, SND_PCM_FORMAT_U32_LE }, { GENSIO_SOUND_FMT_S24_LE, SND_PCM_FORMAT_S24_LE }, { GENSIO_SOUND_FMT_U24_LE, SND_PCM_FORMAT_U24_LE }, { GENSIO_SOUND_FMT_S16_LE, SND_PCM_FORMAT_S16_LE }, { GENSIO_SOUND_FMT_U16_LE, SND_PCM_FORMAT_U16_LE }, { GENSIO_SOUND_FMT_UNKNOWN } }; static enum gensio_sound_fmt_type fallback_order[] = { GENSIO_SOUND_FMT_DOUBLE, GENSIO_SOUND_FMT_DOUBLE_ALT, GENSIO_SOUND_FMT_S32, GENSIO_SOUND_FMT_U32, GENSIO_SOUND_FMT_S32_ALT, GENSIO_SOUND_FMT_U32_ALT, GENSIO_SOUND_FMT_FLOAT, GENSIO_SOUND_FMT_FLOAT_ALT, GENSIO_SOUND_FMT_S16, GENSIO_SOUND_FMT_U16, GENSIO_SOUND_FMT_S16_ALT, GENSIO_SOUND_FMT_U16_ALT, GENSIO_SOUND_FMT_S8, GENSIO_SOUND_FMT_U8, GENSIO_SOUND_FMT_UNKNOWN, }; static snd_pcm_format_t gensio_sound_fmt_to_pcm(enum gensio_sound_fmt_type gfmt) { unsigned int i; for (i = 0; alsa_sound_format_cnv[i].gformat != GENSIO_SOUND_FMT_UNKNOWN; i++) { if (alsa_sound_format_cnv[i].gformat == gfmt) return alsa_sound_format_cnv[i].format; } assert(0); return 0; } static int gensio_sound_alsa_set_hwparams(struct sound_info *si) { struct gensio_os_funcs *o = si->soundll->o; struct alsa_info *a = si->pinfo; snd_pcm_hw_params_t *params; snd_pcm_uframes_t frsize; int err; snd_pcm_hw_params_alloca(¶ms); err = snd_pcm_hw_params_any(a->pcm, params); if (err < 0) { gensio_log(o, GENSIO_LOG_ERR, "alsa error from snd_pcm_hw_params_any: %s\n", snd_strerror(err)); goto out_err; } err = snd_pcm_hw_params_set_rate_resample(a->pcm, params, !si->hwrateonly); if (err < 0) { gensio_log(o, GENSIO_LOG_ERR, "alsa error from snd_pcm_hw_params_set_rate_resample: %s\n", snd_strerror(err)); goto out_err; } err = snd_pcm_hw_params_set_access(a->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { gensio_log(o, GENSIO_LOG_ERR, "alsa error from snd_pcm_hw_params_set_access: %s\n", snd_strerror(err)); goto out_err; } if (si->cnv.pfmt != GENSIO_SOUND_FMT_UNKNOWN) { err = snd_pcm_hw_params_set_format(a->pcm, params, gensio_sound_fmt_to_pcm(si->cnv.pfmt)); } else { err = snd_pcm_hw_params_set_format(a->pcm, params, gensio_sound_fmt_to_pcm(si->cnv.ufmt)); if (err < 0) { unsigned int i; /* * We didn't get the requested one, try the possible values * and use the one we find. */ for (i = 0; fallback_order[i] != GENSIO_SOUND_FMT_UNKNOWN; i++) { err = snd_pcm_hw_params_set_format(a->pcm, params, gensio_sound_fmt_to_pcm(fallback_order[i])); if (err >= 0) { setup_convv(si, fallback_order[i]); break; } } } } if (err < 0) { gensio_log(o, GENSIO_LOG_ERR, "alsa error from snd_pcm_hw_params_set_format %d: %s\n", si->cnv.ufmt, snd_strerror(err)); goto out_err; } if (si->cnv.enabled) { si->cnv.pframesize = (gensiods) si->cnv.psize * si->chans; si->cnv.buf = o->zalloc(o, si->bufsize * si->cnv.pframesize); if (!si->cnv.buf) return GE_NOMEM; } err = snd_pcm_hw_params_set_channels(a->pcm, params, si->chans); if (err < 0) { gensio_log(o, GENSIO_LOG_ERR, "alsa error from snd_pcm_hw_params_set_channels: %s\n", snd_strerror(err)); goto out_err; } err = snd_pcm_hw_params_set_rate(a->pcm, params, si->samplerate, 0); if (err < 0) { gensio_log(o, GENSIO_LOG_ERR, "alsa error from snd_pcm_hw_params_set_rate: %s\n", snd_strerror(err)); goto out_err; } frsize = si->bufsize * si->num_bufs; err = snd_pcm_hw_params_set_buffer_size_near(a->pcm, params, &frsize); if (err < 0) { gensio_log(o, GENSIO_LOG_ERR, "alsa error from snd_pcm_hw_params_set_buffer_size_max: %s\n", snd_strerror(err)); goto out_err; } /* * The below seems to be necessary to set arbitrary rates. It was * ifdef-ed out, but rate setting wasn't always working. */ { /* Period time, in usecs. Do u64 arithmetic to avoid overflow. */ uint64_t lperiod_time = (si->bufsize * 1000000ULL) / si->samplerate; unsigned int period_time = lperiod_time; int dir; err = snd_pcm_hw_params_set_period_time_near(a->pcm, params, &period_time, &dir); if (err < 0) { gensio_log(o, GENSIO_LOG_ERR, "alsa error from snd_pcm_hw_params_ser_period_time_near: %s\n", snd_strerror(err)); goto out_err; } } /* write the parameters to device */ err = snd_pcm_hw_params(a->pcm, params); if (err < 0) { gensio_log(o, GENSIO_LOG_ERR, "alsa error from snd_pcm_hw_params: %s\n", snd_strerror(err)); goto out_err; } return 0; out_err: return GE_OSERR; } static int gensio_sound_alsa_set_swparams(struct sound_info *si) { struct gensio_os_funcs *o = si->soundll->o; struct alsa_info *a = si->pinfo; snd_pcm_sw_params_t *params; int err; snd_pcm_sw_params_alloca(¶ms); /* get the current swparams */ err = snd_pcm_sw_params_current(a->pcm, params); if (err < 0) { gensio_log(o, GENSIO_LOG_ERR, "alsa error from snd_pcm_sw_params_current: %s\n", snd_strerror(err)); goto out_err; } /* start the transfer when a buffer is written: */ err = snd_pcm_sw_params_set_start_threshold(a->pcm, params, si->bufsize); if (err < 0) { gensio_log(o, GENSIO_LOG_ERR, "alsa error from snd_pcm_sw_params_set_start_threshold: %s\n", snd_strerror(err)); goto out_err; } /* * Allow the transfer when at least period_size ont buffer can be * processed. */ err = snd_pcm_sw_params_set_avail_min(a->pcm, params, si->bufsize); if (err < 0) { gensio_log(o, GENSIO_LOG_ERR, "alsa error from snd_pcm_sw_params_set_avail_min: %s\n", snd_strerror(err)); goto out_err; } #if 0 err = snd_pcm_sw_params_set_period_event(a->pcm, params, 1); if (err < 0) { gensio_log(o, GENSIO_LOG_ERR, "alsa error from snd_pcm_sw_params_set_period_event: %s\n", snd_strerror(err)); goto out_err; } #endif err = snd_pcm_sw_params(a->pcm, params); if (err < 0) { gensio_log(o, GENSIO_LOG_ERR, "alsa error from snd_pcm_sw_params: %s\n", snd_strerror(err)); goto out_err; } return 0; out_err: return GE_OSERR; } static bool gensio_sound_alsa_check_xrun_recovery(struct sound_info *si, int rv) { struct alsa_info *a = si->pinfo; snd_pcm_state_t state = snd_pcm_state(a->pcm); switch (state) { case SND_PCM_STATE_XRUN: rv = snd_pcm_prepare(a->pcm); if (rv == 0) return true; return rv; case SND_PCM_STATE_SUSPENDED: rv = snd_pcm_resume(a->pcm); if (rv == -EAGAIN) return false; if (rv < 0) rv = snd_pcm_prepare(a->pcm); if (rv == 0) return true; break; default: break; } if (rv) { gensio_log(si->soundll->o, GENSIO_LOG_ERR, "alsa error from xrun_recovery: %s\n", snd_strerror(rv)); si->soundll->err = GE_OSERR; gensio_sound_sched_deferred_op(si->soundll); } return false; } static void gensio_sound_alsa_do_read(struct sound_info *si) { struct alsa_info *a = si->pinfo; struct sound_ll *soundll = si->soundll; int rv; gensio_sound_alsa_check_xrun_recovery(si, 0); if (soundll->err) return; if (si->cnv.enabled) { rv = snd_pcm_readi(a->pcm, si->cnv.buf + (si->len * si->cnv.pframesize), si->bufsize - si->len); } else { rv = snd_pcm_readi(a->pcm, si->buf + (si->len * si->framesize), si->bufsize - si->len); } if (rv < 0) { if (rv == -EAGAIN || rv == -EBUSY) return; gensio_sound_alsa_check_xrun_recovery(si, rv); } else { si->len += rv; assert(si->len <= si->bufsize); if (si->len == si->bufsize) { if (si->cnv.enabled) { const unsigned char *ibuf = si->cnv.buf; unsigned char *obuf = si->buf; gensiods i; for (i = 0; i < si->bufsize * si->chans; i++) si->cnv.convin(&ibuf, &obuf, &si->cnv); } si->ready = true; } } } static void gensio_sound_alsa_api_set_read(struct sound_info *si, bool enable) { struct gensio_os_funcs *o = si->soundll->o; struct alsa_info *a = si->pinfo; unsigned int i; for (i = 0; i < a->nrfds; i++) { if (a->fds[i].events & POLLIN) o->set_read_handler(a->iods[i], enable); if (a->fds[i].events & POLLOUT) o->set_write_handler(a->iods[i], enable); if (a->fds[i].events & POLLERR) o->set_except_handler(a->iods[i], enable); } if (enable && !si->ready) gensio_sound_alsa_do_read(si); } static void gensio_sound_alsa_api_set_write(struct sound_info *si, bool enable) { struct gensio_os_funcs *o = si->soundll->o; struct alsa_info *a = si->pinfo; unsigned int i; for (i = 0; i < a->nrfds; i++) { if (a->fds[i].events & POLLIN) o->set_read_handler(a->iods[i], enable); if (a->fds[i].events & POLLOUT) o->set_write_handler(a->iods[i], enable); if (a->fds[i].events & POLLERR) o->set_except_handler(a->iods[i], enable); } } static void gensio_sound_alsa_read_handlerb(struct gensio_iod *iod, void *cb_data, unsigned short ievents) { struct sound_info *si = cb_data; struct alsa_info *a = si->pinfo; struct sound_ll *soundll = si->soundll; unsigned int i; unsigned short revents; gensio_sound_ll_lock(soundll); for (i = 0; i < a->nrfds; i++) a->fds[i].revents = ievents; revents = 0; snd_pcm_poll_descriptors_revents(a->pcm, a->fds, a->nrfds, &revents); if (revents & (POLLERR | POLLIN | POLLOUT)) { restart: if (soundll->in.ready || soundll->err) gensio_sound_ll_check_read(soundll); if (!soundll->in.ready && !soundll->err) { gensio_sound_alsa_do_read(&soundll->in); if (soundll->in.ready || soundll->err) goto restart; } } gensio_sound_ll_unlock(soundll); } static void gensio_sound_alsa_read_handler(struct gensio_iod *iod, void *cb_data) { gensio_sound_alsa_read_handlerb(iod, cb_data, POLLIN); } static void gensio_sound_alsa_read_write_handler(struct gensio_iod *iod, void *cb_data) { gensio_sound_alsa_read_handlerb(iod, cb_data, POLLOUT); } static void gensio_sound_alsa_read_exc_handler(struct gensio_iod *iod, void *cb_data) { gensio_sound_alsa_read_handlerb(iod, cb_data, POLLERR); } static void gensio_sound_alsa_write_handlerb(struct gensio_iod *iod, void *cb_data, unsigned short ievents) { struct sound_info *si = cb_data; struct alsa_info *a = si->pinfo; struct sound_ll *soundll = si->soundll; unsigned int i; unsigned short revents; gensio_sound_ll_lock(soundll); for (i = 0; i < a->nrfds; i++) a->fds[i].revents = ievents; revents = 0; snd_pcm_poll_descriptors_revents(a->pcm, a->fds, a->nrfds, &revents); /* For some weird reason we get POLLIN on the output device. */ if (revents & (POLLERR | POLLOUT | POLLIN)) { si->ready = true; gensio_sound_ll_check_write(soundll); } gensio_sound_ll_unlock(soundll); } static void gensio_sound_alsa_write_handler(struct gensio_iod *iod, void *cb_data) { gensio_sound_alsa_write_handlerb(iod, cb_data, POLLOUT); } static void gensio_sound_alsa_write_read_handler(struct gensio_iod *iod, void *cb_data) { gensio_sound_alsa_write_handlerb(iod, cb_data, POLLIN); } static void gensio_sound_alsa_write_exc_handler(struct gensio_iod *iod, void *cb_data) { gensio_sound_alsa_write_handlerb(iod, cb_data, POLLERR); } static void gensio_sound_alsa_cleared_handler(struct gensio_iod *iod, void *cb_data) { struct sound_info *si = cb_data; struct sound_ll *soundll = si->soundll; gensio_sound_ll_lock(soundll); soundll->nr_waiting_close--; if (soundll->nr_waiting_close == 0) { soundll->do_close_now = true; gensio_sound_sched_deferred_op(soundll); } gensio_sound_ll_unlock(soundll); } static void gensio_sound_alsa_timeout(struct gensio_timer *t, void *cb_data) { struct sound_info *si = cb_data; struct alsa_info *a = si->pinfo; unsigned int i; for (i = 0; i < a->nrfds; i++) si->soundll->o->clear_fd_handlers(a->iods[i]); } static unsigned long gensio_sound_alsa_drain_count(struct sound_info *si) { struct alsa_info *a = si->pinfo; snd_pcm_sframes_t frames_left; snd_pcm_delay(a->pcm, &frames_left); return frames_left; } static unsigned int gensio_sound_alsa_api_start_close(struct sound_info *si) { struct gensio_os_funcs *o = si->soundll->o; struct alsa_info *a = si->pinfo; gensio_time timeout; snd_pcm_sframes_t frames_left = 0; uint64_t drain_time; if (!si->is_input && a->nrfds > 0) { /* Wait for output to drain. */ snd_pcm_delay(a->pcm, &frames_left); drain_time = frames_left * GENSIO_NSECS_IN_SEC / si->samplerate; timeout.secs = drain_time / GENSIO_NSECS_IN_SEC; timeout.nsecs = drain_time % GENSIO_NSECS_IN_SEC; assert(o->start_timer(a->close_timer, &timeout) == 0); } else if (a->nrfds > 0) { gensio_sound_alsa_timeout(NULL, si); } return a->nrfds; } static int gensio_sound_alsa_api_write(struct sound_info *out, const unsigned char *buf, gensiods buflen, gensiods *nr_written) { struct alsa_info *a = out->pinfo; snd_pcm_sframes_t rv; retry: rv = snd_pcm_writei(a->pcm, buf, buflen); if (rv < 0) { if (rv == -EBUSY || rv == -EAGAIN) { out->ready = false; *nr_written = 0; return 0; } if (gensio_sound_alsa_check_xrun_recovery(out, rv)) goto retry; return out->soundll->err; } else { *nr_written = rv; } return 0; } static int gensio_sound_alsa_api_open_dev(struct sound_info *si) { struct gensio_os_funcs *o = si->soundll->o; struct alsa_info *a = si->pinfo; int err; unsigned int i; snd_pcm_stream_t stype = (si->is_input ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK); err = snd_pcm_open(&a->pcm, si->devname, stype, SND_PCM_NONBLOCK); if (err < 0) { gensio_log(o, GENSIO_LOG_ERR, "alsa error from snd_pcm_open: %s", snd_strerror(err)); return GE_OSERR; } err = gensio_sound_alsa_set_hwparams(si); if (err) { gensio_sound_alsa_api_close_dev(si); return err; } err = gensio_sound_alsa_set_swparams(si); if (err) { gensio_sound_alsa_api_close_dev(si); return err; } a->nrfds = snd_pcm_poll_descriptors_count(a->pcm); if (a->nrfds == 0) { gensio_sound_alsa_api_close_dev(si); return GE_INCONSISTENT; } a->fds = o->zalloc(o, a->nrfds * sizeof(struct pollfd)); if (!a->fds) { gensio_sound_alsa_api_close_dev(si); return GE_NOMEM; } a->iods = o->zalloc(o, a->nrfds * sizeof(struct gensio_iod *)); if (!a->iods) { gensio_sound_alsa_api_close_dev(si); return GE_NOMEM; } err = snd_pcm_poll_descriptors(a->pcm, a->fds, a->nrfds); if (err < 0) { gensio_log(o, GENSIO_LOG_ERR, "alsa error from snd_pcm_poll_descriptors: %s", snd_strerror(err)); gensio_sound_alsa_api_close_dev(si); return GE_OSERR; } for (i = 0; i < a->nrfds; i++) { err = o->add_iod(o, GENSIO_IOD_PIPE, a->fds[i].fd, &(a->iods[i])); if (err) { gensio_sound_alsa_api_close_dev(si); return err; } err = o->set_fd_handlers(a->iods[i], si, (stype == SND_PCM_STREAM_CAPTURE ? gensio_sound_alsa_read_handler : gensio_sound_alsa_write_read_handler), (stype == SND_PCM_STREAM_PLAYBACK ? gensio_sound_alsa_write_handler : gensio_sound_alsa_read_write_handler), (stype == SND_PCM_STREAM_CAPTURE ? gensio_sound_alsa_read_exc_handler : gensio_sound_alsa_write_exc_handler), gensio_sound_alsa_cleared_handler); if (err) { gensio_sound_alsa_api_close_dev(si); return err; } } return 0; } static int gensio_sound_alsa_api_devices(struct gensio_os_funcs *o, char ***rnames, char ***rspecs, gensiods *rcount) { void **hints, **n; gensiods count = 0, size = 0; char **names = NULL, **specs = NULL; if (snd_device_name_hint(-1, "pcm", &hints) < 0) { *rcount = 0; return 0; } for (n = hints; *n != NULL; n++) { char *name, *desc, *io; unsigned int i, j, len; name = snd_device_name_get_hint(*n, "NAME"); if (!name) continue; desc = snd_device_name_get_hint(*n, "DESC"); if (desc) { char *n2; len = strlen(name) + strlen(desc); for (i = 0; desc[i]; i++) { if (desc[i] == '\n') len += 4; } n2 = malloc(len + 7); /* extra for nil and "\n " */ if (!n2) { free(name); free(desc); goto out_nomem; } strncpy(n2, name, len + 6); i = strlen(n2); strncpy(n2 + i, "\n ", 6); i += 5; for (j = 0; desc[j]; j++) { if (desc[j] == '\n') { strncpy(n2 + i, "\n ", 6); i += 5; } else { n2[i++] = desc[j]; } } n2[i++] = '\n'; n2[i++] = '\0'; free(name); free(desc); name = n2; } io = snd_device_name_get_hint(*n, "IOID"); if (io) { io[0] = tolower(io[0]); } else { io = strdup("input,output"); if (!io) { free(name); goto out_nomem; } } if (count >= size) { if (extend_sound_devs(&names, &specs, &size)) { free(name); free(io); goto out_nomem; } } names[count] = name; name = NULL; specs[count] = io; count++; } snd_device_name_free_hint(hints); *rnames = names; *rspecs = specs; *rcount = count; return 0; out_nomem: snd_device_name_free_hint(hints); gensio_sound_devices_free(names, specs, count); return GE_NOMEM; } static void gensio_sound_alsa_cleanup_func(void) { snd_config_update_free_global(); } static struct gensio_class_cleanup gensio_sound_alsa_class_cleanup = { /* * If you don't call this, lots of cached information gets left * lying around in the alsa code and valgrind complains. */ .cleanup = gensio_sound_alsa_cleanup_func }; static int gensio_sound_alsa_api_setup(struct gensio_pparm_info *p, struct sound_info *si, struct gensio_sound_info *io) { struct gensio_os_funcs *o = si->soundll->o; struct alsa_info *a; char *start, *end; unsigned int len; /* * Extract the card name/number (the value after the ":" and * before the ","), like in "plughw:1,0". */ start = strchr(io->devname, ':'); if (!start) { gensio_pparm_log(p, "devname %s has no ':' in it", io->devname); return GE_INVAL; } start++; end = strchr(start, ','); if (!end) len = strlen(start); else len = end - start; si->cardname = gensio_strndup(o, start, len); if (!si->cardname) return GE_NOMEM; gensio_register_class_cleanup(&gensio_sound_alsa_class_cleanup); si->pinfo = o->zalloc(o, sizeof(struct alsa_info)); if (!si->pinfo) { o->free(o, si->cardname); si->cardname = NULL; return GE_NOMEM; } a = si->pinfo; a->close_timer = o->alloc_timer(o, gensio_sound_alsa_timeout, si); if (!a->close_timer) { o->free(o, si->pinfo); si->pinfo = NULL; o->free(o, si->cardname); si->cardname = NULL; return GE_NOMEM; } return 0; } static void gensio_sound_alsa_api_cleanup(struct sound_info *si) { struct gensio_os_funcs *o = si->soundll->o; struct alsa_info *a = si->pinfo; if (a) { if (a->close_timer) o->free_timer(a->close_timer); o->free(o, a); si->pinfo = NULL; } } static struct sound_type alsa_sound_type = { "alsa", .setup = gensio_sound_alsa_api_setup, .cleanup = gensio_sound_alsa_api_cleanup, .open_dev = gensio_sound_alsa_api_open_dev, .close_dev = gensio_sound_alsa_api_close_dev, .sub_write = gensio_sound_alsa_api_write, .write = gensio_sound_api_default_write, .set_write_enable = gensio_sound_alsa_api_set_write, .set_read_enable = gensio_sound_alsa_api_set_read, .start_close = gensio_sound_alsa_api_start_close, .drain_count = gensio_sound_alsa_drain_count, .devices = gensio_sound_alsa_api_devices }; #define ALSA_INIT &alsa_sound_type, gensio-3.0.0/lib/net_ax25_addr.c0000664000175000017500000002261214747451760012034 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2021 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include bool ax25_subaddr_equal(const struct gensio_ax25_subaddr *a1, const struct gensio_ax25_subaddr *a2) { if (strcmp(a1->addr, a2->addr) != 0) return false; if (a1->ssid != a2->ssid) return false; return true; } static bool ax25_addr_equal(const struct gensio_addr *ia1, const struct gensio_addr *ia2, bool compare_ports, bool compare_all) { struct gensio_ax25_addr *a1 = addr_to_ax25(ia1), *a2 = addr_to_ax25(ia2); unsigned int i; if (compare_ports && a1->tnc_port != a2->tnc_port) return false; if (!ax25_subaddr_equal(&a1->dest, &a2->dest)) return false; if (!ax25_subaddr_equal(&a1->src, &a2->src)) return false; if (!compare_all) return true; if (a1->nr_extra != a2->nr_extra) return false; for (i = 0; i < a1->nr_extra; i++) { if (strcmp(a1->extra[i].addr, a2->extra[i].addr) != 0) return false; if (a1->extra[i].ssid != a2->extra[i].ssid) return false; } return true; } int ax25_subaddr_to_str(const struct gensio_ax25_subaddr *a, char *buf, gensiods *pos, gensiods buflen, bool do_cr) { if (a->ssid) gensio_pos_snprintf(buf, buflen, pos, "%s-%d", a->addr, a->ssid); else gensio_pos_snprintf(buf, buflen, pos, "%s", a->addr); if (do_cr) gensio_pos_snprintf(buf, buflen, pos, ":%c", a->ch ? 'c' : 'r'); return 0; } static int ax25_addr_to_str(const struct gensio_addr *addr, char *buf, gensiods *pos, gensiods buflen) { struct gensio_ax25_addr *a = addr_to_ax25(addr); unsigned int i; gensio_pos_snprintf(buf, buflen, pos, "ax25:%d,", a->tnc_port); ax25_subaddr_to_str(&a->dest, buf, pos, buflen, false); gensio_pos_snprintf(buf, buflen, pos, ","); ax25_subaddr_to_str(&a->src, buf, pos, buflen, false); for (i = 0; i < a->nr_extra; i++) { gensio_pos_snprintf(buf, buflen, pos, ","); ax25_subaddr_to_str(&a->extra[i], buf, pos, buflen, false); if (a->extra[i].ch) gensio_pos_snprintf(buf, buflen, pos, ":h"); } return 0; } static struct gensio_addr * ax25_addr_dup(const struct gensio_addr *iaddr) { struct gensio_ax25_addr *a = addr_to_ax25(iaddr), *ra; ra = a->o->zalloc(a->o, sizeof(*ra)); if (!ra) return NULL; memcpy(ra, a, sizeof(*ra)); return &ra->r; } static struct gensio_addr * ax25_addr_cat(const struct gensio_addr *addr1, const struct gensio_addr *addr2) { return NULL; } static bool ax25_addr_addr_present(const struct gensio_addr *gai, const void *addr, gensiods addrlen, bool compare_ports) { /* FIXME ? */ return false; } static void ax25_addr_free(struct gensio_addr *addr) { struct gensio_ax25_addr *a = addr_to_ax25(addr); a->o->free(a->o, a); } static bool ax25_addr_next(struct gensio_addr *addr) { return false; } static void ax25_addr_rewind(struct gensio_addr *addr) { } static int ax25_addr_get_nettype(const struct gensio_addr *addr) { return GENSIO_NETTYPE_AX25; } static bool ax25_addr_family_supports(const struct gensio_addr *addr, int family, int flags) { return family == GENSIO_NETTYPE_AX25; } static void ax25_addr_getaddr(const struct gensio_addr *addr, void *oaddr, gensiods *rlen) { gensiods len = *rlen; if (len > sizeof(struct gensio_ax25_addr)) len = sizeof(struct gensio_ax25_addr); memcpy(oaddr, addr, len); *rlen = sizeof(struct gensio_ax25_addr); } const static struct gensio_addr_funcs ax25_addr_funcs = { .addr_equal = ax25_addr_equal, .addr_to_str = ax25_addr_to_str, .addr_to_str_all = ax25_addr_to_str, .addr_dup = ax25_addr_dup, .addr_cat = ax25_addr_cat, .addr_addr_present = ax25_addr_addr_present, .addr_free = ax25_addr_free, .addr_next = ax25_addr_next, .addr_rewind = ax25_addr_rewind, .addr_get_nettype = ax25_addr_get_nettype, .addr_family_supports = ax25_addr_family_supports, .addr_getaddr = ax25_addr_getaddr }; int ax25_str_to_subaddr(const char *s, struct gensio_ax25_subaddr *a, bool is_cr) { unsigned int i, j; char *end; if (!*s) /* Reject empty strings. */ return GE_INVAL; for (i = 0; i < 6; i++) { if (!s[i]) break; else if (isupper(s[i]) || isdigit(s[i])) a->addr[i] = s[i]; else if (islower(s[i])) a->addr[i] = toupper(s[i]); else if (s[i] == '-') break; else return GE_INVAL; } if (s[i] == '\0') { a->ssid = 0; return 0; } if (s[i] != '-') return GE_INVAL; for (j = i; j < 6; j++) a->addr[j] = '\0'; a->addr[j] = '\0'; a->ch = 0; i++; j = strtoul(s + i, &end, 10); if (*end == ':') { if (!is_cr && strcmp(end, ":h") == 0) a->ch = 1; else return GE_INVAL; } else if (*end != '\0') { return GE_INVAL; } if (j >= 16) return GE_INVAL; a->ssid = j; a->r1 = 1; a->r2 = 1; a->r3 = 1; return 0; } int gensio_ax25_addr_alloc(struct gensio_os_funcs *o, uint8_t tnc_port, const char *dest, const char *src, uint8_t nr_extra, const char *extras[], struct gensio_addr **raddr) { struct gensio_ax25_addr *a; unsigned int i; int rv; if (nr_extra > GENSIO_AX25_ADDR_MAX_EXTRA) return GE_INVAL; a = o->zalloc(o, sizeof(*a)); if (!a) return GE_NOMEM; a->o = o; a->r.funcs = &ax25_addr_funcs; rv = ax25_str_to_subaddr(dest, &a->dest, true); if (rv) goto out_err; rv = ax25_str_to_subaddr(src, &a->src, true); if (rv) goto out_err; for (i = 0; i < nr_extra; i++) { rv = ax25_str_to_subaddr(extras[i], &(a->extra[i]), false); if (rv) goto out_err; } a->nr_extra = nr_extra; *raddr = &a->r; return 0; out_err: o->free(o, a); return rv; } int gensio_ax25_str_to_addr(struct gensio_os_funcs *o, const char *instr, struct gensio_addr **raddr) { char *s, *dest, *src, *end; const char*extras[GENSIO_AX25_ADDR_MAX_EXTRA + 1]; uint8_t tnc_port; unsigned int i; int rv; if (strncmp(instr, "ax25:", 5) == 0) instr += 5; if (!isdigit(*instr)) /* Must be a number to start. */ return GE_INVAL; tnc_port = strtoul(instr, &end, 10); if (*end != ',') return GE_INVAL; s = gensio_strdup(o, end + 1); if (!s) return GE_NOMEM; dest = s; src = strchr(dest, ','); if (!src) goto out_inval; *src++ = '\0'; end = strchr(src, ','); for (i = 0; end && i < GENSIO_AX25_ADDR_MAX_EXTRA; i++) { *end++ = '\0'; extras[i] = end; end = strchr(extras[i], ','); } if (end) /* Too many extra fields. */ goto out_inval; rv = gensio_ax25_addr_alloc(o, tnc_port, dest, src, i, extras, raddr); o->free(o, s); return rv; out_inval: o->free(o, s); return GE_INVAL; } static int decode_ax25_subaddr(unsigned char *data, gensiods *ipos, gensiods len, struct gensio_ax25_subaddr *addr) { gensiods pos = *ipos; unsigned int i; if (len - *ipos < 7) return GE_INVAL; memset(addr, 0, sizeof(*addr)); for (i = 0; i < 6; i++) { if (data[i + pos] & 1) return GE_INVAL; addr->addr[i] = data[i + pos] >> 1; if (addr->addr[i] == ' ') /* Spaces are at the end and not used. */ addr->addr[i] = '\0'; } addr->ssid = (data[i + pos] >> 1) & 0xf; addr->ch = (data[i + pos] >> 7) & 1; addr->r1 = (data[i + pos] >> 5) & 1; addr->r2 = (data[i + pos] >> 6) & 1; addr->r3 = 1; *ipos += 7; if (data[i + pos] & 1) return GE_REMCLOSE; return 0; } int decode_ax25_addr(struct gensio_os_funcs *o, unsigned char *data, gensiods *ipos, gensiods len, uint16_t tnc_port, struct gensio_ax25_addr *addr) { int rv; addr->tnc_port = tnc_port; addr->r.funcs = &ax25_addr_funcs; addr->o = o; rv = decode_ax25_subaddr(data, ipos, len, &addr->dest); if (rv) return rv; rv = decode_ax25_subaddr(data, ipos, len, &addr->src); addr->nr_extra = 0; if (rv == GE_REMCLOSE) return 0; if (rv) return rv; do { if (addr->nr_extra >= GENSIO_AX25_ADDR_MAX_EXTRA) return GE_INVAL; rv = decode_ax25_subaddr(data, ipos, len, &(addr->extra[addr->nr_extra])); if (rv == GE_INVAL) return rv; addr->nr_extra++; } while (rv == 0); return 0; } unsigned int ax25_addr_encode_len(struct gensio_addr *iaddr) { struct gensio_ax25_addr *addr = addr_to_ax25(iaddr); assert(addr->nr_extra <= GENSIO_AX25_ADDR_MAX_EXTRA); return 7 * (2 + addr->nr_extra); } static void encode_ax25_subaddr(unsigned char *data, struct gensio_ax25_subaddr *addr) { unsigned int i; for (i = 0; i < 6; i++) { if (!addr->addr[i]) break; data[i] = addr->addr[i] << 1; } for (; i < 6; i++) /* Fill the end with spaces. */ data[i] = ' ' << 1; data[i] = (addr->ssid << 1) | addr->ch << 7; } unsigned int ax25_addr_encode(unsigned char *buf, struct gensio_addr *iaddr) { struct gensio_ax25_addr *addr = addr_to_ax25(iaddr); unsigned int len, i; assert(addr->r.funcs == &ax25_addr_funcs); assert(addr->nr_extra <= GENSIO_AX25_ADDR_MAX_EXTRA); encode_ax25_subaddr(buf, &addr->dest); encode_ax25_subaddr(buf + 7, &addr->src); len = 14; for (i = 0; i < addr->nr_extra; i++) { encode_ax25_subaddr(buf + len, &addr->extra[i]); len += 7; } buf[len - 1] |= 1; /* Mark the end of the address. */ return len; } gensio-3.0.0/lib/net_addr.c0000664000175000017500000000531014747451760011171 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include int gensio_addr_create(struct gensio_os_funcs *o, int nettype, const void *iaddr, gensiods len, unsigned int port, struct gensio_addr **newaddr) { return o->addr_create(o, nettype, iaddr, len, port, newaddr); } bool gensio_addr_equal(const struct gensio_addr *a1, const struct gensio_addr *a2, bool compare_ports, bool compare_all) { if (a1->funcs != a2->funcs) return false; return a1->funcs->addr_equal(a1, a2, compare_ports, compare_all); } int gensio_addr_to_str(const struct gensio_addr *addr, char *buf, gensiods *pos, gensiods buflen) { gensiods dummypos = 0; if (!pos) pos = &dummypos; return addr->funcs->addr_to_str(addr, buf, pos, buflen); } int gensio_addr_to_str_all(const struct gensio_addr *addr, char *buf, gensiods *pos, gensiods buflen) { return addr->funcs->addr_to_str_all(addr, buf, pos, buflen); } struct gensio_addr * gensio_addr_dup(const struct gensio_addr *iaddr) { return iaddr->funcs->addr_dup(iaddr); } struct gensio_addr * gensio_addr_cat(const struct gensio_addr *addr1, const struct gensio_addr *addr2) { if (addr1->funcs != addr2->funcs) return NULL; return addr1->funcs->addr_cat(addr1, addr2); } bool gensio_addr_addr_present(const struct gensio_addr *gai, const void *addr, gensiods addrlen, bool compare_ports) { return gai->funcs->addr_addr_present(gai, addr, addrlen, compare_ports); } void gensio_addr_free(struct gensio_addr *addr) { addr->funcs->addr_free(addr); } bool gensio_addr_next(struct gensio_addr *addr) { return addr->funcs->addr_next(addr); } void gensio_addr_rewind(struct gensio_addr *addr) { addr->funcs->addr_rewind(addr); } int gensio_addr_get_nettype(const struct gensio_addr *addr) { return addr->funcs->addr_get_nettype(addr); } int gensio_addr_get_port(const struct gensio_addr *addr) { if (!addr->funcs->addr_get_port) return -1; return addr->funcs->addr_get_port(addr); } void gensio_addr_get_data(const struct gensio_addr *addr, void *oaddr, gensiods *rlen) { if (!addr->funcs->addr_get_data) addr->funcs->addr_getaddr(addr, oaddr, rlen); addr->funcs->addr_get_data(addr, oaddr, rlen); } bool gensio_addr_family_supports(const struct gensio_addr *addr, int family, int flags) { return addr->funcs->addr_family_supports(addr, family, flags); } void gensio_addr_getaddr(const struct gensio_addr *addr, void *oaddr, gensiods *rlen) { addr->funcs->addr_getaddr(addr, oaddr, rlen); } gensio-3.0.0/lib/gensio_echo.c0000664000175000017500000002525014664224267011676 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* This code is for a gensio that echos all writes back to read. */ #include #include #include #include "config.h" #include #include #include #include #include enum echon_state { ECHON_CLOSED, ECHON_IN_OPEN, ECHON_OPEN, ECHON_IN_OPEN_CLOSE, ECHON_IN_CLOSE, }; struct echon_data { struct gensio_os_funcs *o; struct gensio_lock *lock; unsigned int refcount; enum echon_state state; struct gensio *io; bool noecho; bool justdata; struct gensio_circbuf *buf; bool read_enabled; bool xmit_enabled; gensio_done_err open_done; void *open_data; gensio_done close_done; void *close_data; /* * Used to run read callbacks from the selector to avoid running * it directly from user calls. */ bool deferred_op_pending; struct gensio_runner *deferred_op_runner; }; static void echon_start_deferred_op(struct echon_data *ndata); static void echon_finish_free(struct echon_data *ndata) { struct gensio_os_funcs *o = ndata->o; if (ndata->io) gensio_data_free(ndata->io); if (ndata->buf) gensio_circbuf_free(ndata->buf); if (ndata->deferred_op_runner) o->free_runner(ndata->deferred_op_runner); if (ndata->lock) o->free_lock(ndata->lock); o->free(o, ndata); } static void echon_lock(struct echon_data *ndata) { ndata->o->lock(ndata->lock); } static void echon_unlock(struct echon_data *ndata) { ndata->o->unlock(ndata->lock); } static void echon_ref(struct echon_data *ndata) { assert(ndata->refcount > 0); ndata->refcount++; } static void echon_unlock_and_deref(struct echon_data *ndata) { assert(ndata->refcount > 0); if (ndata->refcount == 1) { echon_unlock(ndata); echon_finish_free(ndata); } else { ndata->refcount--; echon_unlock(ndata); } } static int echon_write(struct gensio *io, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen) { struct echon_data *ndata = gensio_get_gensio_data(io); gensiods i, count = 0; echon_lock(ndata); if (ndata->state != ECHON_OPEN) { echon_unlock(ndata); return GE_NOTREADY; } if (ndata->noecho) { for (i = 0; i < sglen; i++) count += sg[i].buflen; if (rcount) *rcount = count; echon_unlock(ndata); return 0; } gensio_circbuf_sg_write(ndata->buf, sg, sglen, &count); if (count) echon_start_deferred_op(ndata); echon_unlock(ndata); if (rcount) *rcount = count; return 0; } static void echon_deferred_op(struct gensio_runner *runner, void *cb_data) { struct echon_data *ndata = cb_data; int err = 0; echon_lock(ndata); restart: if (ndata->state == ECHON_IN_OPEN || ndata->state == ECHON_IN_OPEN_CLOSE) { if (ndata->state == ECHON_IN_OPEN_CLOSE) { ndata->state = ECHON_IN_CLOSE; err = GE_LOCALCLOSED; } else { ndata->state = ECHON_OPEN; } if (ndata->open_done) { echon_unlock(ndata); ndata->open_done(ndata->io, err, ndata->open_data); echon_lock(ndata); } } more_read: while (ndata->state == ECHON_OPEN && (gensio_circbuf_datalen(ndata->buf) > 0 || ndata->justdata) && ndata->read_enabled) { void *data; gensiods count; if (gensio_circbuf_datalen(ndata->buf) == 0) { ndata->read_enabled = false; echon_unlock(ndata); gensio_cb(ndata->io, GENSIO_EVENT_READ, GE_REMCLOSE, NULL, NULL, NULL); echon_lock(ndata); } else { gensio_circbuf_next_read_area(ndata->buf, &data, &count); echon_unlock(ndata); err = gensio_cb(ndata->io, GENSIO_EVENT_READ, 0, data, &count, NULL); echon_lock(ndata); if (err) break; gensio_circbuf_data_removed(ndata->buf, count); } } while (ndata->state == ECHON_OPEN && gensio_circbuf_room_left(ndata->buf) > 0 && ndata->xmit_enabled) { echon_unlock(ndata); err = gensio_cb(ndata->io, GENSIO_EVENT_WRITE_READY, 0, NULL, NULL, NULL); echon_lock(ndata); if (err) break; } if (!err && ndata->state == ECHON_OPEN && gensio_circbuf_datalen(ndata->buf) > 0 && ndata->read_enabled) goto more_read; if (ndata->state == ECHON_IN_CLOSE) { ndata->state = ECHON_CLOSED; if (ndata->close_done) { echon_unlock(ndata); ndata->close_done(ndata->io, ndata->close_data); echon_lock(ndata); } if (ndata->state != ECHON_CLOSED) goto restart; } ndata->deferred_op_pending = false; echon_unlock_and_deref(ndata); } static void echon_start_deferred_op(struct echon_data *ndata) { if (!ndata->deferred_op_pending) { /* Call the read from the selector to avoid lock nesting issues. */ ndata->deferred_op_pending = true; ndata->o->run(ndata->deferred_op_runner); echon_ref(ndata); } } static void echon_set_read_callback_enable(struct gensio *io, bool enabled) { struct echon_data *ndata = gensio_get_gensio_data(io); echon_lock(ndata); ndata->read_enabled = enabled; if (enabled && ndata->state == ECHON_OPEN && (gensio_circbuf_datalen(ndata->buf) > 0 || ndata->justdata)) echon_start_deferred_op(ndata); echon_unlock(ndata); } static void echon_set_write_callback_enable(struct gensio *io, bool enabled) { struct echon_data *ndata = gensio_get_gensio_data(io); echon_lock(ndata); ndata->xmit_enabled = enabled; if (enabled && ndata->state == ECHON_OPEN && gensio_circbuf_room_left(ndata->buf) > 0) echon_start_deferred_op(ndata); echon_unlock(ndata); } static int echon_open(struct gensio *io, gensio_done_err open_done, void *open_data) { struct echon_data *ndata = gensio_get_gensio_data(io); int err = 0; echon_lock(ndata); if (ndata->state != ECHON_CLOSED) { err = GE_NOTREADY; goto out_unlock; } ndata->state = ECHON_IN_OPEN; ndata->open_done = open_done; ndata->open_data = open_data; echon_start_deferred_op(ndata); out_unlock: echon_unlock(ndata); return err; } static int echon_close(struct gensio *io, gensio_done close_done, void *close_data) { struct echon_data *ndata = gensio_get_gensio_data(io); int err = 0; echon_lock(ndata); if (ndata->state != ECHON_OPEN && ndata->state != ECHON_IN_OPEN) { err = GE_NOTREADY; goto out_unlock; } if (ndata->state == ECHON_IN_OPEN) ndata->state = ECHON_IN_OPEN_CLOSE; else ndata->state = ECHON_IN_CLOSE; ndata->close_done = close_done; ndata->close_data = close_data; echon_start_deferred_op(ndata); out_unlock: echon_unlock(ndata); return err; } static void echon_free(struct gensio *io) { struct echon_data *ndata = gensio_get_gensio_data(io); echon_lock(ndata); ndata->state = ECHON_CLOSED; echon_unlock_and_deref(ndata); } static int echon_disable(struct gensio *io) { struct echon_data *ndata = gensio_get_gensio_data(io); echon_lock(ndata); ndata->state = ECHON_CLOSED; echon_unlock(ndata); return 0; } static int echon_control(struct gensio *io, bool get, int option, char *data, gensiods *datalen) { if (option != GENSIO_CONTROL_RADDR) return GE_NOTSUP; if (!get) return GE_NOTSUP; if (strtoul(data, NULL, 0) > 0) return GE_NOTFOUND; *datalen = gensio_pos_snprintf(data, *datalen, NULL, "echo"); return 0; } static int gensio_echo_func(struct gensio *io, int func, gensiods *count, const void *cbuf, gensiods buflen, void *buf, const char *const *auxdata) { switch (func) { case GENSIO_FUNC_WRITE_SG: return echon_write(io, count, cbuf, buflen); case GENSIO_FUNC_OPEN: return echon_open(io, (void *) cbuf, buf); case GENSIO_FUNC_CLOSE: return echon_close(io, (void *) cbuf, buf); case GENSIO_FUNC_FREE: echon_free(io); return 0; case GENSIO_FUNC_SET_READ_CALLBACK: echon_set_read_callback_enable(io, buflen); return 0; case GENSIO_FUNC_SET_WRITE_CALLBACK: echon_set_write_callback_enable(io, buflen); return 0; case GENSIO_FUNC_DISABLE: return echon_disable(io); case GENSIO_FUNC_CONTROL: return echon_control(io, *((bool *) cbuf), buflen, buf, count); default: return GE_NOTSUP; } } static int echo_ndata_setup(struct gensio_os_funcs *o, gensiods max_read_size, struct echon_data **new_ndata) { struct echon_data *ndata; ndata = o->zalloc(o, sizeof(*ndata)); if (!ndata) return GE_NOMEM; ndata->o = o; ndata->refcount = 1; ndata->buf = gensio_circbuf_alloc(o, max_read_size); if (!ndata->buf) goto out_nomem; ndata->deferred_op_runner = o->alloc_runner(o, echon_deferred_op, ndata); if (!ndata->deferred_op_runner) goto out_nomem; ndata->lock = o->alloc_lock(o); if (!ndata->lock) goto out_nomem; *new_ndata = ndata; return 0; out_nomem: echon_finish_free(ndata); return GE_NOMEM; } static int echo_gensio_alloc(const void *gdata, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct echon_data *ndata = NULL; int i; gensiods max_read_size = GENSIO_DEFAULT_BUF_SIZE; bool noecho = false; const char *data = NULL; GENSIO_DECLARE_PPGENSIO(p, o, cb, "echo", user_data); for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(&p, args[i], "readbuf", &max_read_size) > 0) continue; if (gensio_pparm_bool(&p, args[i], "noecho", &noecho) > 0) continue; if (gensio_pparm_value(&p, args[i], "data", &data) > 0) continue; gensio_pparm_unknown_parm(&p, args[i]); return GE_INVAL; } if (data) max_read_size = strlen(data); err = echo_ndata_setup(o, max_read_size, &ndata); if (err) return err; if (data) { struct gensio_sg sg; if (noecho) ndata->justdata = true; sg.buf = data; sg.buflen = max_read_size; gensio_circbuf_sg_write(ndata->buf, &sg, 1, NULL); } ndata->noecho = noecho; ndata->io = gensio_data_alloc(ndata->o, cb, user_data, gensio_echo_func, NULL, "echo", ndata); if (!ndata->io) goto out_nomem; gensio_set_is_client(ndata->io, true); gensio_set_is_reliable(ndata->io, true); *new_gensio = ndata->io; return 0; out_nomem: echon_finish_free(ndata); return GE_NOMEM; } static int str_to_echo_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { return echo_gensio_alloc(NULL, args, o, cb, user_data, new_gensio); } int gensio_init_echo(struct gensio_os_funcs *o) { int rv; rv = register_gensio(o, "echo", str_to_echo_gensio, echo_gensio_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/ll_fd.c0000664000175000017500000006700115060652050010456 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include enum fd_state { /* * fd is not operational * * open -> FD_IN_OPEN (set fds) */ FD_CLOSED, /* * An open has been requested, but is not yet complete. * * fd opened -> FD_OPEN * close -> FD_IN_CLOSE * err * if retry_open() = do retry * -> FD_IN_OPEN_RETRY (clear fds) * else * -> FD_OPEN_ERR_WAIT (clear fds) */ FD_IN_OPEN, /* * An open has been requested, but is not yet complete. We got an * open failure and we cleared the old handlers but the clear is * not finish yet. When the clear is done, we will retry. * * fd cleared * if open success * -> FD_IN_OPEN (set fds) * else * -> FD_CLOSED (report open err) * close -> FD_IN_CLOSE * err -> FD_OPEN_ERR_WAIT */ FD_IN_OPEN_RETRY, /* * The fd is operational * * close -> FD_IN_CLOSE * err -> FD_ERR_WAIT */ FD_OPEN, /* * The fd is waiting close * * fd cleared -> FD_CLOSED * err -> ignore */ FD_IN_CLOSE, /* * An error occurred during open. * * fd cleared -> FD_CLOSED (report open err) * close -> FD_IN_CLOSE (report open err) */ FD_OPEN_ERR_WAIT, /* * An error occurred. * * close -> FD_IN_CLOSED * err -> ignore */ FD_ERR_WAIT }; #ifdef ENABLE_INTERNAL_TRACE #define DEBUG_STATE #endif #ifdef DEBUG_STATE struct fd_state_trace { enum fd_state old_state; enum fd_state new_state; int line; }; #define STATE_TRACE_LEN 256 #endif struct fd_ll { struct gensio_ll *ll; struct gensio_os_funcs *o; struct gensio_lock *lock; unsigned int refcount; gensio_ll_cb cb; void *cb_data; struct gensio_iod *iod; enum fd_state state; bool read_enabled; bool write_enabled; bool write_only; bool read_only; const struct gensio_fd_ll_ops *ops; void *handler_data; /* See fd_start_timer() for details on timer state machine. */ struct gensio_timer *timer; /* For open and close. */ enum { T_STOPPED, T_RUNNING, T_STOPPING, T_RESTART } timer_state; gensio_time timer_restart_val; gensio_ll_open_done open_done; void *open_data; int open_err; gensio_ll_close_done close_done; void *close_data; bool close_requested; bool freed; unsigned char *read_data; gensiods read_data_size; gensiods read_data_len; gensiods read_data_pos; const char *const *auxdata; bool in_read; bool in_write; /* * Used to run read callbacks from the selector to avoid running * it directly from user calls. */ bool deferred_op_pending; struct gensio_runner *deferred_op_runner; bool deferred_open; bool deferred_read; bool deferred_close; bool deferred_except; #ifdef DEBUG_STATE struct fd_state_trace trace[STATE_TRACE_LEN]; unsigned int trace_pos; #endif }; #define ll_to_fd(v) ((struct fd_ll *) gensio_ll_get_user_data(v)) static void fd_handle_write_ready(struct fd_ll *fdll, struct gensio_iod *iod); static void fd_stop_timer(struct fd_ll *fdll); static void fd_finish_free(struct fd_ll *fdll) { if (fdll->ll) gensio_ll_free_data(fdll->ll); if (fdll->lock) fdll->o->free_lock(fdll->lock); if (fdll->timer) fdll->o->free_timer(fdll->timer); if (fdll->deferred_op_runner) fdll->o->free_runner(fdll->deferred_op_runner); if (fdll->read_data) fdll->o->free(fdll->o, fdll->read_data); if (fdll->ops) fdll->ops->free(fdll->handler_data); fdll->o->free(fdll->o, fdll); } #ifdef DEBUG_STATE static void i_fd_add_trace(struct fd_ll *fdll, enum fd_state new_state, int line) { fdll->trace[fdll->trace_pos].old_state = fdll->state; fdll->trace[fdll->trace_pos].new_state = new_state; fdll->trace[fdll->trace_pos].line = line; if (fdll->trace_pos == STATE_TRACE_LEN - 1) fdll->trace_pos = 0; else fdll->trace_pos++; } #define fd_add_trace(fdll, new_state) \ i_fd_add_trace(fdll, new_state, __LINE__) static void i_fd_lock(struct fd_ll *fdll, int line) { fdll->o->lock(fdll->lock); i_fd_add_trace(fdll, 1000 + fdll->refcount, line); } #define fd_lock(fdll) i_fd_lock(fdll, __LINE__) static void i_fd_unlock(struct fd_ll *fdll, int line) { i_fd_add_trace(fdll, 1000 + fdll->refcount, line); fdll->o->unlock(fdll->lock); } #define fd_unlock(fdll) i_fd_unlock(fdll, __LINE__) static void i_fd_ref(struct fd_ll *fdll, int line) { assert(fdll->refcount > 0); fdll->refcount++; i_fd_add_trace(fdll, 1000 + fdll->refcount, line); } #define fd_ref(fdll) i_fd_ref(fdll, __LINE__) static void i_fd_deref(struct fd_ll *fdll, int line) { assert(fdll->refcount > 1); fdll->refcount--; i_fd_add_trace(fdll, 1000 + fdll->refcount, line); } #define fd_deref(fdll) i_fd_deref(fdll, __LINE__) static void i_fd_lock_and_ref(struct fd_ll *fdll, int line) { i_fd_lock(fdll, line); assert(fdll->refcount > 0); fdll->refcount++; } #define fd_lock_and_ref(fdll) i_fd_lock_and_ref(fdll, __LINE__) static void i_fd_set_state(struct fd_ll *fdll, enum fd_state state, int line) { i_fd_add_trace(fdll, state, line); fdll->state = state; } #define fd_set_state(fdll, state) i_fd_set_state(fdll, state, __LINE__) static void i_fd_deref_and_unlock(struct fd_ll *fdll, int line) { unsigned int count; assert(fdll->refcount > 0); count = --fdll->refcount; i_fd_unlock(fdll, line); if (count == 0) fd_finish_free(fdll); } #define fd_deref_and_unlock(fdll) i_fd_deref_and_unlock(fdll, __LINE__) #else /* DEBUG_STATE */ #define fd_add_trace(fdll, new_state) static void fd_lock(struct fd_ll *fdll) { fdll->o->lock(fdll->lock); } static void fd_unlock(struct fd_ll *fdll) { fdll->o->unlock(fdll->lock); } static void fd_ref(struct fd_ll *fdll) { assert(fdll->refcount > 0); fdll->refcount++; } static void fd_deref(struct fd_ll *fdll) { assert(fdll->refcount > 1); fdll->refcount--; } static void fd_lock_and_ref(struct fd_ll *fdll) { fd_lock(fdll); assert(fdll->refcount > 0); fdll->refcount++; } static void fd_set_state(struct fd_ll *fdll, enum fd_state state) { fdll->state = state; } static void fd_deref_and_unlock(struct fd_ll *fdll) { unsigned int count; assert(fdll->refcount > 0); count = --fdll->refcount; fd_unlock(fdll); if (count == 0) fd_finish_free(fdll); } #endif /* DEBUG_STATE */ static void fd_set_callbacks(struct gensio_ll *ll, gensio_ll_cb cb, void *cb_data) { struct fd_ll *fdll = ll_to_fd(ll); fdll->cb = cb; fdll->cb_data = cb_data; } gensiods gensio_fd_ll_callback(struct gensio_ll *ll, int op, int val, void *buf, gensiods buflen, const void *auxdata) { struct fd_ll *fdll = ll_to_fd(ll); return fdll->cb(fdll->cb_data, op, val, buf, buflen, auxdata); } static int fd_write(struct gensio_ll *ll, gensiods *rcount, const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { struct fd_ll *fdll = ll_to_fd(ll); if (fdll->ops->write) return fdll->ops->write(fdll->handler_data, fdll->iod, rcount, sg, sglen, auxdata); return fdll->o->write(fdll->iod, sg, sglen, rcount); } static void fd_deliver_read_data(struct fd_ll *fdll, int err) { if (err || fdll->read_data_len) { gensiods count; retry: fd_unlock(fdll); if (fdll->ops->deliver_read) count = fdll->ops->deliver_read(fdll->handler_data, fdll->cb_data, fdll->cb, err, fdll->read_data + fdll->read_data_pos, fdll->read_data_len, fdll->auxdata); else count = gensio_fd_ll_callback(fdll->ll, GENSIO_LL_CB_READ, err, fdll->read_data + fdll->read_data_pos, fdll->read_data_len, fdll->auxdata); fd_lock(fdll); if (err || count >= fdll->read_data_len) { fdll->read_data_pos = 0; fdll->read_data_len = 0; fdll->auxdata = NULL; } else { fdll->read_data_pos += count; fdll->read_data_len -= count; if (fdll->read_enabled) goto retry; } } } static void fd_finish_open(struct fd_ll *fdll, int err) { gensio_ll_open_done open_done = fdll->open_done; if (err) fd_set_state(fdll, FD_CLOSED); else fd_set_state(fdll, FD_OPEN); fdll->open_done = NULL; fd_unlock(fdll); open_done(fdll->cb_data, err, fdll->open_data); fd_lock(fdll); if (fdll->state == FD_OPEN) { if (fdll->read_enabled) fdll->o->set_read_handler(fdll->iod, true); if (fdll->write_enabled) fdll->o->set_write_handler(fdll->iod, true); fdll->o->set_except_handler(fdll->iod, fdll->read_enabled || fdll->write_enabled); } } static void fd_finish_close(struct fd_ll *fdll) { fd_set_state(fdll, FD_CLOSED); if (fdll->close_done) { gensio_ll_close_done close_done = fdll->close_done; fdll->close_done = NULL; fd_unlock(fdll); close_done(fdll->cb_data, fdll->close_data); fd_lock(fdll); } fd_deref(fdll); } static void fd_deferred_op(struct gensio_runner *runner, void *cbdata) { struct fd_ll *fdll = cbdata; fd_lock(fdll); if (fdll->deferred_open) { fdll->deferred_open = false; fd_finish_open(fdll, fdll->open_err); } if (fdll->deferred_except && fdll->write_enabled) { fdll->deferred_except = false; if (fdll->iod) fd_handle_write_ready(fdll, fdll->iod); } while (fdll->deferred_read) { fdll->deferred_read = false; if (!fdll->in_read) { fdll->in_read = true; while (fdll->read_enabled && fdll->read_data_len) fd_deliver_read_data(fdll, 0); fdll->in_read = false; } } if (fdll->deferred_close) { fdll->deferred_close = false; fd_finish_close(fdll); } fdll->deferred_op_pending = false; if (fdll->state == FD_OPEN) { fdll->o->set_read_handler(fdll->iod, fdll->read_enabled); fdll->o->set_except_handler(fdll->iod, fdll->read_enabled || fdll->write_enabled); fdll->o->set_write_handler(fdll->iod, fdll->write_enabled); } fd_deref_and_unlock(fdll); } static void fd_sched_deferred_op(struct fd_ll *fdll) { if (!fdll->deferred_op_pending) { /* Call the read from the selector to avoid lock nesting issues. */ fd_ref(fdll); fdll->deferred_op_pending = true; fdll->o->run(fdll->deferred_op_runner); } } static void fd_start_close(struct fd_ll *fdll) { if (fdll->ops->check_close) fdll->ops->check_close(fdll->handler_data, fdll->iod, GENSIO_LL_CLOSE_STATE_START, NULL); if (!fdll->iod) { fdll->deferred_close = true; fd_sched_deferred_op(fdll); } else if (fdll->state != FD_OPEN_ERR_WAIT && fdll->state != FD_IN_OPEN_RETRY) { fd_stop_timer(fdll); fdll->o->clear_fd_handlers(fdll->iod); } fd_set_state(fdll, FD_IN_CLOSE); } static void fd_handle_incoming(struct fd_ll *fdll, int (*doread)(struct gensio_iod *iod, void *buf, gensiods count, gensiods *rcount, const char ***auxdata, void *cb_data), const char **auxdata, void *cb_data) { int err = 0; gensiods count; fd_lock_and_ref(fdll); if (fdll->in_read || fdll->state == FD_ERR_WAIT || fdll->state == FD_OPEN_ERR_WAIT) goto out_disable; fdll->in_read = true; if (!fdll->read_data_len) { fd_unlock(fdll); err = doread(fdll->iod, fdll->read_data, fdll->read_data_size, &count, &auxdata, cb_data); fd_lock(fdll); if (!err) { fdll->read_data_len = count; fdll->auxdata = auxdata; } } fd_deliver_read_data(fdll, err); if (err) { switch(fdll->state) { case FD_IN_OPEN: case FD_IN_OPEN_RETRY: case FD_OPEN_ERR_WAIT: case FD_CLOSED: assert(0); /* Should not be possible. */ break; case FD_OPEN: fdll->o->set_write_handler(fdll->iod, false); fdll->o->set_except_handler(fdll->iod, false); fd_set_state(fdll, FD_ERR_WAIT); break; case FD_ERR_WAIT: case FD_IN_CLOSE: break; } } fdll->in_read = false; /* * We could turn off read when there is pending data, but * if the user is doing their job right, it shouldn't matter. */ if (fdll->state == FD_OPEN && fdll->read_enabled) { fdll->o->set_read_handler(fdll->iod, true); fdll->o->set_except_handler(fdll->iod, true); } else { out_disable: fdll->o->set_read_handler(fdll->iod, false); fdll->o->set_except_handler(fdll->iod, fdll->write_enabled); } fd_deref_and_unlock(fdll); } void gensio_fd_ll_handle_incoming(struct gensio_ll *ll, int (*doread)(struct gensio_iod *iod, void *buf, gensiods count, gensiods *rcount, const char ***auxdata, void *cb_data), const char **auxdata, void *cb_data) { struct fd_ll *fdll = ll_to_fd(ll); fd_handle_incoming(fdll, doread, auxdata, cb_data); } static int gensio_ll_fd_read(struct gensio_iod *iod, void *buf, gensiods count, gensiods *rcount, const char ***auxdata, void *cb_data) { return iod->f->read(iod, buf, count, rcount); } static void fd_read_ready(struct gensio_iod *iod, void *cbdata) { struct fd_ll *fdll = cbdata; if (fdll->ops->read_ready) { fdll->ops->read_ready(fdll->handler_data, fdll->iod); return; } fd_handle_incoming(fdll, gensio_ll_fd_read, NULL, fdll); } static int fd_setup_handlers(struct fd_ll *fdll); /* * Timer state machine. A timer may be in one of four states: * * T_STOPPED: The timer is not running or in the handler. * T_RUNNING: The timer is running or in the handler. * T_STOPPING: The timer is not running but in the handler. * T_RESTART: The timer is not running but in the handler and will start * itself with the timer_restart_value when it runns. * * The timer being "in the handler" means that the timer has gone off * but the handler has not yet been called, or has been called but is * sitting at the lock call waiting to claim the lock. */ static void fd_start_timer(struct fd_ll *fdll, gensio_time *timeout) { int rv; switch (fdll->timer_state) { case T_STOPPED: /* Timer is stopped, just start it. */ fd_ref(fdll); start: assert(fdll->o->start_timer(fdll->timer, timeout) == 0); fdll->timer_state = T_RUNNING; break; case T_RUNNING: /* Restart the timer with a new value. */ rv = fdll->o->stop_timer(fdll->timer); if (rv == GE_TIMEDOUT) /* Timer is in the handler, treat it as such. */ goto stopping; goto start; case T_STOPPING: /* * Timer has already been stopped but is in the handler, restart * in the handler with a new value. */ stopping: fdll->timer_restart_val = *timeout; fdll->timer_state = T_RESTART; break; case T_RESTART: fdll->timer_restart_val = *timeout; break; } } static void fd_stop_timer(struct fd_ll *fdll) { int rv; switch (fdll->timer_state) { case T_STOPPED: break; case T_RUNNING: /* Just stop the timer. */ rv = fdll->o->stop_timer(fdll->timer); if (rv == GE_TIMEDOUT) { /* Timer is in the handler. */ fdll->timer_state = T_STOPPING; } else { /* Timer was stopped. */ fd_deref(fdll); fdll->timer_state = T_STOPPED; } break; case T_STOPPING: break; case T_RESTART: fdll->timer_state = T_STOPPING; break; } } static void fd_handle_write_ready(struct fd_ll *fdll, struct gensio_iod *iod) { if (fdll->state == FD_IN_OPEN) { int err; gensio_time timeout; err = fdll->ops->check_open(fdll->handler_data, fdll->iod, &timeout); if (err == GE_RETRY) { fd_start_timer(fdll, &timeout); return; } fdll->o->set_write_handler(iod, false); fdll->o->set_except_handler(iod, fdll->read_enabled); if (err && err != GE_NOMEM && fdll->ops->retry_open) { /* * The GE_NOMEM check is strange here, but it really has * more to do with testing. check_open() is not going to * return GE_NOMEM unless it's an error trigger failure, * and we really want to fail in that case or we will get * a "error triggered but no failure" in the test. */ fd_set_state(fdll, FD_IN_OPEN_RETRY); fd_stop_timer(fdll); fdll->o->clear_fd_handlers(fdll->iod); } else { if (err) { fdll->open_err = err; fd_set_state(fdll, FD_OPEN_ERR_WAIT); fd_stop_timer(fdll); fdll->o->clear_fd_handlers(fdll->iod); } else { fd_finish_open(fdll, 0); } } } else if (fdll->state == FD_OPEN && fdll->write_enabled && !fdll->in_write) { fdll->in_write = true; fd_unlock(fdll); if (fdll->ops->write_ready) fdll->ops->write_ready(fdll->handler_data, fdll->iod); else gensio_fd_ll_callback(fdll->ll, GENSIO_LL_CB_WRITE_READY, 0, NULL, 0, NULL); fd_lock(fdll); fdll->in_write = false; if ((fdll->state == FD_OPEN || fdll->state == FD_IN_CLOSE) && fdll->write_enabled) { fdll->o->set_write_handler(fdll->iod, true); fdll->o->set_except_handler(fdll->iod, true); } else { fdll->o->set_write_handler(iod, false); fdll->o->set_except_handler(iod, fdll->read_enabled); } } else { fdll->o->set_write_handler(iod, false); fdll->o->set_except_handler(iod, fdll->read_enabled); } } static void fd_write_ready(struct gensio_iod *iod, void *cbdata) { struct fd_ll *fdll = cbdata; fd_lock_and_ref(fdll); fd_handle_write_ready(fdll, iod); fd_deref_and_unlock(fdll); } static void fd_except_ready(struct gensio_iod *iod, void *cbdata) { struct fd_ll *fdll = cbdata; int rv = 0; fd_lock(fdll); /* * In some cases, if a connect() call fails, we get an exception, * not a write ready. So in the open case, call write ready. */ if (fdll->state == FD_IN_OPEN || fdll->state == FD_IN_OPEN_RETRY) { fd_ref(fdll); fd_handle_write_ready(fdll, iod); fd_deref_and_unlock(fdll); } else if (fdll->ops->except_ready) { fd_unlock(fdll); rv = fdll->ops->except_ready(fdll->handler_data, fdll->iod); if (rv) { fd_lock(fdll); goto handle_except_internal; } } else { handle_except_internal: if (fdll->read_enabled) { fd_unlock(fdll); fd_read_ready(iod, fdll); } else { if (fdll->write_enabled) fd_handle_write_ready(fdll, iod); else fdll->deferred_except = true; fd_unlock(fdll); } } } static void fd_finish_cleared(struct fd_ll *fdll) { if (fdll->iod) fdll->o->close(&fdll->iod); if (fdll->state == FD_OPEN_ERR_WAIT) fdll->deferred_open = true; fdll->deferred_close = true; fd_sched_deferred_op(fdll); } void gensio_fd_ll_close_now(struct gensio_ll *ll) { struct fd_ll *fdll = ll_to_fd(ll); if (fdll->iod) fdll->o->close(&fdll->iod); } static void fd_check_close(struct fd_ll *fdll) { gensio_time timeout; int err = 0; if (fdll->ops->check_close) { err = fdll->ops->check_close(fdll->handler_data, fdll->iod, GENSIO_LL_CLOSE_STATE_DONE, &timeout); if (err != GE_INPROGRESS) fdll->iod = NULL; } if (err == GE_INPROGRESS) fd_start_timer(fdll, &timeout); else fd_finish_cleared(fdll); } static void fd_timeout(struct gensio_timer *t, void *cb_data) { struct fd_ll *fdll = cb_data; fd_lock(fdll); switch (fdll->timer_state) { case T_STOPPED: /* Nothing to do. Shouldn't happen, but no biggie. */ break; case T_STOPPING: fdll->timer_state = T_STOPPED; break; case T_RESTART: fd_ref(fdll); assert(fdll->o->start_timer(fdll->timer, &fdll->timer_restart_val) == 0); fdll->timer_state = T_RUNNING; break; case T_RUNNING: fdll->timer_state = T_STOPPED; if (fdll->state == FD_IN_CLOSE) fd_check_close(fdll); else if (fdll->state == FD_IN_OPEN) fd_handle_write_ready(fdll, fdll->iod); break; } fd_deref_and_unlock(fdll); /* Lose the timer ref. */ } static void fd_cleared(struct gensio_iod *iod, void *cb_data) { struct fd_ll *fdll = cb_data; int err; gensio_time timeout; fd_lock_and_ref(fdll); if (fdll->state == FD_IN_OPEN_RETRY) { fdll->o->close(&fdll->iod); err = fdll->ops->retry_open(fdll->handler_data, &fdll->iod, &timeout); if (err == GE_INPROGRESS || err == GE_RETRY) { int err2 = fd_setup_handlers(fdll); if (err2) { fdll->o->close(&fdll->iod); err = err2; } else { if (err == GE_RETRY) fd_start_timer(fdll, &timeout); fd_set_state(fdll, FD_IN_OPEN); err = 0; } } if (err) { fd_deref(fdll); fd_finish_open(fdll, err); } else { fdll->o->set_write_handler(fdll->iod, true); fdll->o->set_except_handler(fdll->iod, true); } } else { fd_check_close(fdll); } fd_deref_and_unlock(fdll); } static int fd_open(struct gensio_ll *ll, gensio_ll_open_done done, void *open_data) { struct fd_ll *fdll = ll_to_fd(ll); int err; gensio_time timeout; if (!fdll->ops->sub_open) return GE_NOTSUP; fd_lock(fdll); if (fdll->state != FD_CLOSED) { err = GE_NOTREADY; goto out; } fdll->close_requested = false; fdll->open_err = 0; fdll->read_data_len = 0; fdll->read_data_pos = 0; err = fdll->ops->sub_open(fdll->handler_data, &fdll->iod, &timeout); if (err == GE_INPROGRESS || err == GE_RETRY || err == 0) { int err2 = fd_setup_handlers(fdll); if (err2) { err = err2; fdll->o->close(&fdll->iod); goto out; } fdll->open_done = done; fdll->open_data = open_data; if (err == GE_INPROGRESS || err == GE_RETRY) { if (err == GE_RETRY) { fd_start_timer(fdll, &timeout); err = GE_INPROGRESS; } fd_set_state(fdll, FD_IN_OPEN); fdll->o->set_write_handler(fdll->iod, true); fdll->o->set_except_handler(fdll->iod, true); } else { fd_set_state(fdll, FD_OPEN); } fd_ref(fdll); } out: fd_unlock(fdll); return err; } static int fd_setup_handlers(struct fd_ll *fdll) { if (fdll->o->set_fd_handlers(fdll->iod, fdll, fd_read_ready, fd_write_ready, fd_except_ready, fd_cleared)) return GE_NOMEM; return 0; } static int fd_close(struct gensio_ll *ll, gensio_ll_close_done done, void *close_data) { struct fd_ll *fdll = ll_to_fd(ll); int err = GE_NOTREADY; fd_lock(fdll); if (fdll->close_requested) goto out_unlock; switch(fdll->state) { case FD_IN_OPEN: case FD_IN_OPEN_RETRY: fdll->open_err = GE_LOCALCLOSED; /* Fallthrough */ case FD_OPEN_ERR_WAIT: fdll->deferred_open = true; fd_sched_deferred_op(fdll); /* Fallthrough */ case FD_OPEN: case FD_ERR_WAIT: fdll->close_done = done; fdll->close_data = close_data; fd_start_close(fdll); err = 0; break; case FD_CLOSED: break; default: assert(0); } fdll->close_requested = true; out_unlock: fd_unlock(fdll); return err; } static void fd_set_read_callback_enable(struct gensio_ll *ll, bool enabled) { struct fd_ll *fdll = ll_to_fd(ll); fd_lock(fdll); if (fdll->write_only) goto out_unlock; fdll->read_enabled = enabled; if (fdll->in_read || fdll->state != FD_OPEN || (fdll->read_data_len && !enabled)) { /* It will be handled in finish_read or open finish. */ } else if (fdll->read_data_len) { /* Call the read from the selector to avoid lock nesting issues. */ fdll->deferred_read = true; fd_sched_deferred_op(fdll); } else { fdll->o->set_read_handler(fdll->iod, enabled); fdll->o->set_except_handler(fdll->iod, enabled || fdll->write_enabled); } out_unlock: fd_unlock(fdll); } static void fd_set_write_callback_enable(struct gensio_ll *ll, bool enabled) { struct fd_ll *fdll = ll_to_fd(ll); fd_lock(fdll); if (fdll->read_only) goto out_unlock; fdll->write_enabled = enabled; if (fdll->state == FD_OPEN || fdll->state == FD_IN_OPEN || fdll->state == FD_IN_OPEN_RETRY) { fdll->o->set_write_handler(fdll->iod, enabled); fdll->o->set_except_handler(fdll->iod, enabled || fdll->read_enabled); } else if (fdll->deferred_except) { fd_sched_deferred_op(fdll); } out_unlock: fd_unlock(fdll); } static void fd_free(struct gensio_ll *ll) { struct fd_ll *fdll = ll_to_fd(ll); fd_lock(fdll); assert(!fdll->freed); fdll->freed = true; switch (fdll->state) { case FD_IN_CLOSE: case FD_CLOSED: break; case FD_OPEN: case FD_ERR_WAIT: case FD_OPEN_ERR_WAIT: fdll->close_done = NULL; fd_start_close(fdll); break; default: assert(0); break; } fd_deref_and_unlock(fdll); } static int fd_control(struct gensio_ll *ll, bool get, unsigned int option, char *data, gensiods *datalen) { struct fd_ll *fdll = ll_to_fd(ll); if (!fdll->ops->control) return GE_NOTSUP; return fdll->ops->control(fdll->handler_data, fdll->iod, get, option, data, datalen); } static int fd_acontrol(struct gensio_ll *ll, bool get, unsigned int option, struct gensio_func_acontrol *data) { struct fd_ll *fdll = ll_to_fd(ll); if (!fdll->ops->acontrol) return GE_NOTSUP; return fdll->ops->acontrol(fdll->handler_data, fdll->iod, get, option, data); } static void fd_disable(struct gensio_ll *ll) { struct fd_ll *fdll = ll_to_fd(ll); fd_set_state(fdll, FD_CLOSED); fd_deref(fdll); fd_stop_timer(fdll); fdll->o->clear_fd_handlers_norpt(fdll->iod); fdll->o->close(&fdll->iod); } static int gensio_ll_fd_func(struct gensio_ll *ll, int op, gensiods *count, void *buf, const void *cbuf, gensiods buflen, const char *const *auxdata) { switch (op) { case GENSIO_LL_FUNC_SET_CALLBACK: fd_set_callbacks(ll, (void *) cbuf, buf); return 0; case GENSIO_LL_FUNC_WRITE_SG: return fd_write(ll, count, cbuf, buflen, auxdata); case GENSIO_LL_FUNC_OPEN: return fd_open(ll, (void *) cbuf, buf); case GENSIO_LL_FUNC_CLOSE: return fd_close(ll, (void *) cbuf, buf); case GENSIO_LL_FUNC_SET_READ_CALLBACK: fd_set_read_callback_enable(ll, buflen); return 0; case GENSIO_LL_FUNC_SET_WRITE_CALLBACK: fd_set_write_callback_enable(ll, buflen); return 0; case GENSIO_LL_FUNC_FREE: fd_free(ll); return 0; case GENSIO_LL_FUNC_CONTROL: return fd_control(ll, *((bool *) cbuf), buflen, buf, count); case GENSIO_LL_FUNC_ACONTROL: return fd_acontrol(ll, *((bool *) cbuf), buflen, buf); case GENSIO_LL_FUNC_DISABLE: fd_disable(ll); return 0; default: return GE_NOTSUP; } } void * gensio_fd_ll_get_handler_data(struct gensio_ll *ll) { struct fd_ll *fdll = ll_to_fd(ll); return fdll->handler_data; } struct gensio_ll * fd_gensio_ll_alloc(struct gensio_os_funcs *o, struct gensio_iod *iod, const struct gensio_fd_ll_ops *ops, void *handler_data, gensiods max_read_size, bool write_only, bool read_only) { struct fd_ll *fdll; fdll = o->zalloc(o, sizeof(*fdll)); if (!fdll) return NULL; fdll->o = o; fdll->handler_data = handler_data; fdll->iod = iod; fdll->refcount = 1; fdll->write_only = write_only; fdll->read_only = read_only; if (!iod) { fd_set_state(fdll, FD_CLOSED); } else { fd_set_state(fdll, FD_OPEN); fd_ref(fdll); } fdll->timer = o->alloc_timer(o, fd_timeout, fdll); if (!fdll->timer) goto out_nomem; fdll->deferred_op_runner = o->alloc_runner(o, fd_deferred_op, fdll); if (!fdll->deferred_op_runner) goto out_nomem; fdll->lock = o->alloc_lock(o); if (!fdll->lock) goto out_nomem; fdll->read_data_size = max_read_size; if (max_read_size > 0) { fdll->read_data = o->zalloc(o, max_read_size); if (!fdll->read_data) goto out_nomem; } fdll->ll = gensio_ll_alloc_data(o, gensio_ll_fd_func, fdll); if (!fdll->ll) goto out_nomem; if (iod) { int err = fd_setup_handlers(fdll); if (err) goto out_nomem; } /* * Don't set ops until here to avoid it trying to call ops->free * on an error above. */ fdll->ops = ops; return fdll->ll; out_nomem: fd_finish_free(fdll); return NULL; } gensio-3.0.0/lib/telnet.h0000664000175000017500000001106514664224267010713 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #ifndef _SER2NET_TELNET_H #define _SER2NET_TELNET_H #include /* Telnet commands */ #define TN_SE 240 #define TN_DATA_MARK 242 #define TN_BREAK 243 #define TN_SB 250 #define TN_WILL 251 #define TN_WONT 252 #define TN_DO 253 #define TN_DONT 254 #define TN_IAC 255 #define TN_OPT_BINARY_TRANSMISSION 0 #define TN_OPT_ECHO 1 #define TN_OPT_SUPPRESS_GO_AHEAD 3 #define TN_OPT_COM_PORT 44 /* rfc2217 */ #define TN_OPT_NAWS 31 /* rfc1073 - Window size */ typedef struct telnet_data_s telnet_data_t; #define TELNET_CMD_END_OPTION 255 struct telnet_cmd { unsigned char option; unsigned int i_will : 1; unsigned int i_do : 1; unsigned int sent_will : 1; unsigned int sent_do : 1; unsigned int rem_will : 1; unsigned int rem_do : 1; /* If this is non-null, this will be called on any options received by the code */ void (*option_handler)(void *cb_data, unsigned char *option, int len); /* If this is non-null, this will be called if a will/wont/do/dont command is sent by the remote end. For will and do commands, if this returns 1, the option will be allowed (a DO/WILL is returned). If it returns 0, a DONT/WONT is returned. The return value is ignored for wont and dont commands. */ int (*will_do_handler)(void *cb_data, unsigned char cmd); }; #define MAX_TELNET_CMD_SIZE 31 #define MAX_TELNET_CMD_XMIT_BUF 256 struct telnet_data_s { /* Incoming telnet commands. This is "+1" because the last byte always holds the previous byte received, even on an overflow, so that the end of the options can be correctly detected. */ unsigned char telnet_cmd[MAX_TELNET_CMD_SIZE + 1]; int telnet_cmd_pos; /* Current position in the telnet_cmd buffer. If zero, no telnet command is in progress. */ int suboption_iac; /* If true, we are in a suboption and processing an IAC. */ /* Outgoing telnet commands. The output routines should look at this *first* to see if they should transmit some data from here. */ struct gensio_buffer out_telnet_cmd; unsigned char out_telnet_cmdbuf[MAX_TELNET_CMD_XMIT_BUF]; /* Marks that an output error occurred. The only error that can occur is "out of space", meaning that the code needed to do output wut out_telnet_cmd was full. */ int error; void *cb_data; /* Call when data is added to out_telnet_cmd. */ void (*output_ready)(void *cb_data); /* Called for all one-byte telnet commands. */ void (*cmd_handler)(void *cb_data, unsigned char cmd); /* An array of commands, the last option must be set to 255 to mark the end of the array. */ struct telnet_cmd *cmds; }; /* Send a telnet command. This will set td->error to true if an output error occurs (out of space). */ void telnet_cmd_send(telnet_data_t *td, const unsigned char *cmd, unsigned int len); /* Received some data from the TCP port representing telnet, process it. The leftover length is returned by this function, and the telnet data will be removed from data. This will set td->error to true if an output error occurs (out of space).*/ unsigned int process_telnet_data(unsigned char *outdata, unsigned int outlen, unsigned char **indata, unsigned int *inlen, telnet_data_t *td); /* Double all the IACs in the transmitted data. If outlen is more than twice the size of inlen, this will process all the data. The number of bytes put into outdata is returned. inlen will be updated to the number of bytes not processed in indata and indata will be updated to point to the location after the last processed character. */ unsigned int process_telnet_xmit(unsigned char *outdata, unsigned int outlen, const unsigned char **indata, size_t *inlen); /* Used to send an option. The option should *not* contain the inital "255 250" nor the tailing "255 240" and should *not* double internal 255 values. */ void telnet_send_option(telnet_data_t *td, const unsigned char *option, unsigned int len); /* Initialize the telnet data. */ void telnet_init(telnet_data_t *td, void *cb_data, void (*output_ready)(void *cb_data), void (*cmd_handler)(void *cb_data, unsigned char cmd), struct telnet_cmd *cmds, const unsigned char *init_seq, int init_seq_len); void telnet_cleanup(telnet_data_t *td); #endif /* _SER2NET_TELNET_H */ gensio-3.0.0/lib/gensio_perf.c0000664000175000017500000004465114747451760011724 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018-2025 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include struct perf_filter { struct gensio_filter *filter; gensio_filter_cb filter_cb; void *filter_cb_data; struct gensio_os_funcs *o; struct gensio_lock *lock; /* Data waiting to be delivered to the lower layer. */ unsigned char *write_data; gensiods writebuf_size; gensiods write_len; gensiods write_data_left; gensiods read_count; gensiods expect_len; gensiods orig_expect_len; struct gensio_time start_time; bool read_end_time_set; struct gensio_time read_end_time; bool write_end_time_set; struct gensio_time write_end_time; unsigned int timeouts_since_print; gensiods read_since_last_timeout; gensiods write_since_last_timeout; gensiods print_pending; gensiods print_pos; char print_buffer[1024]; bool final_started; }; #define filter_to_perf(v) ((struct perf_filter *) \ gensio_filter_get_user_data(v)) static void perf_lock(struct perf_filter *pfilter) { pfilter->o->lock(pfilter->lock); } static void perf_unlock(struct perf_filter *pfilter) { pfilter->o->unlock(pfilter->lock); } static bool perf_ul_read_pending(struct gensio_filter *filter) { struct perf_filter *pfilter = filter_to_perf(filter); return pfilter->print_pending; } static bool perf_ll_write_pending(struct gensio_filter *filter) { struct perf_filter *pfilter = filter_to_perf(filter); /* * Always return true if we are supplying data. We want it to * supply data and then return a GE_REMCLOSE when out of data. * But we want to get our data out to the lower layer before * reporting that. */ return (pfilter->write_len > 0 && !(pfilter->final_started && (pfilter->print_pending > 0 || pfilter->expect_len > 0))) || (pfilter->orig_expect_len && pfilter->expect_len == 0 && pfilter->print_pending == 0); } static bool perf_ll_read_needed(struct gensio_filter *filter) { return false; } static void perf_filter_start_timer(struct perf_filter *pfilter) { gensio_time timeout = { 1, 0 }; pfilter->filter_cb(pfilter->filter_cb_data, GENSIO_FILTER_CB_START_TIMER, &timeout); } static void perf_set_callbacks(struct gensio_filter *filter, gensio_filter_cb cb, void *cb_data) { struct perf_filter *pfilter = filter_to_perf(filter); pfilter->filter_cb = cb; pfilter->filter_cb_data = cb_data; } static int perf_check_open_done(struct gensio_filter *filter, struct gensio *io) { struct perf_filter *pfilter = filter_to_perf(filter); perf_filter_start_timer(pfilter); pfilter->o->get_monotonic_time(pfilter->o, &pfilter->start_time); return 0; } static int perf_try_connect(struct gensio_filter *filter, gensio_time *timeout) { return 0; } static void set_read_end_time(struct perf_filter *pfilter) { if (!pfilter->read_end_time_set) { pfilter->o->get_monotonic_time(pfilter->o, &pfilter->read_end_time); pfilter->read_end_time_set = true; } } static void set_write_end_time(struct perf_filter *pfilter) { if (!pfilter->write_end_time_set) { pfilter->o->get_monotonic_time(pfilter->o, &pfilter->write_end_time); pfilter->write_end_time_set = true; } } static int perf_handle_end_check(struct perf_filter *pfilter) { if (pfilter->final_started && pfilter->print_pending == 0) return 0; set_read_end_time(pfilter); set_write_end_time(pfilter); if (!pfilter->final_started && pfilter->print_pending == 0) { gensiods write_count; double total_read_time; double total_write_time; pfilter->read_end_time.secs -= pfilter->start_time.secs; pfilter->read_end_time.nsecs -= pfilter->start_time.nsecs; while (pfilter->read_end_time.nsecs < 0) { pfilter->read_end_time.nsecs += 1000000000; pfilter->read_end_time.secs -= 1; } pfilter->write_end_time.secs -= pfilter->start_time.secs; pfilter->write_end_time.nsecs -= pfilter->start_time.nsecs; while (pfilter->write_end_time.nsecs < 0) { pfilter->write_end_time.nsecs += 1000000000; pfilter->write_end_time.secs -= 1; } write_count = pfilter->write_len - pfilter->write_data_left; total_read_time = ((double) pfilter->read_end_time.secs + ((double) pfilter->read_end_time.nsecs / 1000000000.0)); total_write_time = ((double) pfilter->write_end_time.secs + ((double) pfilter->write_end_time.nsecs / 1000000000.0)); /* Flip read and write, this is from the user's perspective. */ pfilter->print_pending = snprintf(pfilter->print_buffer, sizeof(pfilter->print_buffer), "TOTAL: Wrote %ld in %llu.%3.3u seconds\n" " %lf write bytes/sec\n" " Read %ld in %llu.%3.3u seconds\n" " %lf read bytes/sec\n", write_count, (unsigned long long) pfilter->write_end_time.secs, (pfilter->write_end_time.nsecs + 500000) / 1000000, (double) write_count / total_write_time, pfilter->read_count, (unsigned long long) pfilter->read_end_time.secs, (pfilter->read_end_time.nsecs + 500000) / 1000000, (double) pfilter->read_count / total_read_time); pfilter->final_started = true; pfilter->print_pos = 0; } return GE_INPROGRESS; } static int perf_try_disconnect(struct gensio_filter *filter, gensio_time *timeout) { return 0; } static int perf_ul_write(struct gensio_filter *filter, gensio_ul_filter_data_handler handler, void *cb_data, gensiods *rcount, const struct gensio_sg *isg, gensiods sglen, const char *const *auxdata) { struct perf_filter *pfilter = filter_to_perf(filter); int err = 0; gensiods i, writelen = 0; /* Just ignore data from the upper layer. */ for (i = 0; i < sglen; i++) writelen += isg[i].buflen; if (rcount) *rcount = writelen; perf_lock(pfilter); if (pfilter->write_data_left > 0) { gensiods count = pfilter->write_data_left, ocount; struct gensio_sg sg = { pfilter->write_data, 0 }; if (count > pfilter->writebuf_size) count = pfilter->writebuf_size; sg.buflen = count; ocount = count; perf_unlock(pfilter); err = handler(cb_data, &count, &sg, 1, NULL); perf_lock(pfilter); if (!err) { if (count > ocount) count = ocount; pfilter->write_since_last_timeout += count; pfilter->write_data_left -= count; if (pfilter->write_data_left == 0) set_write_end_time(pfilter); } } else if (pfilter->write_len || pfilter->orig_expect_len) { if (!pfilter->final_started && pfilter->expect_len == 0) /* We were supplying data and we are out of data. */ perf_handle_end_check(pfilter); else if (pfilter->final_started && pfilter->print_pending == 0) err = GE_REMCLOSE; } perf_unlock(pfilter); return err; } static int perf_ll_write(struct gensio_filter *filter, gensio_ll_filter_data_handler handler, void *cb_data, gensiods *rcount, unsigned char *buf, gensiods buflen, const char *const *auxdata) { struct perf_filter *pfilter = filter_to_perf(filter); int err = 0; if (rcount) *rcount = buflen; /* Ignore data from below. */ perf_lock(pfilter); pfilter->read_count += buflen; pfilter->read_since_last_timeout += buflen; if (buflen > pfilter->expect_len) pfilter->expect_len = 0; else pfilter->expect_len -= buflen; if (pfilter->orig_expect_len && pfilter->expect_len == 0) set_read_end_time(pfilter); if (pfilter->print_pending) { gensiods count = pfilter->print_pending - pfilter->print_pos; perf_unlock(pfilter); err = handler(cb_data, &count, (unsigned char *) pfilter->print_buffer + pfilter->print_pos, count, NULL); perf_lock(pfilter); if (!err) { if (count > pfilter->print_pending - pfilter->print_pos) count = pfilter->print_pending - pfilter->print_pos; pfilter->print_pos += count; if (pfilter->print_pos == pfilter->print_pending) pfilter->print_pending = 0; } } perf_unlock(pfilter); return err; } static int perf_filter_timeout(struct gensio_filter *filter) { struct perf_filter *pfilter = filter_to_perf(filter); perf_lock(pfilter); pfilter->timeouts_since_print++; if (!pfilter->print_pending) { pfilter->print_pending = snprintf(pfilter->print_buffer, sizeof(pfilter->print_buffer), "Wrote %ld, Read %ld in %u second%s\n", pfilter->write_since_last_timeout, pfilter->read_since_last_timeout, pfilter->timeouts_since_print, pfilter->timeouts_since_print == 1 ? "" : "s"); pfilter->write_since_last_timeout = 0; pfilter->read_since_last_timeout = 0; pfilter->timeouts_since_print = 0; pfilter->print_pos = 0; } perf_filter_start_timer(pfilter); perf_unlock(pfilter); return 0; } static void perf_filter_io_err(struct gensio_filter *filter, int err) { struct perf_filter *pfilter = filter_to_perf(filter); perf_lock(pfilter); perf_handle_end_check(pfilter); perf_unlock(pfilter); } static int perf_setup(struct gensio_filter *filter) { return 0; } static void perf_filter_cleanup(struct gensio_filter *filter) { struct perf_filter *pfilter = filter_to_perf(filter); pfilter->write_data_left = pfilter->write_len; pfilter->expect_len = pfilter->orig_expect_len; pfilter->read_count = 0; pfilter->read_end_time_set = false; pfilter->write_end_time_set = false; pfilter->read_since_last_timeout = 0; pfilter->write_since_last_timeout = 0; pfilter->timeouts_since_print = 0; pfilter->print_pending = 0; pfilter->final_started = false; } static void pfilter_free(struct perf_filter *pfilter) { if (pfilter->lock) pfilter->o->free_lock(pfilter->lock); if (pfilter->write_data) pfilter->o->free(pfilter->o, pfilter->write_data); if (pfilter->filter) gensio_filter_free_data(pfilter->filter); pfilter->o->free(pfilter->o, pfilter); } static void perf_free(struct gensio_filter *filter) { struct perf_filter *pfilter = filter_to_perf(filter); pfilter_free(pfilter); } static int gensio_perf_filter_func(struct gensio_filter *filter, int op, void *func, void *data, gensiods *count, void *buf, const void *cbuf, gensiods buflen, const char *const *auxdata) { switch (op) { case GENSIO_FILTER_FUNC_SET_CALLBACK: perf_set_callbacks(filter, func, data); return 0; case GENSIO_FILTER_FUNC_UL_READ_PENDING: return perf_ul_read_pending(filter); case GENSIO_FILTER_FUNC_LL_WRITE_PENDING: return perf_ll_write_pending(filter); case GENSIO_FILTER_FUNC_LL_READ_NEEDED: return perf_ll_read_needed(filter); case GENSIO_FILTER_FUNC_CHECK_OPEN_DONE: return perf_check_open_done(filter, data); case GENSIO_FILTER_FUNC_TRY_CONNECT: return perf_try_connect(filter, data); case GENSIO_FILTER_FUNC_TRY_DISCONNECT: return perf_try_disconnect(filter, data); case GENSIO_FILTER_FUNC_UL_WRITE_SG: return perf_ul_write(filter, func, data, count, cbuf, buflen, auxdata); case GENSIO_FILTER_FUNC_LL_WRITE: return perf_ll_write(filter, func, data, count, buf, buflen, auxdata); case GENSIO_FILTER_FUNC_TIMEOUT: return perf_filter_timeout(filter); case GENSIO_FILTER_FUNC_SETUP: return perf_setup(filter); case GENSIO_FILTER_FUNC_CLEANUP: perf_filter_cleanup(filter); return 0; case GENSIO_FILTER_FUNC_IO_ERR: perf_filter_io_err(filter, *((int *) data)); return 0; case GENSIO_FILTER_FUNC_FREE: perf_free(filter); return 0; default: return GE_NOTSUP; } } static struct gensio_filter * gensio_perf_filter_raw_alloc(struct gensio_os_funcs *o, gensiods writebuf_size, gensiods write_len, gensiods expect_len) { struct perf_filter *pfilter; pfilter = o->zalloc(o, sizeof(*pfilter)); if (!pfilter) return NULL; pfilter->o = o; pfilter->writebuf_size = writebuf_size; pfilter->write_len = write_len; pfilter->write_data_left = write_len; pfilter->expect_len = expect_len; pfilter->orig_expect_len = expect_len; pfilter->lock = o->alloc_lock(o); if (!pfilter->lock) goto out_nomem; pfilter->write_data = o->zalloc(o, writebuf_size); if (!pfilter->write_data) goto out_nomem; pfilter->filter = gensio_filter_alloc_data(o, gensio_perf_filter_func, pfilter); if (!pfilter->filter) goto out_nomem; return pfilter->filter; out_nomem: pfilter_free(pfilter); return NULL; } static int gensio_perf_filter_alloc(struct gensio_pparm_info *p, struct gensio_os_funcs *o, const char * const args[], struct gensio_filter **rfilter) { struct gensio_filter *filter; gensiods writebuf_size = 1024; gensiods write_len = 0; gensiods expect_len = 0; unsigned int i; for (i = 0; args && args[i]; i++) { if (gensio_pparm_ds(p, args[i], "writebuf", &writebuf_size) > 0) continue; if (gensio_pparm_ds(p, args[i], "write_len", &write_len) > 0) continue; if (gensio_pparm_ds(p, args[i], "expect_len", &expect_len) > 0) continue; gensio_pparm_unknown_parm(p, args[i]); return GE_INVAL; } filter = gensio_perf_filter_raw_alloc(o, writebuf_size, write_len, expect_len); if (!filter) return GE_NOMEM; *rfilter = filter; return 0; } static int perf_gensio_alloc(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **net) { int err; struct gensio_filter *filter; struct gensio_ll *ll; struct gensio *io; GENSIO_DECLARE_PPGENSIO(p, o, cb, "perf", user_data); err = gensio_perf_filter_alloc(&p, o, args, &filter); if (err) return err; ll = gensio_gensio_ll_alloc(o, child); if (!ll) { gensio_filter_free(filter); return GE_NOMEM; } gensio_ref(child); /* So gensio_ll_free doesn't free the child if fail */ io = base_gensio_alloc(o, ll, filter, child, "perf", cb, user_data); if (!io) { gensio_ll_free(ll); gensio_filter_free(filter); return GE_NOMEM; } gensio_set_is_reliable(io, gensio_is_reliable(child)); gensio_set_is_packet(io, gensio_is_packet(child)); gensio_set_is_authenticated(io, gensio_is_authenticated(child)); gensio_set_is_encrypted(io, gensio_is_encrypted(child)); gensio_set_is_message(io, gensio_is_message(child)); gensio_free(child); /* Lose the ref we acquired. */ *net = io; return 0; } static int str_to_perf_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct gensio *io2; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio(str, o, cb, user_data, &io2); if (err) return err; err = perf_gensio_alloc(io2, args, o, cb, user_data, new_gensio); if (err) gensio_free(io2); return err; } struct perfna_data { struct gensio_accepter *acc; const char **args; struct gensio_os_funcs *o; gensio_accepter_event cb; void *user_data; }; static void perfna_free(void *acc_data) { struct perfna_data *nadata = acc_data; if (nadata->args) gensio_argv_free(nadata->o, nadata->args); nadata->o->free(nadata->o, nadata); } static int perfna_alloc_gensio(void *acc_data, const char * const *iargs, struct gensio *child, struct gensio **rio) { struct perfna_data *nadata = acc_data; return perf_gensio_alloc(child, iargs, nadata->o, NULL, NULL, rio); } static int perfna_new_child(void *acc_data, void **finish_data, struct gensio_filter **filter) { struct perfna_data *nadata = acc_data; GENSIO_DECLARE_PPACCEPTER(p, nadata->o, nadata->cb, "perf", nadata->user_data); return gensio_perf_filter_alloc(&p, nadata->o, nadata->args, filter); } static int perfna_finish_parent(void *acc_data, void *finish_data, struct gensio *io) { gensio_set_attr_from_child(io, gensio_get_child(io, 0)); return 0; } static int gensio_gensio_acc_perf_cb(void *acc_data, int op, void *data1, void *data2, void *data3, const void *data4) { switch (op) { case GENSIO_GENSIO_ACC_ALLOC_GENSIO: return perfna_alloc_gensio(acc_data, data4, data1, data2); case GENSIO_GENSIO_ACC_NEW_CHILD: return perfna_new_child(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FINISH_PARENT: return perfna_finish_parent(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FREE: perfna_free(acc_data); return 0; default: return GE_NOTSUP; } } static int perf_gensio_accepter_alloc(struct gensio_accepter *child, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { struct perfna_data *nadata; int err; nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) return GE_NOMEM; err = gensio_argv_copy(o, args, NULL, &nadata->args); if (err) { o->free(o, nadata); return err; } nadata->o = o; nadata->cb = cb; nadata->user_data = user_data; err = gensio_gensio_accepter_alloc(child, o, "perf", cb, user_data, gensio_gensio_acc_perf_cb, nadata, &nadata->acc); if (err) goto out_err; gensio_acc_set_is_reliable(nadata->acc, gensio_acc_is_reliable(child)); gensio_acc_set_is_packet(nadata->acc, gensio_acc_is_packet(child)); gensio_acc_set_is_message(nadata->acc, gensio_acc_is_message(child)); *accepter = nadata->acc; return 0; out_err: perfna_free(nadata); return err; } static int str_to_perf_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { int err; struct gensio_accepter *acc2 = NULL; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio_accepter(str, o, cb, user_data, &acc2); if (!err) { err = perf_gensio_accepter_alloc(acc2, args, o, cb, user_data, acc); if (err) gensio_acc_free(acc2); } return err; } int gensio_init_perf(struct gensio_os_funcs *o) { int rv; rv = register_filter_gensio(o, "perf", str_to_perf_gensio, perf_gensio_alloc); if (rv) return rv; rv = register_filter_gensio_accepter(o, "perf", str_to_perf_gensio_accepter, perf_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/gensio_certauth.c0000664000175000017500000026423315055560617012602 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 /* On Windows you can use / or \. */ #define DIRSEPS "\\/" #else #define DIRSEPS "/" #endif struct gensio_certauth_filter_data { struct gensio_os_funcs *o; bool is_client; char *CAfilepath; char *keyfile; char *certfile; char *username; char *password; char *service; char *val_2fa; unsigned int len_2fa; bool allow_authfail; bool use_child_auth; bool enable_password; bool require_password; bool do_2fa; /* Ask for two-factor authentication, version 2+ */ /* Amount of time in which the connection process must complete. */ gensio_time con_timeout; /* * The following is only used for testing. so certauth can be run * over stdio for fuzz testing. Do not document. */ bool allow_unencrypted; }; #include #include #include #include #include #include #include #include #include #include #include /* Also in gensio_filter_ssl.c. */ static int gensio_cert_get_name(X509 *cert, char *data, gensiods *datalen) { char *nidstr = NULL, *end; int index = -1, len, tlen, nid; int datasize; X509_NAME *nm; X509_NAME_ENTRY *e; ASN1_STRING *as; unsigned char *strobj; int strobjlen; ASN1_OBJECT *obj; if (!cert) return GE_NOCERT; datasize = *datalen; index = strtol(data, &end, 0); if (*end == ',') nidstr = end + 1; else if (*end) return GE_CERTINVALID; nm = X509_get_subject_name(cert); if (nidstr) { nid = OBJ_sn2nid(nidstr); if (nid == NID_undef) { nid = OBJ_ln2nid(data); if (nid == NID_undef) return GE_CERTINVALID; } index = X509_NAME_get_index_by_NID(nm, nid, index); if (index < 0) return GE_NOTFOUND; } e = X509_NAME_get_entry(nm, index); if (!e) return GE_NOTFOUND; obj = X509_NAME_ENTRY_get_object(e); nid = OBJ_obj2nid(obj); len = snprintf(data, datasize, "%d,%s,", index, OBJ_nid2sn(nid)); as = X509_NAME_ENTRY_get_data(e); strobjlen = ASN1_STRING_to_UTF8(&strobj, as); if (strobjlen < 0) return GE_NOMEM; tlen = strobjlen; if (len + 1 < datasize) { if (strobjlen > datasize - len - 1) strobjlen = datasize - len - 1; memcpy(data + len, strobj, strobjlen); data[strobjlen + len] = '\0'; } len += tlen; OPENSSL_free(strobj); *datalen = len; return 0; } /* Also in gensio_filter_ssl.c. */ static int gensio_cert_to_buf(X509 *cert, char *buf, gensiods *buflen) { BIO *mbio; BUF_MEM *bptr; gensiods len = *buflen, copylen; mbio = BIO_new(BIO_s_mem()); if (!mbio) return GE_NOMEM; if (PEM_write_bio_X509(mbio, cert) == 0) { BIO_free(mbio); return GE_IOERR; } BIO_get_mem_ptr(mbio, &bptr); *buflen = bptr->length; copylen = len; if (copylen > bptr->length) copylen = bptr->length; memcpy(buf, bptr->data, copylen); if (len > copylen) buf[copylen] = '\0'; BIO_free(mbio); return 0; } /* Also in gensio_filter_ssl.c. */ static int gensio_cert_fingerprint(X509 *cert, char *buf, gensiods *buflen) { gensiods len = *buflen, clen; unsigned int i, n, l; unsigned char md[EVP_MAX_MD_SIZE]; if (X509_digest(cert, EVP_sha1(), md, &n) == 0) return GE_NOMEM; clen = snprintf(buf, len, "%2.2X", md[0]); for (i = 1; i < n; i++) { if (clen >= len) l = 0; else l = len - clen; clen += snprintf(buf + clen, l, ":%2.2X", md[i]); } *buflen = clen; return 0; } #if OPENSSL_VERSION_NUMBER < 0x10100000L #define X509_up_ref(x) CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509) static EVP_MD_CTX *EVP_MD_CTX_new(void) { EVP_MD_CTX *c = OPENSSL_malloc(sizeof(*c)); if (c) memset(c, 0, sizeof(*c)); return c; } static void EVP_MD_CTX_free(EVP_MD_CTX *c) { OPENSSL_free(c); } #endif #define GENSIO_CERTAUTH_DATA_SIZE 2048 #define GENSIO_CERTAUTH_CHALLENGE_SIZE 32 #define GENSIO_CERTAUTH_VERSION 4 /* * Passwords are always sent in this size buffer to keep an attacker * from getting the actual password length. */ #define GENSIO_CERTAUTH_PASSWORD_LEN 100 /* * A message consists of the following: * * [ * [ ...] * * The message number is the same as the states below, it is one byte * long. Message elements may come in any order. The element number * is one byte and the element length is a two byte network order * unsigned integer, giving the maximum element data length of 65535 * bytes. */ /* * State machines for both the client and the server, also message * numbers (for values < 100). */ enum certauth_state { /* * Client first sends the hello (containing the version, username, * and optional service and options) and goes into SERVERHELLO. */ CERTAUTH_CLIENT_START = 0, /* * Server waits for CLIENTHELLO. * * The app is called to check the username. If the app says * verification is done, send a SERVERDONE with error result * from the app. * * If apps says to continue verification, send the SERVERHELLO * (containing the version, random challenge, and optional * options) and goes into CHALLENGE_RESPONSE. * * Message contains a VERSION element, an optional USERNAME * element, and an optional SERVICE element. */ CERTAUTH_CLIENTHELLO = 1, /* * Client waits for SERVERHELLO and uses the random challenge to * generate a challenge response and sends challenge response * (containing certificate and challenge response) and goes into * PASSWORD_REQUEST. * * Client may also receive a SERVERDONE in this state if the * authorization is rejected or authorized on username alone. * * Message contains a VERSION element, a CHALLENGE_DATA element, * and an optional AUX_DATA element. AUX_DATA is version 2 or * later. */ CERTAUTH_SERVERHELLO = 2, /* * Client waits for a random amount of time before processing the * random challenge from the server. This is to help with timing * attacks. * * This will be transitioned from with a timer and will process * the challenge and go to PASSWORD_REQUEST. */ CERTAUTH_CLIENTDELAY = 110, /* * Server receives the challenge response verifies the reponse and * the certificate against the CA. * * The app is called before the verification so it can do things * based on certificate data. If the app says * verification is done, send a SERVERDONE with error result * from the app. * * Otherwise the certificate is verified and the challenge * response is checked. If the certificate verifies but the * challenge response fails, fail the connection. If both pass * verification, send a SERVERDONE giving the result and go into * passthrough mode. If the certificate does not verify, send * a PASSWORD_REQUEST (no data) and go into PASSWORD mode. * * Message contains a CERTIFICATE element, a CHALLENGE_RSP * element, and an optional AUX_DATA element. AUX_DATA is version * 2 or later. AUX_DATA has to be here, and not in CLIENTHELLO, * because the client doesn't know the remote version when sending * a CLIENTHELLO. */ CERTAUTH_CHALLENGE_RESPONSE = 3, /* * Client waits for PASSWORD_REQUEST. * * Client may also receive a SERVERDONE in this state if the * authorization is rejected or authorized by the certificate. * * Message contains a PASSWORD_TYPE element to tell how to handle * the request. */ CERTAUTH_PASSWORD_REQUEST = 4, /* * Server waits for a password. When received. the application is * notified of the password. Send a SERVERDONE with error result * from the app. * * Message contains either a PASSWORD_DATA element or a DUMMY_DATA * element and then an optional 2FA_DATA element. */ CERTAUTH_PASSWORD = 5, /* * Client waits for SERVERDONE and goes into passthrough mode if * successful, contains the result. * * Message contains a RESULT element. */ CERTAUTH_SERVERDONE = 6, /* * We are done, just waiting for the data to be written from the * buffer before reporting so. */ CERTAUTH_WAIT_WRITE_DONE = 107, /* * Just pass all the data through. */ CERTAUTH_PASSTHROUGH = 108, /* * Something went wrong, abort. */ CERTAUTH_ERR = 109 }; #define CERTAUTH_STATE_MAX CERTAUTH_SERVERDONE /* * Various message components. * * The contents are given for each one. */ enum certauth_elements { /* * 100 2 <2 byte version number> */ CERTAUTH_VERSION = 100, /* * 101 */ CERTAUTH_USERNAME = 101, /* * Currently not used. */ CERTAUTH_OPTIONS = 102, /* * 103 32 <32 bytes of random data> */ CERTAUTH_CHALLENGE_DATA = 103, /* * 104 */ CERTAUTH_CHALLENGE_RSP = 104, /* * 105 */ CERTAUTH_CERTIFICATE = 105, /* * 106 2 1|2 * * The challenge response is verified, 1 is for success, 2 is for * failure. */ CERTAUTH_RESULT = 106, /* * 107 * * The service is used to tell the server what service the client * wishes to run. It is optional and may be ignored. */ CERTAUTH_SERVICE = 107, /* * 108 100 <100-byte string with password> * * The service is used to transfer a password. */ CERTAUTH_PASSWORD_DATA = 108, /* 109 n * * Dummy data to mask the fact that we are not sending certs or * passwords. */ CERTAUTH_DUMMY_DATA = 109, /* * 110 2 * The bottom two bits is what password data we are asking for, either * send the password (1) or send a dummy (2). Bit 8 requests that a * 2FA_DATA element be sent, also. */ CERTAUTH_PASSWORD_TYPE = 110, /* * 111 <2fa data length n> * * The service is used to transfer 2-factor auth data. Added in version 2. */ CERTAUTH_2FA_DATA = 111, /* * 112 * * Holds a block of generic data. It has no meaning to certauth, * it is used to transfer useful information to the other end. */ CERTAUTH_AUX_DATA = 112, /* * 200 * * This is the last thing in the message. */ CERTAUTH_END = 200 }; #define CERTAUTH_MIN_ELEMENT CERTAUTH_VERSION #define CERTAUTH_MAX_ELEMENT CERTAUTH_AUX_DATA #define CERTAUTH_RESULT_SUCCESS 1 #define CERTAUTH_RESULT_FAILURE 2 #define CERTAUTH_RESULT_ERR 3 /* Request a password. */ #define CERTAUTH_PASSWORD_TYPE_REQ 1 /* Don't send a password, just send dummy data. */ #define CERTAUTH_PASSWORD_TYPE_DUMMY 2 #define CERTAUTH_PASSWORD_TYPE_MASK 0xff /* * Request 2 factor authentication data on top of password or dummy data. * Added in version 2. */ #define CERTAUTH_PASSWORD_TYPE_BIT_2FA (1 << 8) struct certauth_filter { struct gensio_filter *filter; struct gensio_os_funcs *o; bool is_client; enum certauth_state state; struct gensio_lock *lock; /* * If we get an error while reading, hold it here until the try * connect is called. */ int pending_err; /* Version number from the remote end. */ unsigned int version; /* My version number, may be lowered due to openssl capabilities. */ unsigned int my_version; /* Result from the server or local verification. */ unsigned int result; /* Result from the response check. */ unsigned int response_result; /* Certificate verification result, server only. */ bool verified; /* Use authenticated from the child gensio to skip this layer. */ bool use_child_auth; /* Enable password authentication. */ bool enable_password; /* Require password authentication, even if certificate passed. */ bool require_password; /* Enable 2-factor authentication. */ bool do_2fa; /* try_connect() has been called at least once. */ bool started; /* Time to wait for the connection to complete. */ gensio_time con_timeout; /* Absolute time when the connection will time out. */ gensio_time contime_done; char *username; size_t username_len; unsigned int password_req_val; char *password; size_t password_len; bool req_2fa_val; unsigned char *val_2fa; gensiods len_2fa; /* Aux data locally and from the remote end. */ unsigned char *val_aux; gensiods len_aux; unsigned char *val_rem_aux; gensiods len_rem_aux; char *service; size_t service_len; unsigned char *challenge_data; gensiods challenge_data_size; X509 *cert; STACK_OF(X509) *sk_ca; EVP_PKEY *pkey; X509_STORE *verify_store; bool allow_authfail; BUF_MEM cert_buf_mem; BIO *cert_bio; const EVP_MD *rsa_md5; const EVP_MD *sha3_512; const EVP_MD *digest; unsigned char *read_buf; gensiods read_buf_len; gensiods max_read_size; unsigned char *write_buf; gensiods write_buf_len; gensiods write_buf_pos; gensiods max_write_size; /* * Processing for incoming messages. */ unsigned char curr_msg_type; unsigned char curr_elem; unsigned int curr_elem_len; bool curr_elem_len_b1; bool curr_elem_len_b2; bool got_msg; }; #define filter_to_certauth(v) ((struct certauth_filter *) \ gensio_filter_get_user_data(v)) static void certauth_lock(struct certauth_filter *sfilter); static void certauth_unlock(struct certauth_filter *sfilter); /* * This function releases and reclaims the lock, so it can only be * called in places where this is ok. */ static void gca_vlog(struct certauth_filter *f, enum gensio_log_levels l, bool do_ssl_err, char *fmt, va_list ap) { certauth_unlock(f); if (do_ssl_err) { char buf[256], buf2[200]; unsigned long ssl_err = ERR_get_error(); if (!ssl_err) goto no_ssl_err; ERR_error_string_n(ssl_err, buf2, sizeof(buf2)); snprintf(buf, sizeof(buf), "certauth: %s: %s", fmt, buf2); gensio_filter_vlog(f->filter, l, buf, ap); } else { no_ssl_err: gensio_filter_vlog(f->filter, l, fmt, ap); } certauth_lock(f); } static void gca_log_info(struct certauth_filter *f, char *fmt, ...) { va_list ap; va_start(ap, fmt); gca_vlog(f, GENSIO_LOG_INFO, false, fmt, ap); va_end(ap); } static void gca_log_err(struct certauth_filter *f, char *fmt, ...) { va_list ap; va_start(ap, fmt); gca_vlog(f, GENSIO_LOG_ERR, false, fmt, ap); va_end(ap); } static void gca_logs_info(struct certauth_filter *f, char *fmt, ...) { va_list ap; va_start(ap, fmt); gca_vlog(f, GENSIO_LOG_INFO, true, fmt, ap); va_end(ap); } static void gca_logs_err(struct certauth_filter *f, char *fmt, ...) { va_list ap; va_start(ap, fmt); gca_vlog(f, GENSIO_LOG_ERR, true, fmt, ap); va_end(ap); } static void certauth_lock(struct certauth_filter *sfilter) { sfilter->o->lock(sfilter->lock); } static void certauth_unlock(struct certauth_filter *sfilter) { sfilter->o->unlock(sfilter->lock); } static void certauth_set_callbacks(struct gensio_filter *filter, gensio_filter_cb cb, void *cb_data) { /* We don't currently use callbacks. */ } static bool certauth_ul_read_pending(struct gensio_filter *filter) { return false; /* We never have data pending to the upper layer. */ } static bool certauth_ll_write_pending(struct gensio_filter *filter) { struct certauth_filter *sfilter = filter_to_certauth(filter); return sfilter->write_buf_len > 0; } static bool certauth_ll_read_needed(struct gensio_filter *filter) { struct certauth_filter *sfilter = filter_to_certauth(filter); /* * Turn off read when we have a message to process. */ return !sfilter->got_msg; } static int certauth_check_open_done(struct gensio_filter *filter, struct gensio *io) { struct certauth_filter *sfilter = filter_to_certauth(filter); int rv = 0; certauth_lock(sfilter); if (!sfilter->result) sfilter->result = CERTAUTH_RESULT_FAILURE; if (sfilter->result == CERTAUTH_RESULT_SUCCESS) gensio_set_is_authenticated(io, true); else if (sfilter->result == CERTAUTH_RESULT_ERR) rv = GE_AUTHREJECT; else if (sfilter->is_client || !sfilter->allow_authfail) rv = GE_AUTHREJECT; certauth_unlock(sfilter); return rv; } static void certauth_write(struct certauth_filter *sfilter, void *data, unsigned int len) { if (len + sfilter->write_buf_len > sfilter->max_write_size) { gca_log_err(sfilter, "Unable to write data to network"); sfilter->pending_err = GE_TOOBIG; return; } memcpy(sfilter->write_buf + sfilter->write_buf_len, data, len); sfilter->write_buf_len += len; } static void certauth_write_zeros(struct certauth_filter *sfilter, unsigned int len) { if (len + sfilter->write_buf_len > sfilter->max_write_size) { gca_log_err(sfilter, "Unable to write data to network"); sfilter->pending_err = GE_TOOBIG; return; } memset(sfilter->write_buf + sfilter->write_buf_len, 0, len); sfilter->write_buf_len += len; } static void certauth_u16_to_buf(unsigned char *buf, unsigned int v) { buf[0] = (v >> 8) & 0xff; buf[1] = v & 0xff; } static unsigned int certauth_buf_to_u16(unsigned char *buf) { return (((unsigned int) buf[0]) << 8) | buf[1]; } static void certauth_write_byte(struct certauth_filter *sfilter, unsigned char b) { certauth_write(sfilter, &b, 1); } static void certauth_write_u16(struct certauth_filter *sfilter, unsigned int v) { unsigned char d[2]; certauth_u16_to_buf(d, v); certauth_write(sfilter, d, 2); } static gensiods certauth_writeleft(struct certauth_filter *sfilter) { return sfilter->max_write_size - sfilter->write_buf_len; } static void * certauth_writepos(struct certauth_filter *sfilter) { return sfilter->write_buf + sfilter->write_buf_len; } static int certauth_verify_cert(struct certauth_filter *sfilter) { X509_STORE_CTX *cert_store_ctx = NULL; int rv = 0, verify_err; const char *auxdata[] = { NULL, NULL }; cert_store_ctx = X509_STORE_CTX_new(); if (!cert_store_ctx) { rv = GE_NOMEM; goto out_err; } if (!X509_STORE_CTX_init(cert_store_ctx, sfilter->verify_store, sfilter->cert, sfilter->sk_ca)) { rv = GE_NOMEM; goto out_err; } verify_err = X509_verify_cert(cert_store_ctx); if (verify_err <= 0) { verify_err = X509_STORE_CTX_get_error(cert_store_ctx); if (verify_err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY || verify_err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) rv = GE_CERTNOTFOUND; else if (verify_err == X509_V_ERR_CERT_REVOKED) rv = GE_CERTREVOKED; else if (verify_err == X509_V_ERR_CERT_HAS_EXPIRED || verify_err == X509_V_ERR_CRL_HAS_EXPIRED) rv = GE_CERTEXPIRED; else rv = GE_CERTINVALID; } else { verify_err = X509_V_OK; } certauth_unlock(sfilter); if (rv) auxdata[0] = X509_verify_cert_error_string(verify_err); rv = gensio_filter_do_event(sfilter->filter, GENSIO_EVENT_POSTCERT_VERIFY, rv, NULL, NULL, auxdata); certauth_lock(sfilter); if (rv == GE_NOTSUP) { if (verify_err != X509_V_OK) { gca_logs_info(sfilter, "Remote peer certificate verify failed: %s", X509_verify_cert_error_string(verify_err)); rv = GE_NOTSUP; } else { rv = 0; } } if (rv == 0) sfilter->verified = true; out_err: if (cert_store_ctx) X509_STORE_CTX_free(cert_store_ctx); return rv; } static int certauth_add_cert(struct certauth_filter *sfilter) { unsigned int lenpos; certauth_write_byte(sfilter, CERTAUTH_CERTIFICATE); lenpos = sfilter->write_buf_len; sfilter->write_buf_len += 2; sfilter->cert_buf_mem.length = 0; sfilter->cert_buf_mem.data = certauth_writepos(sfilter); sfilter->cert_buf_mem.max = certauth_writeleft(sfilter); BIO_set_mem_buf(sfilter->cert_bio, &sfilter->cert_buf_mem, BIO_NOCLOSE); BIO_set_flags(sfilter->cert_bio, 0); if (PEM_write_bio_X509(sfilter->cert_bio, sfilter->cert) == 0) { gca_logs_err(sfilter, "Failure writing cert to network"); return GE_TOOBIG; } sfilter->write_buf_len += sfilter->cert_buf_mem.length; certauth_u16_to_buf(sfilter->write_buf + lenpos, sfilter->cert_buf_mem.length); return 0; } static int certauth_get_cert(struct certauth_filter *sfilter) { sfilter->cert_buf_mem.length = sfilter->read_buf_len; sfilter->cert_buf_mem.data = (char *) sfilter->read_buf; sfilter->cert_buf_mem.max = sfilter->read_buf_len; BIO_set_mem_buf(sfilter->cert_bio, &sfilter->cert_buf_mem, BIO_NOCLOSE); BIO_set_flags(sfilter->cert_bio, BIO_FLAGS_MEM_RDONLY); sfilter->cert = PEM_read_bio_X509(sfilter->cert_bio, NULL, NULL, NULL); if (!sfilter->cert) { gca_logs_err(sfilter, "Failure reading cert from network"); return GE_NOCERT; } sfilter->sk_ca = sk_X509_new_null(); if (!sfilter->sk_ca) { gca_log_err(sfilter, "Failure allocating CA stack"); return GE_NOMEM; } if (!sk_X509_push(sfilter->sk_ca, sfilter->cert)) { gca_log_err(sfilter, "Failure pushing to CA stack"); return GE_NOMEM; } /* cert is in the stack and held by the user. */ X509_up_ref(sfilter->cert); return 0; } static int v3_certauth_add_challenge_rsp(struct certauth_filter *sfilter) { EVP_MD_CTX *sign_ctx; unsigned int lenpos, len; int rv = 0; #ifdef EVP_PKEY_ED25519 if (EVP_PKEY_base_id(sfilter->pkey) == EVP_PKEY_ED25519) { gca_log_err(sfilter, "Remote end or SSL too old to support ed25519 key"); return GE_KEYINVALID; } #endif certauth_write_byte(sfilter, CERTAUTH_CHALLENGE_RSP); lenpos = sfilter->write_buf_len; sfilter->write_buf_len += 2; /* EVP_PKEY_size() docs say it always returns a positive number. */ if (certauth_writeleft(sfilter) < (gensiods) EVP_PKEY_size(sfilter->pkey)) { gca_log_err(sfilter, "Key too large to fit in the data"); return GE_TOOBIG; } sign_ctx = EVP_MD_CTX_new(); if (!sign_ctx) { gca_log_err(sfilter, "Unable to allocate signature context"); return GE_NOMEM; } if (!EVP_SignInit(sign_ctx, sfilter->digest)) { gca_logs_err(sfilter, "Signature init failed"); goto out_nomem; } if (!EVP_SignUpdate(sign_ctx, sfilter->challenge_data, sfilter->challenge_data_size)) { gca_logs_err(sfilter, "Signature update failed"); goto out_nomem; } if (!EVP_SignUpdate(sign_ctx, sfilter->service, sfilter->service_len)) { gca_logs_err(sfilter, "Signature update (service) failed"); goto out_nomem; } if (!EVP_SignFinal(sign_ctx, certauth_writepos(sfilter), &len, sfilter->pkey)) { gca_logs_err(sfilter, "Signature final failed"); goto out_nomem; } sfilter->write_buf_len += len; certauth_u16_to_buf(sfilter->write_buf + lenpos, len); out: EVP_MD_CTX_free(sign_ctx); return rv; out_nomem: rv = GE_NOMEM; goto out; } static int certauth_add_challenge_rsp(struct certauth_filter *sfilter) { struct gensio_os_funcs *o = sfilter->o; EVP_MD_CTX *sign_ctx; size_t lenpos, len; int rv = 0; unsigned char *to_sign = NULL; gensiods to_sign_size; const EVP_MD *digest = sfilter->digest; if (sfilter->version < 4 || sfilter->my_version < 4) return v3_certauth_add_challenge_rsp(sfilter); #ifdef EVP_PKEY_ED25519 if (EVP_PKEY_base_id(sfilter->pkey) == EVP_PKEY_ED25519) digest = NULL; #endif certauth_write_byte(sfilter, CERTAUTH_CHALLENGE_RSP); lenpos = sfilter->write_buf_len; sfilter->write_buf_len += 2; sign_ctx = EVP_MD_CTX_new(); if (!sign_ctx) { gca_log_err(sfilter, "Unable to allocate signature context"); return GE_NOMEM; } to_sign_size = sfilter->challenge_data_size + sfilter->service_len; to_sign = o->zalloc(o, to_sign_size); if (!to_sign) { gca_logs_err(sfilter, "challeng data allocation failed"); goto out_nomem; } memcpy(to_sign, sfilter->challenge_data, sfilter->challenge_data_size); memcpy(to_sign + sfilter->challenge_data_size, sfilter->service, sfilter->service_len); if (!EVP_DigestSignInit(sign_ctx, NULL, digest, NULL, sfilter->pkey)) { gca_logs_err(sfilter, "Digest signature init failed"); goto out_nomem; } if (!EVP_DigestSign(sign_ctx, NULL, &len, to_sign, to_sign_size)) { gca_logs_err(sfilter, "Digest Signature sign failed"); goto out_nomem; } if (certauth_writeleft(sfilter) < len) { gca_log_err(sfilter, "Signature too large to fit in the data"); return GE_TOOBIG; } if (!EVP_DigestSign(sign_ctx, certauth_writepos(sfilter), &len, to_sign, to_sign_size)) { gca_logs_err(sfilter, "Digest Signature sign(2) failed"); goto out_nomem; } sfilter->write_buf_len += len; certauth_u16_to_buf(sfilter->write_buf + lenpos, len); out: if (to_sign) o->free(o, to_sign); EVP_MD_CTX_free(sign_ctx); return rv; out_nomem: rv = GE_NOMEM; goto out; } static int v3_certauth_check_challenge(struct certauth_filter *sfilter) { EVP_MD_CTX *sign_ctx; int rv = 0; EVP_PKEY *pkey; sign_ctx = EVP_MD_CTX_new(); if (!sign_ctx) { gca_log_err(sfilter, "Unable to allocate verify context"); return GE_NOMEM; } if (!EVP_VerifyInit(sign_ctx, sfilter->digest)) { gca_logs_err(sfilter, "Verify init failed"); goto out_nomem; } if (!EVP_VerifyUpdate(sign_ctx, sfilter->challenge_data, sfilter->challenge_data_size)) { gca_logs_err(sfilter, "Verify update failed"); goto out_nomem; } if (!EVP_VerifyUpdate(sign_ctx, sfilter->service, sfilter->service_len)) { gca_logs_err(sfilter, "Verify update (service) failed"); goto out_nomem; } pkey = X509_get_pubkey(sfilter->cert); if (!pkey) { gca_logs_err(sfilter, "Getting public key failed"); goto out_nomem; } rv = EVP_VerifyFinal(sign_ctx, sfilter->read_buf, sfilter->read_buf_len, pkey); EVP_PKEY_free(pkey); if (rv < 0) { gca_logs_err(sfilter, "Verify final failed"); goto out_nomem; } if (rv) { sfilter->response_result = CERTAUTH_RESULT_SUCCESS; } else { sfilter->response_result = CERTAUTH_RESULT_FAILURE; gca_logs_info(sfilter, "Challenge verify failed"); } rv = 0; out: EVP_MD_CTX_free(sign_ctx); return rv; out_nomem: rv = GE_NOMEM; goto out; } static int certauth_check_challenge(struct certauth_filter *sfilter) { struct gensio_os_funcs *o = sfilter->o; EVP_MD_CTX *sign_ctx; int rv = 0; EVP_PKEY *pkey = NULL; unsigned char *to_sign = NULL; gensiods to_sign_size; const EVP_MD *digest = sfilter->digest; if (sfilter->version < 4 || sfilter->my_version < 4) return v3_certauth_check_challenge(sfilter); sign_ctx = EVP_MD_CTX_new(); if (!sign_ctx) { gca_log_err(sfilter, "Unable to allocate verify context"); return GE_NOMEM; } to_sign_size = sfilter->challenge_data_size + sfilter->service_len; to_sign = o->zalloc(o, to_sign_size); if (!to_sign) { gca_logs_err(sfilter, "challeng data allocation failed"); goto out_nomem; } memcpy(to_sign, sfilter->challenge_data, sfilter->challenge_data_size); memcpy(to_sign + sfilter->challenge_data_size, sfilter->service, sfilter->service_len); pkey = X509_get_pubkey(sfilter->cert); if (!pkey) { gca_logs_err(sfilter, "Getting public key failed"); goto out_nomem; } #ifdef EVP_PKEY_ED25519 if (EVP_PKEY_base_id(pkey) == EVP_PKEY_ED25519) digest = NULL; #endif if (!EVP_DigestVerifyInit(sign_ctx, NULL, digest, NULL, pkey)) { gca_logs_err(sfilter, "Digest verify init failed"); goto out_nomem; } rv = EVP_DigestVerify(sign_ctx, sfilter->read_buf, sfilter->read_buf_len, to_sign, to_sign_size); if (rv != 0 && rv != 1) { gca_logs_err(sfilter, "Verify final failed"); goto out_nomem; } if (rv) { sfilter->response_result = CERTAUTH_RESULT_SUCCESS; } else { sfilter->response_result = CERTAUTH_RESULT_FAILURE; gca_logs_info(sfilter, "Challenge verify failed"); } rv = 0; out: if (pkey) EVP_PKEY_free(pkey); if (to_sign) o->free(o, to_sign); EVP_MD_CTX_free(sign_ctx); return rv; out_nomem: rv = GE_NOMEM; goto out; } static void certauth_add_dummy(struct certauth_filter *sfilter, unsigned int len) { certauth_write_byte(sfilter, CERTAUTH_DUMMY_DATA); certauth_write_u16(sfilter, len); certauth_write_zeros(sfilter, len); } static void certauth_send_server_done(struct certauth_filter *sfilter) { int result = CERTAUTH_RESULT_SUCCESS; if (!sfilter->result) sfilter->result = CERTAUTH_RESULT_FAILURE; if (!sfilter->allow_authfail) result = sfilter->result; if (sfilter->result == CERTAUTH_RESULT_ERR) result = CERTAUTH_RESULT_FAILURE; sfilter->write_buf_len = 0; certauth_write_byte(sfilter, CERTAUTH_SERVERDONE); certauth_write_byte(sfilter, CERTAUTH_RESULT); certauth_write_u16(sfilter, 2); certauth_write_u16(sfilter, result); certauth_write_byte(sfilter, CERTAUTH_END); } static void certauth_start_con_timeout(struct certauth_filter *sfilter) { struct gensio_os_funcs *o = sfilter->o; o->get_monotonic_time(o, &sfilter->contime_done); gensio_time_add(&sfilter->contime_done, &sfilter->con_timeout); } static void set_digest(struct certauth_filter *sfilter) { if (sfilter->version >= 3 && sfilter->my_version >= 3) sfilter->digest = sfilter->sha3_512; else sfilter->digest = sfilter->rsa_md5; } static int certauth_try_connect(struct gensio_filter *filter, gensio_time *timeout, bool was_timeout) { struct certauth_filter *sfilter = filter_to_certauth(filter); struct gensio *io; gensiods len; bool password_requested = false; int err, rv; unsigned int req; int64_t timeout_ns; gensio_time time_now; struct gensio_os_funcs *o = sfilter->o; certauth_lock(sfilter); if (!sfilter->started) { certauth_start_con_timeout(sfilter); sfilter->started = true; } if (sfilter->pending_err) goto out_finish; if (!sfilter->got_msg && !was_timeout) goto out_inprogress2; if (was_timeout && sfilter->state != CERTAUTH_CLIENTDELAY) { gca_log_err(sfilter, "Remote system didn't finish connect in time"); sfilter->pending_err = GE_TIMEDOUT; goto finish_result; } switch (sfilter->state) { case CERTAUTH_CLIENT_START: sfilter->write_buf_len = 0; certauth_write_byte(sfilter, CERTAUTH_CLIENTHELLO); certauth_write_byte(sfilter, CERTAUTH_VERSION); certauth_write_u16(sfilter, 2); certauth_write_u16(sfilter, sfilter->my_version); if (sfilter->username && sfilter->username_len) { certauth_write_byte(sfilter, CERTAUTH_USERNAME); certauth_write_u16(sfilter, sfilter->username_len); certauth_write(sfilter, sfilter->username, sfilter->username_len); } if (sfilter->service && sfilter->service_len) { certauth_write_byte(sfilter, CERTAUTH_SERVICE); certauth_write_u16(sfilter, sfilter->service_len); certauth_write(sfilter, sfilter->service, sfilter->service_len); } certauth_write_byte(sfilter, CERTAUTH_END); sfilter->state = CERTAUTH_SERVERHELLO; break; case CERTAUTH_CLIENTHELLO: if (!sfilter->version) { /* Remote end didn't send version. */ gca_log_err(sfilter, "Remote client didn't send version"); sfilter->pending_err = GE_DATAMISSING; break; } /* Verify support for things requested. */ if (sfilter->do_2fa && sfilter->version < 2) { gca_log_err(sfilter, "2-factor auth requested but other end doesn't have it"); sfilter->pending_err = GE_INVAL; break; } set_digest(sfilter); io = gensio_filter_get_gensio(filter); if (sfilter->use_child_auth) { if (gensio_is_authenticated(io)) { /* * A lower layer has already authenticated, just skip this. */ gca_log_info(sfilter, "Using lower layer authentication"); sfilter->result = CERTAUTH_RESULT_SUCCESS; /* Go ahead and go through the motions. */ } } else { /* Override child setting. */ gensio_set_is_authenticated(io, false); } certauth_unlock(sfilter); err = gensio_filter_do_event(sfilter->filter, GENSIO_EVENT_AUTH_BEGIN, 0, NULL, NULL, NULL); certauth_lock(sfilter); if (!err) /* * Note that we go ahead and do the rest of the messages * even though they may fail, because otherwise we are * broadcasting to the world that we have a login with * no credentials. */ sfilter->result = CERTAUTH_RESULT_SUCCESS; else if (err == GE_AUTHREJECT) { sfilter->result = CERTAUTH_RESULT_ERR; gca_log_err(sfilter, "auth begin rejected connection"); } else if (err != GE_NOTSUP) { gca_log_err(sfilter, "Error from application at auth begin: %s", gensio_err_to_str(err)); sfilter->pending_err = err; goto finish_result; } sfilter->write_buf_len = 0; certauth_write_byte(sfilter, CERTAUTH_SERVERHELLO); certauth_write_byte(sfilter, CERTAUTH_VERSION); certauth_write_u16(sfilter, 2); certauth_write_u16(sfilter, sfilter->my_version); certauth_write_byte(sfilter, CERTAUTH_CHALLENGE_DATA); certauth_write_u16(sfilter, sfilter->challenge_data_size); if (!RAND_bytes(sfilter->challenge_data, sfilter->challenge_data_size)) { gca_log_err(sfilter, "Unable to get random data"); sfilter->pending_err = GE_IOERR; break; } certauth_write(sfilter, sfilter->challenge_data, sfilter->challenge_data_size); if (sfilter->version >= 2 && sfilter->len_aux && sfilter->val_aux) { certauth_write_byte(sfilter, CERTAUTH_AUX_DATA); certauth_write_u16(sfilter, sfilter->len_aux); certauth_write(sfilter, sfilter->val_aux, sfilter->len_aux); } certauth_write_byte(sfilter, CERTAUTH_END); sfilter->state = CERTAUTH_CHALLENGE_RESPONSE; break; case CERTAUTH_SERVERHELLO: if (sfilter->result) /* We got a server done with result, just go on. */ goto handle_server_done; if (!sfilter->challenge_data || !sfilter->version) { gca_log_err(sfilter, "Remote server didn't send challenge data or version"); sfilter->pending_err = GE_DATAMISSING; break; } /* * Start a random timer from 0 to 10ms to obscure the * processing time for avoiding timing attacks. */ if (!RAND_bytes((unsigned char *) &timeout_ns, sizeof(timeout_ns))) { gca_log_err(sfilter, "Unable to get random response delay"); sfilter->pending_err = GE_DATAMISSING; break; } if (timeout_ns < 0) timeout_ns = -timeout_ns; timeout_ns %= GENSIO_MSECS_TO_NSECS(10); timeout->secs = timeout_ns / GENSIO_NSECS_IN_SEC; timeout->nsecs = timeout_ns % GENSIO_NSECS_IN_SEC; sfilter->got_msg = false; sfilter->state = CERTAUTH_CLIENTDELAY; rv = GE_RETRY; goto out; case CERTAUTH_CLIENTDELAY: if (!was_timeout) { if (sfilter->got_msg) { gca_log_err(sfilter, "Got server data while client waiting in challenge delay"); sfilter->pending_err = GE_NOTREADY; goto finish_result; } goto out_inprogress; } set_digest(sfilter); sfilter->write_buf_len = 0; certauth_write_byte(sfilter, CERTAUTH_CHALLENGE_RESPONSE); if (sfilter->cert) { sfilter->pending_err = certauth_add_cert(sfilter); if (sfilter->pending_err) goto finish_result; } else { /* Mask the fact we are not sending a cert. */ certauth_add_dummy(sfilter, 1265); } if (sfilter->pkey) { sfilter->pending_err = certauth_add_challenge_rsp(sfilter); if (sfilter->pending_err) goto finish_result; } else { /* Mask the fact we are not sending a response. */ certauth_add_dummy(sfilter, 256); } if (sfilter->version >= 2 && sfilter->len_aux && sfilter->val_aux) { certauth_write_byte(sfilter, CERTAUTH_AUX_DATA); certauth_write_u16(sfilter, sfilter->len_aux); certauth_write(sfilter, sfilter->val_aux, sfilter->len_aux); } certauth_write_byte(sfilter, CERTAUTH_END); sfilter->state = CERTAUTH_PASSWORD_REQUEST; break; case CERTAUTH_CHALLENGE_RESPONSE: if (sfilter->result == CERTAUTH_RESULT_SUCCESS) /* Already authenticated, just do the dummy password. */ goto try_password; if (!sfilter->cert) { if (!sfilter->enable_password) { sfilter->pending_err = GE_AUTHREJECT; goto finish_result; } /* * Remote end didn't send certificate and/or challenge * response, or the challenge response failed, try * password. */ goto try_password; } if (!!sfilter->cert != !!sfilter->response_result) { gca_log_err(sfilter, "Remote end did not send cert and response"); sfilter->pending_err = GE_PROTOERR; goto finish_result; } if (!sfilter->result) { certauth_unlock(sfilter); err = gensio_filter_do_event(sfilter->filter, GENSIO_EVENT_PRECERT_VERIFY, 0, NULL, NULL, NULL); certauth_lock(sfilter); if (!err) { sfilter->result = CERTAUTH_RESULT_SUCCESS; } else if (err == GE_AUTHREJECT) { gca_log_err(sfilter, "precert verify rejected connection"); sfilter->result = CERTAUTH_RESULT_ERR; } else if (err != GE_NOTSUP) { gca_log_err(sfilter, "Error from application at precert: %s", gensio_err_to_str(err)); sfilter->pending_err = err; goto finish_result; } } err = certauth_verify_cert(sfilter); if (!sfilter->result) { if (err == GE_AUTHREJECT) { gca_log_err(sfilter, "precert verify rejected connection"); sfilter->result = CERTAUTH_RESULT_ERR; } else if (err && err != GE_NOTSUP) { gca_log_err(sfilter, "Error from application at precert: %s", gensio_err_to_str(err)); sfilter->pending_err = err; goto finish_result; } if (sfilter->verified && sfilter->response_result == CERTAUTH_RESULT_SUCCESS) { sfilter->result = CERTAUTH_RESULT_SUCCESS; if (sfilter->require_password) { /* User still wants to do password authentication. */ req = CERTAUTH_PASSWORD_TYPE_REQ; goto try_password2; } } } /* * We may mark it as authenticated, but go through the * password request so an attacker can't tell how the * authentication was done. */ try_password: if (!sfilter->result && sfilter->enable_password) req = CERTAUTH_PASSWORD_TYPE_REQ; else req = CERTAUTH_PASSWORD_TYPE_DUMMY; try_password2: /* Request 2 factor authentication data. */ if (sfilter->do_2fa) req |= CERTAUTH_PASSWORD_TYPE_BIT_2FA; sfilter->write_buf_len = 0; certauth_write_byte(sfilter, CERTAUTH_PASSWORD_REQUEST); certauth_write_byte(sfilter, CERTAUTH_PASSWORD_TYPE); certauth_write_u16(sfilter, 2); certauth_write_u16(sfilter, req); certauth_write_byte(sfilter, CERTAUTH_END); sfilter->state = CERTAUTH_PASSWORD; break; case CERTAUTH_PASSWORD_REQUEST: if (!sfilter->password_req_val) { gca_log_err(sfilter, "Remote client didn't send request value"); sfilter->pending_err = GE_DATAMISSING; goto finish_result; } sfilter->write_buf_len = 0; if (sfilter->password_req_val != CERTAUTH_PASSWORD_TYPE_REQ) { certauth_write_byte(sfilter, CERTAUTH_PASSWORD); certauth_add_dummy(sfilter, sfilter->password_len); goto password_done; } if (!sfilter->enable_password) { /* * If we don't have passwords enabled but the other end * requests, send all zeros. */ certauth_write_byte(sfilter, CERTAUTH_PASSWORD); certauth_write_byte(sfilter, CERTAUTH_PASSWORD_DATA); certauth_write_u16(sfilter, sfilter->password_len); if (sfilter->password_len) certauth_write_zeros(sfilter, sfilter->password_len); goto password_done; } if (!*sfilter->password) { /* Empty password, ask the user. */ gensiods dummy_len = sfilter->password_len; certauth_unlock(sfilter); err = gensio_filter_do_event(sfilter->filter, GENSIO_EVENT_REQUEST_PASSWORD, 0, (unsigned char *) sfilter->password, &dummy_len, NULL); certauth_lock(sfilter); if (err) { memset(sfilter->password, 0, sfilter->password_len); if (err != GE_NOTSUP) { gca_log_err(sfilter, "Error fetching password: %s", gensio_err_to_str(err)); sfilter->pending_err = err; goto finish_result; } } password_requested = true; } certauth_write_byte(sfilter, CERTAUTH_PASSWORD); certauth_write_byte(sfilter, CERTAUTH_PASSWORD_DATA); certauth_write_u16(sfilter, sfilter->password_len); if (sfilter->password_len) certauth_write(sfilter, sfilter->password, sfilter->password_len); if (password_requested) memset(sfilter->password, 0, sfilter->password_len); password_done: if (sfilter->val_2fa) { if (sfilter->version < 2) { gca_log_err(sfilter, "2-factor auth given, but server doesn't support it"); sfilter->pending_err = GE_INVAL; goto finish_result; } goto send_2fa; } if (!sfilter->req_2fa_val) goto password_end; password_requested = false; if (!sfilter->val_2fa) { /* Empty 2fa data, ask the user. */ certauth_unlock(sfilter); err = gensio_filter_do_event(sfilter->filter, GENSIO_EVENT_REQUEST_2FA, 0, (unsigned char *) &sfilter->val_2fa, &sfilter->len_2fa, NULL); certauth_lock(sfilter); if (err) { if (err != GE_NOTSUP) { gca_log_err(sfilter, "Error fetching 2-factor auth: %s", gensio_err_to_str(err)); sfilter->pending_err = err; goto finish_result; } } password_requested = true; if (sfilter->len_2fa > 65535 || sfilter->len_2fa < 1) { gca_log_err(sfilter, "2-factor auth data bad size: %lld", (unsigned long long) sfilter->len_2fa); sfilter->pending_err = GE_TOOBIG; goto clear_2fa; } } send_2fa: certauth_write_byte(sfilter, CERTAUTH_2FA_DATA); certauth_write_u16(sfilter, sfilter->len_2fa); if (sfilter->len_2fa) certauth_write(sfilter, sfilter->val_2fa, sfilter->len_2fa); clear_2fa: if (password_requested) { memset(sfilter->val_2fa, 0, sfilter->len_2fa); sfilter->o->free(sfilter->o, sfilter->val_2fa); sfilter->val_2fa = NULL; sfilter->len_2fa = 0; } if (sfilter->pending_err) goto finish_result; password_end: certauth_write_byte(sfilter, CERTAUTH_END); sfilter->state = CERTAUTH_SERVERDONE; break; case CERTAUTH_PASSWORD: if (sfilter->do_2fa && !sfilter->val_2fa) { /* Remote end didn't send 2fa and we requested one. */ gca_log_err(sfilter, "Remote client didn't send 2fa data"); sfilter->pending_err = GE_DATAMISSING; goto finish_result; } if (sfilter->result && !sfilter->require_password) { /* Already verified by certificate, the password was for show. */ if (sfilter->val_2fa && sfilter->result == CERTAUTH_RESULT_SUCCESS) { sfilter->result = 0; goto check_2fa; } goto finish_result; } if ((sfilter->enable_password || sfilter->require_password) && !sfilter->password) { /* Remote end didn't send a password and we requested one. */ gca_log_err(sfilter, "Remote client didn't send password"); sfilter->pending_err = GE_DATAMISSING; goto finish_result; } if (!sfilter->password || !*sfilter->password) goto finish_result; len = sfilter->password_len; certauth_unlock(sfilter); err = gensio_filter_do_event(sfilter->filter, GENSIO_EVENT_PASSWORD_VERIFY, 0, (unsigned char *) sfilter->password, &len, NULL); certauth_lock(sfilter); if (sfilter->state != CERTAUTH_PASSWORD) /* * Either something went wrong, or the user called * GENSIO_CONTROL_FINISH_INIT. We just exit in either * case. */ goto out_finish; memset(sfilter->password, 0, sfilter->password_len); if (!err) { sfilter->result = CERTAUTH_RESULT_SUCCESS; } else if (err == GE_CERTINVALID) { gca_log_err(sfilter, "Application rejected password"); } else if (err != GE_NOTSUP) { gca_log_err(sfilter, "Error from application at password: %s", gensio_err_to_str(err)); sfilter->pending_err = err; } if (!sfilter->do_2fa) goto finish_result; check_2fa: len = sfilter->len_2fa; certauth_unlock(sfilter); err = gensio_filter_do_event(sfilter->filter, GENSIO_EVENT_2FA_VERIFY, 0, (unsigned char *) sfilter->val_2fa, &len, NULL); certauth_lock(sfilter); if (sfilter->state != CERTAUTH_PASSWORD) /* * Either something went wrong, or the user called * GENSIO_CONTROL_FINISH_INIT. We just exit in either * case. */ goto out_finish; memset(sfilter->val_2fa, 0, sfilter->len_2fa); sfilter->o->free(sfilter->o, sfilter->val_2fa); sfilter->val_2fa = NULL; sfilter->len_2fa = 0; if (!err) { sfilter->result = CERTAUTH_RESULT_SUCCESS; } else if (err == GE_CERTINVALID) { gca_log_err(sfilter, "Application rejected 2-factor auth"); } else if (err != GE_NOTSUP) { gca_log_err(sfilter, "Error from application at 2-factor auth: %s", gensio_err_to_str(err)); sfilter->pending_err = err; } finish_result: certauth_send_server_done(sfilter); if (sfilter->pending_err) { sfilter->state = CERTAUTH_ERR; goto out_finish; } sfilter->state = CERTAUTH_WAIT_WRITE_DONE; /* * Leave got_msg enabled so we won't read any more until we go * to passthrough state. Don't start the timer in this state. */ goto out_inprogress2; case CERTAUTH_SERVERDONE: if (!sfilter->result) { /* Remote end didn't send result. */ gca_log_err(sfilter, "Remote server didn't send result"); sfilter->pending_err = GE_DATAMISSING; goto out_finish; } handle_server_done: if (sfilter->result != CERTAUTH_RESULT_SUCCESS) { sfilter->pending_err = GE_AUTHREJECT; goto out_finish; } sfilter->state = CERTAUTH_PASSTHROUGH; goto out_finish; case CERTAUTH_WAIT_WRITE_DONE: if (sfilter->write_buf_len == 0) { sfilter->state = CERTAUTH_PASSTHROUGH; goto out_finish; } goto out_inprogress; default: assert(false); } sfilter->got_msg = false; out_inprogress: o->get_monotonic_time(o, &time_now); timeout_ns = gensio_time_diff_nsecs(&sfilter->contime_done, &time_now); if (timeout_ns < 0) timeout_ns = 0; timeout->secs = timeout_ns / GENSIO_NSECS_IN_SEC; timeout->nsecs = timeout_ns % GENSIO_NSECS_IN_SEC; rv = GE_RETRY; goto out; out_inprogress2: rv = GE_INPROGRESS; goto out; out_finish: rv = sfilter->pending_err; out: certauth_unlock(sfilter); return rv; } static int certauth_try_disconnect(struct gensio_filter *filter, gensio_time *timeout) { return 0; } static int certauth_ul_write(struct gensio_filter *filter, gensio_ul_filter_data_handler handler, void *cb_data, gensiods *rcount, const struct gensio_sg *isg, gensiods sglen, const char *const *auxdata) { struct certauth_filter *sfilter = filter_to_certauth(filter); int rv = 0; certauth_lock(sfilter); if (isg) { if (sfilter->state != CERTAUTH_PASSTHROUGH || sfilter->pending_err) rv = GE_NOTREADY; else rv = handler(cb_data, rcount, isg, sglen, auxdata); if (rv) goto out_unlock; } if (sfilter->write_buf_len) { gensiods count = 0; struct gensio_sg sg = { sfilter->write_buf + sfilter->write_buf_pos, sfilter->write_buf_len - sfilter->write_buf_pos }; rv = handler(cb_data, &count, &sg, 1, auxdata); if (rv) goto out_unlock; if (count + sfilter->write_buf_pos >= sfilter->write_buf_len) { sfilter->write_buf_len = 0; sfilter->write_buf_pos = 0; } else { sfilter->write_buf_pos += count; } } out_unlock: certauth_unlock(sfilter); return rv; } static unsigned int limited_strlen(const char *str, unsigned int max) { unsigned int i; for (i = 0; i < max; i++) { if (!*str) return i; } return i; } static void certauth_handle_new_element(struct certauth_filter *sfilter) { struct gensio_os_funcs *o = sfilter->o; switch (sfilter->curr_elem) { case CERTAUTH_VERSION: if (sfilter->version) { gca_log_err(sfilter, "Version received when already set"); sfilter->pending_err = GE_PROTOERR; break; } if (sfilter->curr_elem_len != 2) { gca_log_err(sfilter, "Version size not 2"); sfilter->pending_err = GE_PROTOERR; } else { sfilter->version = certauth_buf_to_u16(sfilter->read_buf); if (!sfilter->version) { gca_log_err(sfilter, "Version was zero"); sfilter->pending_err = GE_PROTOERR; } } break; case CERTAUTH_USERNAME: if (sfilter->username) { gca_log_err(sfilter, "Username received when already set"); sfilter->pending_err = GE_PROTOERR; break; } sfilter->username = o->zalloc(o, sfilter->curr_elem_len + 1); sfilter->username_len = sfilter->curr_elem_len; if (!sfilter->username) { gca_log_err(sfilter, "Unable to allocate memory for username"); sfilter->pending_err = GE_NOMEM; } else { memcpy(sfilter->username, sfilter->read_buf, sfilter->curr_elem_len); } break; case CERTAUTH_SERVICE: if (sfilter->service) { gca_log_err(sfilter, "Service received when already set"); sfilter->pending_err = GE_PROTOERR; break; } sfilter->service = o->zalloc(o, sfilter->curr_elem_len + 1); sfilter->service_len = sfilter->curr_elem_len; if (!sfilter->service) { gca_log_err(sfilter, "Unable to allocate memory for service"); sfilter->pending_err = GE_NOMEM; } else { memcpy(sfilter->service, sfilter->read_buf, sfilter->curr_elem_len); } break; case CERTAUTH_PASSWORD_TYPE: if (sfilter->password_req_val) { gca_log_err(sfilter, "password req received when already set"); sfilter->pending_err = GE_PROTOERR; break; } if (sfilter->curr_elem_len != 2) { gca_log_err(sfilter, "password req size not 2"); sfilter->pending_err = GE_PROTOERR; } else { sfilter->password_req_val = certauth_buf_to_u16(sfilter->read_buf); sfilter->req_2fa_val = (sfilter->password_req_val & CERTAUTH_PASSWORD_TYPE_BIT_2FA); sfilter->password_req_val &= CERTAUTH_PASSWORD_TYPE_MASK; if (!sfilter->password_req_val) { gca_log_err(sfilter, "password req was zero"); sfilter->pending_err = GE_PROTOERR; } } break; case CERTAUTH_PASSWORD_DATA: if (sfilter->password) { gca_log_err(sfilter, "Password received when already set"); sfilter->pending_err = GE_PROTOERR; break; } sfilter->password_len = limited_strlen((char *) sfilter->read_buf, sfilter->curr_elem_len); sfilter->password = o->zalloc(o, sfilter->password_len + 1); if (!sfilter->password) { gca_log_err(sfilter, "Unable to allocate memory for password"); sfilter->pending_err = GE_NOMEM; } else { memcpy(sfilter->password, sfilter->read_buf, sfilter->password_len); } break; case CERTAUTH_2FA_DATA: if (sfilter->len_2fa) { gca_log_err(sfilter, "2-factor auth received when already set"); sfilter->pending_err = GE_PROTOERR; break; } sfilter->len_2fa = sfilter->curr_elem_len; sfilter->val_2fa = o->zalloc(o, sfilter->len_2fa + 1); if (!sfilter->val_2fa) { gca_log_err(sfilter, "Unable to allocate memory for 2-factor auth"); sfilter->pending_err = GE_NOMEM; } else { memcpy(sfilter->val_2fa, sfilter->read_buf, sfilter->len_2fa); } break; case CERTAUTH_AUX_DATA: if (sfilter->len_rem_aux) { gca_log_err(sfilter, "Remote aux data received when already set"); sfilter->pending_err = GE_PROTOERR; break; } sfilter->len_rem_aux = sfilter->curr_elem_len; sfilter->val_rem_aux = o->zalloc(o, sfilter->len_rem_aux + 1); if (!sfilter->val_rem_aux) { gca_log_err(sfilter, "Unable to allocate memory for remote aux"); sfilter->pending_err = GE_NOMEM; } else { memcpy(sfilter->val_rem_aux, sfilter->read_buf, sfilter->len_rem_aux); } break; case CERTAUTH_OPTIONS: break; case CERTAUTH_CHALLENGE_DATA: if (sfilter->challenge_data) { gca_log_err(sfilter, "Challenge data received when already set"); sfilter->pending_err = GE_PROTOERR; break; } sfilter->challenge_data = o->zalloc(o, sfilter->curr_elem_len); sfilter->challenge_data_size = sfilter->curr_elem_len; if (!sfilter->challenge_data) { gca_log_err(sfilter, "Unable to allocate memory for challenge"); sfilter->pending_err = GE_NOMEM; } else { memcpy(sfilter->challenge_data, sfilter->read_buf, sfilter->curr_elem_len); } break; case CERTAUTH_CHALLENGE_RSP: if (sfilter->response_result) { gca_log_err(sfilter, "Challenge response received when already set"); sfilter->pending_err = GE_PROTOERR; break; } sfilter->pending_err = certauth_check_challenge(sfilter); break; case CERTAUTH_CERTIFICATE: if (sfilter->cert) { gca_log_err(sfilter, "Certificate received when already set"); sfilter->pending_err = GE_PROTOERR; break; } sfilter->pending_err = certauth_get_cert(sfilter); break; case CERTAUTH_RESULT: if (sfilter->result) { gca_log_err(sfilter, "Result received when already set"); sfilter->pending_err = GE_PROTOERR; break; } if (sfilter->curr_elem_len != 2) { gca_log_err(sfilter, "Result size not 2"); sfilter->pending_err = GE_PROTOERR; } else { sfilter->result = certauth_buf_to_u16(sfilter->read_buf); if (!sfilter->result) { gca_log_err(sfilter, "Result value was zero"); sfilter->pending_err = GE_PROTOERR; } } break; case CERTAUTH_DUMMY_DATA: /* Just ignore it. */ break; default: break; } } static int certauth_ll_write(struct gensio_filter *filter, gensio_ll_filter_data_handler handler, void *cb_data, gensiods *rcount, unsigned char *buf, gensiods buflen, const char *const *auxdata) { struct certauth_filter *sfilter = filter_to_certauth(filter); int err = 0; unsigned char *obuf = buf; gensiods elemleft; if (buflen == 0) goto out; certauth_lock(sfilter); if (sfilter->state == CERTAUTH_PASSTHROUGH) { certauth_unlock(sfilter); err = gensio_filter_do_event(sfilter->filter, GENSIO_EVENT_READ, 0, buf, &buflen, auxdata); if (rcount) *rcount = buflen; return err; } if (gensio_str_in_auxdata(auxdata, "oob")) { /* Ignore oob data. */ if (rcount) *rcount = buflen; goto out_unlock; } if (sfilter->pending_err) { if (rcount) *rcount = buflen; goto out_unlock; } if (!sfilter->curr_msg_type) { sfilter->curr_msg_type = *buf; buf++; buflen--; if (sfilter->curr_msg_type > CERTAUTH_STATE_MAX) { gca_log_err(sfilter, "Invalid message type: %d", sfilter->curr_msg_type); sfilter->pending_err = GE_PROTOERR; goto out_unlock; } sfilter->curr_elem = 0; sfilter->curr_elem_len_b1 = false; sfilter->curr_elem_len_b2 = false; sfilter->read_buf_len = 0; if (sfilter->is_client && sfilter->curr_msg_type == CERTAUTH_SERVERDONE) { /* We allow server done in any state. */ sfilter->state = CERTAUTH_SERVERDONE; } else if (sfilter->curr_msg_type != sfilter->state) { gca_log_err(sfilter, "Expected message type %d, got %d", sfilter->state, sfilter->curr_msg_type); sfilter->pending_err = GE_PROTOERR; goto out_unlock; } } if (buflen == 0) goto out_unlock; restart: if (!sfilter->curr_elem) { sfilter->curr_elem = *buf; buf++; buflen--; if (sfilter->curr_elem == CERTAUTH_END) { sfilter->curr_msg_type = 0; sfilter->got_msg = true; goto out_unlock; } if (sfilter->curr_elem > CERTAUTH_MAX_ELEMENT || sfilter->curr_elem < CERTAUTH_MIN_ELEMENT) { gca_log_err(sfilter, "Invalid message element: %d", sfilter->curr_elem); sfilter->pending_err = GE_PROTOERR; goto out_unlock; } } if (buflen == 0) goto out_unlock; if (!sfilter->curr_elem_len_b1) { sfilter->curr_elem_len_b1 = true; sfilter->curr_elem_len = ((unsigned int) (*buf)) << 8; buf++; buflen--; } if (buflen == 0) goto out_unlock; if (!sfilter->curr_elem_len_b2) { sfilter->curr_elem_len_b2 = true; sfilter->curr_elem_len |= *buf; if (!sfilter->curr_elem_len || sfilter->curr_elem_len > sfilter->max_read_size) { gca_log_err(sfilter, "Element type %d was too large: %d", sfilter->curr_elem, sfilter->curr_elem_len); sfilter->pending_err = GE_PROTOERR; goto out_unlock; } buf++; buflen--; } elemleft = sfilter->curr_elem_len - sfilter->read_buf_len; if (buflen >= elemleft) { memcpy(sfilter->read_buf + sfilter->read_buf_len, buf, elemleft); buflen -= elemleft; buf += elemleft; sfilter->read_buf_len += elemleft; certauth_handle_new_element(sfilter); sfilter->curr_elem = 0; sfilter->curr_elem_len_b1 = false; sfilter->curr_elem_len_b2 = false; sfilter->read_buf_len = 0; goto restart; } else { memcpy(sfilter->read_buf + sfilter->read_buf_len, buf, buflen); sfilter->read_buf_len += buflen; buf += buflen; buflen = 0; } out_unlock: err = sfilter->pending_err; certauth_unlock(sfilter); out: if (rcount) *rcount = buf - obuf; return err; } static int certauth_setup(struct gensio_filter *filter) { struct certauth_filter *sfilter = filter_to_certauth(filter); gensio_time tv_rand; /* Make sure the random number generator is seeded. */ sfilter->o->get_monotonic_time(sfilter->o, &tv_rand); tv_rand.secs += tv_rand.nsecs; RAND_add(&tv_rand.secs, sizeof(tv_rand.secs), 0); return 0; } static void certauth_cleanup(struct gensio_filter *filter) { struct certauth_filter *sfilter = filter_to_certauth(filter); struct gensio_os_funcs *o = sfilter->o; if (sfilter->is_client) { if (sfilter->challenge_data) o->free(o, sfilter->challenge_data); sfilter->challenge_data = NULL; memset(sfilter->password, 0, sfilter->password_len); } else { if (sfilter->cert) X509_free(sfilter->cert); if (sfilter->sk_ca) sk_X509_pop_free(sfilter->sk_ca, X509_free); sfilter->cert = NULL; sfilter->sk_ca = NULL; if (sfilter->password) memset(sfilter->password, 0, sfilter->password_len); if (!sfilter->is_client && sfilter->password) { o->free(o, sfilter->password); sfilter->password = NULL; sfilter->password_len = 0; } if (sfilter->username) o->free(o, sfilter->username); sfilter->username = NULL; sfilter->username_len = 0; if (sfilter->service) o->free(o, sfilter->service); sfilter->service = NULL; sfilter->service_len = 0; } if (sfilter->val_2fa) o->free(o, sfilter->val_2fa); sfilter->val_2fa = NULL; sfilter->len_2fa = 0; if (sfilter->val_aux) o->free(o, sfilter->val_aux); sfilter->val_aux = NULL; sfilter->len_aux = 0; if (sfilter->val_rem_aux) o->free(o, sfilter->val_rem_aux); sfilter->val_rem_aux = NULL; sfilter->len_rem_aux = 0; sfilter->pending_err = 0; sfilter->password_req_val = 0; sfilter->read_buf_len = 0; sfilter->write_buf_len = 0; sfilter->write_buf_pos = 0; sfilter->version = 0; sfilter->result = 0; sfilter->response_result = 0; sfilter->verified = false; } static void sfilter_free(struct certauth_filter *sfilter) { struct gensio_os_funcs *o = sfilter->o; if (sfilter->cert) X509_free(sfilter->cert); if (sfilter->sk_ca) sk_X509_pop_free(sfilter->sk_ca, X509_free); if (sfilter->cert_bio) BIO_free(sfilter->cert_bio); if (sfilter->lock) o->free_lock(sfilter->lock); if (sfilter->read_buf) { memset(sfilter->read_buf, 0, sfilter->max_read_size); o->free(o, sfilter->read_buf); } if (sfilter->write_buf) o->free(o, sfilter->write_buf); if (sfilter->pkey) EVP_PKEY_free(sfilter->pkey); if (sfilter->password) { memset(sfilter->password, 0, sfilter->password_len); o->free(o, sfilter->password); } if (sfilter->username) o->free(o, sfilter->username); if (sfilter->service) o->free(o, sfilter->service); if (sfilter->challenge_data) o->free(o, sfilter->challenge_data); if (sfilter->filter) gensio_filter_free_data(sfilter->filter); if (sfilter->verify_store) X509_STORE_free(sfilter->verify_store); o->free(o, sfilter); } static void certauth_free(struct gensio_filter *filter) { struct certauth_filter *sfilter = filter_to_certauth(filter); sfilter_free(sfilter); } static int certauth_filter_control(struct gensio_filter *filter, bool get, int op, char *data, gensiods *datalen) { struct certauth_filter *sfilter = filter_to_certauth(filter); X509_STORE *store; char *CApath = NULL, *CAfile = NULL; int rv = 0; switch (op) { case GENSIO_CONTROL_GET_PEER_CERT_NAME: if (!get) return GE_NOTSUP; return gensio_cert_get_name(sfilter->cert, data, datalen); case GENSIO_CONTROL_CERT: if (!get) return GE_NOTSUP; if (!sfilter->cert) return GE_NOTFOUND; return gensio_cert_to_buf(sfilter->cert, data, datalen); case GENSIO_CONTROL_USERNAME: { certauth_lock(sfilter); if (get) { if (!sfilter->username) { rv = GE_DATAMISSING; goto out_username; } *datalen = snprintf(data, *datalen, "%s", sfilter->username); } else { char *newusername = NULL; if (data) { newusername = gensio_strdup(sfilter->o, data); if (!newusername) { rv = GE_NOMEM; goto out_username; } } if (sfilter->username) sfilter->o->free(sfilter->o, sfilter->username); sfilter->username = newusername; } out_username: certauth_unlock(sfilter); return rv; } case GENSIO_CONTROL_PASSWORD: { certauth_lock(sfilter); if (get) { if (!sfilter->password) { rv = GE_DATAMISSING; goto out_username; } *datalen = snprintf(data, *datalen, "%s", sfilter->password); } else { char *newpw = NULL; if (data) { newpw = gensio_strdup(sfilter->o, data); if (!newpw) { rv = GE_NOMEM; goto out_pw; } } if (sfilter->password) sfilter->o->free(sfilter->o, sfilter->password); sfilter->password = newpw; } out_pw: certauth_unlock(sfilter); return rv; } case GENSIO_CONTROL_2FA: { gensiods len; certauth_lock(sfilter); if (get) { if (!sfilter->val_2fa) { rv = GE_DATAMISSING; goto out_username; } len = sfilter->len_2fa; if (len > *datalen) len = *datalen; memcpy(data, sfilter->val_2fa, len); *datalen = sfilter->len_2fa; } else { unsigned char *new2fa = NULL; if (*datalen == 0) data = NULL; if (data) { new2fa = sfilter->o->zalloc(sfilter->o, *datalen); if (!new2fa) { rv = GE_NOMEM; goto out_2fa; } memcpy(new2fa, data, *datalen); } if (sfilter->val_2fa) sfilter->o->free(sfilter->o, sfilter->val_2fa); sfilter->val_2fa = new2fa; sfilter->len_2fa = *datalen; } out_2fa: certauth_unlock(sfilter); return rv; } case GENSIO_CONTROL_AUX_DATA: { gensiods len; certauth_lock(sfilter); if (get) { if (!sfilter->val_aux) { rv = GE_DATAMISSING; goto out_username; } len = sfilter->len_aux; if (len > *datalen) len = *datalen; memcpy(data, sfilter->val_aux, len); *datalen = sfilter->len_aux; } else { unsigned char *newaux = NULL; if (*datalen == 0) data = NULL; if (data) { newaux = sfilter->o->zalloc(sfilter->o, *datalen); if (!newaux) { rv = GE_NOMEM; goto out_aux; } memcpy(newaux, data, *datalen); } if (sfilter->val_aux) sfilter->o->free(sfilter->o, sfilter->val_aux); sfilter->val_aux = newaux; sfilter->len_aux = *datalen; } out_aux: certauth_unlock(sfilter); return rv; } case GENSIO_CONTROL_REM_AUX_DATA: { gensiods len; certauth_lock(sfilter); if (get) { if (!sfilter->val_rem_aux) { rv = GE_DATAMISSING; goto out_username; } len = sfilter->len_rem_aux; if (len > *datalen) len = *datalen; memcpy(data, sfilter->val_rem_aux, len); *datalen = sfilter->len_rem_aux; } else { unsigned char *newrem_aux = NULL; if (*datalen == 0) data = NULL; if (data) { newrem_aux = sfilter->o->zalloc(sfilter->o, *datalen); if (!newrem_aux) { rv = GE_NOMEM; goto out_rem_aux; } memcpy(newrem_aux, data, *datalen); } if (sfilter->val_rem_aux) sfilter->o->free(sfilter->o, sfilter->val_rem_aux); sfilter->val_rem_aux = newrem_aux; sfilter->len_rem_aux = *datalen; } out_rem_aux: certauth_unlock(sfilter); return rv; } case GENSIO_CONTROL_SERVICE: if (get) { gensiods to_copy; if (!sfilter->service) return GE_DATAMISSING; to_copy = sfilter->service_len; if (to_copy > *datalen) to_copy = *datalen; memcpy(data, sfilter->service, to_copy); *datalen = sfilter->service_len; } else { char *new_service = sfilter->o->zalloc(sfilter->o, *datalen); if (!new_service) return GE_NOMEM; memcpy(new_service, data, *datalen); if (sfilter->service) sfilter->o->free(sfilter->o, sfilter->service); sfilter->service = new_service; sfilter->service_len = *datalen; } return 0; case GENSIO_CONTROL_CERT_AUTH: if (get) return GE_NOTSUP; store = X509_STORE_new(); if (!store) return GE_NOMEM; if (strchr(DIRSEPS, data[strlen(data) - 1])) CApath = data; else CAfile = data; if (!X509_STORE_load_locations(store, CAfile, CApath)) { X509_STORE_free(store); return GE_CERTNOTFOUND; } certauth_lock(sfilter); if (sfilter->verify_store) X509_STORE_free(sfilter->verify_store); sfilter->verify_store = store; certauth_unlock(sfilter); return 0; case GENSIO_CONTROL_CERT_FINGERPRINT: if (!get) return GE_NOTSUP; if (!sfilter->cert) return GE_NOTFOUND; return gensio_cert_fingerprint(sfilter->cert, data, datalen); default: return GE_NOTSUP; } } static int gensio_certauth_filter_func(struct gensio_filter *filter, int op, void *func, void *data, gensiods *count, void *buf, const void *cbuf, gensiods buflen, const char *const *auxdata) { switch (op) { case GENSIO_FILTER_FUNC_SET_CALLBACK: certauth_set_callbacks(filter, func, data); return 0; case GENSIO_FILTER_FUNC_UL_READ_PENDING: return certauth_ul_read_pending(filter); case GENSIO_FILTER_FUNC_LL_WRITE_PENDING: return certauth_ll_write_pending(filter); case GENSIO_FILTER_FUNC_LL_READ_NEEDED: return certauth_ll_read_needed(filter); case GENSIO_FILTER_FUNC_CHECK_OPEN_DONE: return certauth_check_open_done(filter, data); case GENSIO_FILTER_FUNC_TRY_CONNECT: return certauth_try_connect(filter, data, buflen); case GENSIO_FILTER_FUNC_TRY_DISCONNECT: return certauth_try_disconnect(filter, data); case GENSIO_FILTER_FUNC_UL_WRITE_SG: return certauth_ul_write(filter, func, data, count, cbuf, buflen, buf); case GENSIO_FILTER_FUNC_LL_WRITE: return certauth_ll_write(filter, func, data, count, buf, buflen, NULL); case GENSIO_FILTER_FUNC_SETUP: return certauth_setup(filter); case GENSIO_FILTER_FUNC_CLEANUP: certauth_cleanup(filter); return 0; case GENSIO_FILTER_FUNC_FREE: certauth_free(filter); return 0; case GENSIO_FILTER_FUNC_CONTROL: return certauth_filter_control(filter, *((bool *) cbuf), buflen, data, count); case GENSIO_FILTER_FUNC_TIMEOUT: default: return GE_NOTSUP; } } static int gensio_certauth_filter_raw_alloc(struct gensio_os_funcs *o, bool is_client, X509_STORE *store, X509 *cert, STACK_OF(X509) *sk_ca, EVP_PKEY *pkey, const char *username, const char *password, const char *val_2fa, gensiods len_2fa, const char *service, bool allow_authfail, bool use_child_auth, bool enable_password, bool require_password, bool do_2fa, gensio_time con_timeout, struct gensio_filter **rfilter) { struct certauth_filter *sfilter; int rv; sfilter = o->zalloc(o, sizeof(*sfilter)); if (!sfilter) return GE_NOMEM; sfilter->o = o; sfilter->is_client = is_client; sfilter->allow_authfail = allow_authfail; sfilter->use_child_auth = use_child_auth; sfilter->enable_password = enable_password; sfilter->require_password = require_password; sfilter->do_2fa = do_2fa; sfilter->con_timeout = con_timeout; sfilter->my_version = GENSIO_CERTAUTH_VERSION; sfilter->rsa_md5 = EVP_get_digestbyname("ssl3-md5"); if (!sfilter->rsa_md5) { rv = GE_IOERR; goto out_err; } sfilter->sha3_512 = EVP_get_digestbyname("sha3-512"); if (!sfilter->sha3_512) sfilter->my_version = 2; if (is_client) { /* Extra byte at the end so it's always nil terminated. */ sfilter->password = o->zalloc(o, GENSIO_CERTAUTH_PASSWORD_LEN + 1); if (!sfilter->password) { rv = GE_NOMEM; goto out_err; } sfilter->password_len = GENSIO_CERTAUTH_PASSWORD_LEN; if (password) { size_t pwlen = strlen(password); if (pwlen > GENSIO_CERTAUTH_PASSWORD_LEN) { rv = GE_TOOBIG; goto out_err; } strncpy(sfilter->password, password, GENSIO_CERTAUTH_PASSWORD_LEN); } if (val_2fa) { sfilter->val_2fa = o->zalloc(o, len_2fa); if (!sfilter->val_2fa) { rv = GE_NOMEM; goto out_err; } memcpy(sfilter->val_2fa, val_2fa, len_2fa); sfilter->len_2fa = len_2fa; } } sfilter->lock = o->alloc_lock(o); if (!sfilter->lock) goto out_nomem; sfilter->cert_bio = BIO_new(BIO_s_mem()); if (!sfilter->cert_bio) goto out_nomem; if (username) { sfilter->username = gensio_strdup(o, username); if (!sfilter->username) goto out_nomem; sfilter->username_len = strlen(username); } if (service) { sfilter->service = gensio_strdup(o, service); if (!sfilter->service) goto out_nomem; sfilter->service_len = strlen(service); } if (is_client) { sfilter->state = CERTAUTH_CLIENT_START; sfilter->got_msg = true; /* Go ahead and run the state machine. */ } else { sfilter->state = CERTAUTH_CLIENTHELLO; sfilter->challenge_data = o->zalloc(o, GENSIO_CERTAUTH_CHALLENGE_SIZE); if (!sfilter->challenge_data) goto out_nomem; sfilter->challenge_data_size = GENSIO_CERTAUTH_CHALLENGE_SIZE; } sfilter->read_buf = o->zalloc(o, GENSIO_CERTAUTH_DATA_SIZE); if (!sfilter->read_buf) goto out_nomem; sfilter->max_read_size = GENSIO_CERTAUTH_DATA_SIZE; sfilter->write_buf = o->zalloc(o, GENSIO_CERTAUTH_DATA_SIZE); if (!sfilter->write_buf) goto out_nomem; sfilter->max_write_size = GENSIO_CERTAUTH_DATA_SIZE; sfilter->filter = gensio_filter_alloc_data(o, gensio_certauth_filter_func, sfilter); if (!sfilter->filter) goto out_nomem; /* Don't set these until here so sfilter_free() doesn't free them on err. */ sfilter->cert = cert; sfilter->sk_ca = sk_ca; sfilter->pkey = pkey; sfilter->verify_store = store; *rfilter = sfilter->filter; return 0; out_nomem: rv = GE_NOMEM; out_err: sfilter_free(sfilter); return rv; } static void gensio_certauth_filter_config_free(struct gensio_certauth_filter_data *data) { struct gensio_os_funcs *o; if (!data) return; o = data->o; if (data->CAfilepath) o->free(o, data->CAfilepath); if (data->keyfile) o->free(o, data->keyfile); if (data->certfile) o->free(o, data->certfile); if (data->password) { memset(data->password, 0, strlen(data->password)); o->free(o, data->password); } if (data->val_2fa) { memset(data->val_2fa, 0, data->len_2fa); o->free(o, data->val_2fa); } if (data->username) o->free(o, data->username); if (data->service) o->free(o, data->service); o->free(o, data); } static int gensio_certauth_filter_config(struct gensio_pparm_info *p, struct gensio_os_funcs *o, const char * const args[], bool default_is_client, struct gensio_base_parms *parms, struct gensio_certauth_filter_data **rdata) { unsigned int i; struct gensio_certauth_filter_data *data = o->zalloc(o, sizeof(*data)); int rv = GE_NOMEM, ival; const char *str; char *fstr; if (!data) return GE_NOMEM; data->o = o; data->is_client = default_is_client; rv = gensio_get_default(o, "certauth", "allow-authfail", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (rv) return rv; data->allow_authfail = ival; rv = gensio_get_default(o, "certauth", "use-child-auth", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (rv) return rv; data->use_child_auth = ival; rv = gensio_get_default(o, "certauth", "enable-password", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (rv) return rv; data->enable_password = ival; rv = gensio_get_default(o, "certauth", "require-password", false, GENSIO_DEFAULT_BOOL, NULL, &ival); if (rv) return rv; data->require_password = ival; rv = gensio_get_default(o, "certauth", "mode", false, GENSIO_DEFAULT_STR, &fstr, NULL); if (rv) { gensio_log(o, GENSIO_LOG_ERR, "Failed getting certauth mode: %s", gensio_err_to_str(rv)); return rv; } if (fstr) { if (strcasecmp(fstr, "client") == 0) data->is_client = true; else if (strcasecmp(fstr, "server") == 0) data->is_client = false; else { gensio_log(o, GENSIO_LOG_ERR, "Unknown default certauth mode (%s), ignoring", fstr); } o->free(o, fstr); } rv = gensio_get_default(o, "certauth", "con-timeout", false, GENSIO_DEFAULT_INT, NULL, &ival); if (rv) return rv; data->con_timeout.secs = ival; data->con_timeout.nsecs = 0; rv = GE_NOMEM; for (i = 0; args && args[i]; i++) { if (gensio_pparm_value(p, args[i], "CA", &str) > 0) { data->CAfilepath = gensio_strdup(o, str); if (!data->CAfilepath) goto out_err; continue; } if (gensio_pparm_value(p, args[i], "key", &str) > 0) { data->keyfile = gensio_strdup(o, str); if (!data->keyfile) goto out_err; continue; } if (gensio_pparm_value(p, args[i], "cert", &str) > 0) { data->certfile = gensio_strdup(o, str); if (!data->certfile) goto out_err; continue; } if (gensio_pparm_value(p, args[i], "username", &str) > 0) { data->username = gensio_strdup(o, str); if (!data->username) goto out_err; continue; } if (gensio_pparm_value(p, args[i], "password", &str) > 0) { data->password = gensio_strdup(o, str); if (!data->password) goto out_err; continue; } if (gensio_pparm_value(p, args[i], "2fa", &str) > 0) { data->len_2fa = strlen(str); if (data->len_2fa == 0) goto out_err; data->val_2fa = gensio_strdup(o, str); if (!data->val_2fa) goto out_err; continue; } if (gensio_pparm_value(p, args[i], "service", &str) > 0) { data->service = gensio_strdup(o, str); if (!data->service) goto out_err; continue; } if (gensio_pparm_boolv(p, args[i], "mode", "client", "server", &data->is_client) > 0) continue; if (gensio_pparm_bool(p, args[i], "allow-authfail", &data->allow_authfail) > 0) continue; if (gensio_pparm_bool(p, args[i], "use-child-auth", &data->use_child_auth) > 0) continue; if (gensio_pparm_bool(p, args[i], "enable-password", &data->enable_password) > 0) continue; if (gensio_pparm_bool(p, args[i], "require-password", &data->require_password) > 0) continue; if (gensio_pparm_bool(p, args[i], "enable-2fa", &data->do_2fa) > 0) continue; if (gensio_pparm_time(p, args[i], "con-timeout", 's', &data->con_timeout) > 0) continue; if (gensio_pparm_bool(p, args[i], "allow-unencrypted", &data->allow_unencrypted) > 0) continue; if (gensio_base_parm(parms, p, args[i]) > 0) continue; gensio_pparm_unknown_parm(p, args[i]); rv = GE_INVAL; goto out_err; } if (!data->keyfile) { rv = gensio_get_default(o, "certauth", "key", false, GENSIO_DEFAULT_STR, &data->keyfile, NULL); if (rv) { gensio_log(o, GENSIO_LOG_ERR, "Unable to get default key for certauth: %s", gensio_err_to_str(rv)); goto out_err; } } if (!data->certfile) { rv = gensio_get_default(o, "certauth", "cert", false, GENSIO_DEFAULT_STR, &data->certfile, NULL); if (rv) { gensio_log(o, GENSIO_LOG_ERR, "Unable to get default cert for certauth: %s", gensio_err_to_str(rv)); goto out_err; } } if (!data->CAfilepath) { rv = gensio_get_default(o, "certauth", "CA", false, GENSIO_DEFAULT_STR, &data->CAfilepath, NULL); if (rv) { gensio_log(o, GENSIO_LOG_ERR, "Unable to get default CA for certauth: %s", gensio_err_to_str(rv)); goto out_err; } } if (!data->username) { rv = gensio_get_default(o, "certauth", "username", false, GENSIO_DEFAULT_STR, &data->username, NULL); if (rv) { gensio_log(o, GENSIO_LOG_ERR, "Unable to get default username for certauth: %s", gensio_err_to_str(rv)); goto out_err; } } if (!data->password) { rv = gensio_get_default(o, "certauth", "password", false, GENSIO_DEFAULT_STR, &data->password, NULL); if (rv) { gensio_log(o, GENSIO_LOG_ERR, "Unable to get default password for certauth: %s", gensio_err_to_str(rv)); goto out_err; } } if (!data->service) { gensio_get_default(o, "certauth", "service", false, GENSIO_DEFAULT_STR, &data->service, NULL); if (rv) { gensio_log(o, GENSIO_LOG_ERR, "Unable to get default service for certauth: %s", gensio_err_to_str(rv)); goto out_err; } } if (!data->keyfile && data->certfile) { data->keyfile = gensio_strdup(o, data->certfile); if (!data->keyfile) { rv = GE_NOMEM; goto out_err; } } if (data->is_client) { if (data->CAfilepath) { gensio_pparm_slog(p, "CA is not valid for clients"); rv = GE_INVAL; goto out_err; } if (data->do_2fa) { gensio_pparm_slog(p, "enable-2fa is not valid for clients"); rv = GE_INVAL; goto out_err; } } else { if (data->keyfile) { gensio_pparm_slog(p, "key is not valid for servers"); rv = GE_INVAL; goto out_err; } if (data->username) { gensio_pparm_slog(p, "username is not valid for servers"); rv = GE_INVAL; goto out_err; } if (data->val_2fa) { gensio_pparm_slog(p, "2fa is not valid for servers"); rv = GE_INVAL; goto out_err; } } *rdata = data; return 0; out_err: gensio_certauth_filter_config_free(data); return rv; } static bool gensio_certauth_filter_config_allow_unencrypted( struct gensio_certauth_filter_data *data) { return data->allow_unencrypted; } static bool gensio_certauth_filter_config_is_client( struct gensio_certauth_filter_data *data) { return data->is_client; } static int read_certificate_chain(const char *file, X509 **rcert, STACK_OF(X509) **rca) { BIO *in; int rv = 0; X509 *cert = NULL, *ca = NULL; STACK_OF(X509) *sk_ca = NULL; ERR_clear_error(); in = BIO_new(BIO_s_file()); if (!in) return GE_NOMEM; if (BIO_read_filename(in, file) <= 0) { rv = GE_CERTNOTFOUND; goto out_err; } cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); if (!cert) { rv = GE_CERTINVALID; goto out_err; } sk_ca = sk_X509_new_null(); if (!sk_ca) { rv = GE_NOMEM; goto out_err; } if (!sk_X509_push(sk_ca, cert)) { rv = GE_NOMEM; goto out_err; } X509_up_ref(cert); while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) { if (!sk_X509_push(sk_ca, ca)) { X509_free(ca); rv = GE_NOMEM; goto out_err; } } *rcert = cert; *rca = sk_ca; goto out; out_err: if (sk_ca) sk_X509_pop_free(sk_ca, X509_free); if (cert) X509_free(cert); out: BIO_free(in); return rv; } static int read_private_key(const char *file, EVP_PKEY **rpkey) { BIO *in; EVP_PKEY *pkey; ERR_clear_error(); in = BIO_new(BIO_s_file()); if (!in) return GE_NOMEM; if (BIO_read_filename(in, file) <= 0) { BIO_free(in); return GE_KEYNOTFOUND; } pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL); BIO_free(in); if (!pkey) return GE_KEYINVALID; *rpkey = pkey; return 0; } static int gensio_certauth_filter_alloc(struct gensio_certauth_filter_data *data, struct gensio_filter **rfilter) { struct gensio_os_funcs *o = data->o; struct gensio_filter *filter; X509_STORE *store = NULL; X509 *cert = NULL; EVP_PKEY *pkey = NULL; STACK_OF(X509) *sk_ca = NULL; int rv = GE_INVAL; store = X509_STORE_new(); if (!store) { rv = GE_NOMEM; goto err; } if (data->CAfilepath && data->CAfilepath[0]) { char *CAfile = NULL, *CApath = NULL; if (strchr(DIRSEPS, data->CAfilepath[strlen(data->CAfilepath) - 1])) CApath = data->CAfilepath; else CAfile = data->CAfilepath; if (!X509_STORE_load_locations(store, CAfile, CApath)) { rv = GE_CERTNOTFOUND; goto err; } } else { if (!X509_STORE_set_default_paths(store)) { gensio_log(o, GENSIO_LOG_ERR, "Setting default CA path failed for certauth"); rv = GE_NOCERT; goto err; } } if (data->certfile && data->certfile[0]) { rv = read_certificate_chain(data->certfile, &cert, &sk_ca); if (rv) goto err; rv = read_private_key(data->keyfile, &pkey); if (rv) goto err; } rv = gensio_certauth_filter_raw_alloc(o, data->is_client, store, cert, sk_ca, pkey, data->username, data->password, data->val_2fa, data->len_2fa, data->service, data->allow_authfail, data->use_child_auth, data->enable_password, data->require_password, data->do_2fa, data->con_timeout, &filter); if (rv) goto err; *rfilter = filter; return 0; err: if (sk_ca) sk_X509_pop_free(sk_ca, X509_free); if (cert) X509_free(cert); if (pkey) EVP_PKEY_free(pkey); if (store) X509_STORE_free(store); return rv; } static int certauth_gensio_alloc2(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio_base_parms *parms, struct gensio **net) { int err; struct gensio_filter *filter; struct gensio_ll *ll; struct gensio *io; struct gensio_certauth_filter_data *data; bool is_client; GENSIO_DECLARE_PPGENSIO(p, o, cb, "certauth", user_data); if (!parms) { err = gensio_base_parms_alloc(o, true, "certauth", &parms); if (err) goto out_err; } err = gensio_certauth_filter_config(&p, o, args, true, parms, &data); if (err) goto out_err; if (!gensio_is_reliable(child) || !(gensio_is_encrypted(child) || gensio_certauth_filter_config_allow_unencrypted(data))) { /* * Cowardly refusing to run over an unreliable or unencrypted * connection. The allow-unencrypted flag is internal for * testing and undocumented. */ err = GE_NOTSUP; goto out_err; } is_client = gensio_certauth_filter_config_is_client(data); err = gensio_certauth_filter_alloc(data, &filter); gensio_certauth_filter_config_free(data); if (err) goto out_err; ll = gensio_gensio_ll_alloc(o, child); if (!ll) { gensio_filter_free(filter); goto out_nomem; } gensio_ref(child); /* So gensio_ll_free doesn't free the child if fail */ io = base_gensio_alloc(o, ll, filter, child, "certauth", cb, user_data); if (!io) { gensio_ll_free(ll); gensio_filter_free(filter); goto out_nomem; } err = gensio_base_parms_set(io, &parms); if (err) { gensio_free(io); goto out_err; } gensio_set_is_client(io, is_client); gensio_set_is_packet(io, true); gensio_set_is_reliable(io, true); gensio_set_is_encrypted(io, true); gensio_free(child); /* Lose the ref we acquired. */ *net = io; return 0; out_nomem: err = GE_NOMEM; out_err: if (parms) gensio_base_parms_free(&parms); return err; } static int certauth_gensio_alloc(struct gensio *child, const char *const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **net) { return certauth_gensio_alloc2(child, args, o, cb, user_data, NULL, net); } static int str_to_certauth_gensio(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_event cb, void *user_data, struct gensio **new_gensio) { int err; struct gensio *io2; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio(str, o, cb, user_data, &io2); if (err) return err; err = certauth_gensio_alloc(io2, args, o, cb, user_data, new_gensio); if (err) gensio_free(io2); return err; } struct certauthna_data { struct gensio_accepter *acc; struct gensio_certauth_filter_data *data; struct gensio_os_funcs *o; }; static void certauthna_free(void *acc_data) { struct certauthna_data *nadata = acc_data; gensio_certauth_filter_config_free(nadata->data); nadata->o->free(nadata->o, nadata); } static int certauthna_alloc_gensio(void *acc_data, const char * const *iargs, struct gensio *child, struct gensio **rio) { struct certauthna_data *nadata = acc_data; struct gensio_base_parms *parms = NULL; parms = gensio_acc_base_parms_dup(nadata->acc); if (!parms) return GE_NOMEM; return certauth_gensio_alloc2(child, iargs, nadata->o, NULL, NULL, parms, rio); } static int certauthna_new_child(void *acc_data, void **finish_data, struct gensio_filter **filter) { struct certauthna_data *nadata = acc_data; return gensio_certauth_filter_alloc(nadata->data, filter); } static int certauthna_gensio_event(struct gensio *io, void *user_data, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) { struct certauthna_data *nadata = user_data; struct gensio_acc_password_verify_data pwvfy; struct gensio_acc_postcert_verify_data postvfy; int rv; switch (event) { case GENSIO_EVENT_AUTH_BEGIN: return gensio_acc_cb(nadata->acc, GENSIO_ACC_EVENT_AUTH_BEGIN, io); case GENSIO_EVENT_PRECERT_VERIFY: return gensio_acc_cb(nadata->acc, GENSIO_ACC_EVENT_PRECERT_VERIFY, io); case GENSIO_EVENT_POSTCERT_VERIFY: postvfy.io = io; postvfy.err = err; postvfy.errstr = auxdata ? auxdata[0] : NULL; return gensio_acc_cb(nadata->acc, GENSIO_ACC_EVENT_POSTCERT_VERIFY, &postvfy); case GENSIO_EVENT_PASSWORD_VERIFY: pwvfy.io = io; pwvfy.password = (char *) buf; pwvfy.password_len = *buflen; return gensio_acc_cb(nadata->acc, GENSIO_ACC_EVENT_PASSWORD_VERIFY, &pwvfy); case GENSIO_EVENT_REQUEST_PASSWORD: pwvfy.io = io; pwvfy.password = (char *) buf; pwvfy.password_len = *buflen; rv = gensio_acc_cb(nadata->acc, GENSIO_ACC_EVENT_REQUEST_PASSWORD, &pwvfy); if (!rv) *buflen = pwvfy.password_len; return rv; case GENSIO_EVENT_2FA_VERIFY: pwvfy.io = io; pwvfy.password = (char *) buf; pwvfy.password_len = *buflen; return gensio_acc_cb(nadata->acc, GENSIO_ACC_EVENT_2FA_VERIFY, &pwvfy); case GENSIO_EVENT_REQUEST_2FA: pwvfy.io = io; pwvfy.password = (char *) buf; pwvfy.password_len = 0; rv = gensio_acc_cb(nadata->acc, GENSIO_ACC_EVENT_REQUEST_2FA, &pwvfy); if (!rv) *buflen = pwvfy.password_len; return rv; case GENSIO_EVENT_LOG: { struct gensio_log_data *d = (struct gensio_log_data *) buf; gensio_acc_vlog(nadata->acc, d->level, d->log, d->args); return 0; } default: return GE_NOTSUP; } } static int certauthna_finish_parent(void *acc_data, void *finish_data, struct gensio *io) { struct certauthna_data *nadata = acc_data; int err; err = gensio_acc_base_parms_apply(nadata->acc, io); if (err) return err; gensio_set_is_client(io, gensio_certauth_filter_config_is_client( nadata->data)); gensio_set_is_packet(io, true); gensio_set_is_reliable(io, true); gensio_set_is_encrypted(io, true); gensio_set_callback(io, certauthna_gensio_event, acc_data); return 0; } static int gensio_gensio_acc_certauth_cb(void *acc_data, int op, void *data1, void *data2, void *data3, const void *data4) { switch (op) { case GENSIO_GENSIO_ACC_ALLOC_GENSIO: return certauthna_alloc_gensio(acc_data, data4, data1, data2); case GENSIO_GENSIO_ACC_NEW_CHILD: return certauthna_new_child(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FINISH_PARENT: return certauthna_finish_parent(acc_data, data1, data2); case GENSIO_GENSIO_ACC_FREE: certauthna_free(acc_data); return 0; default: return GE_NOTSUP; } } static int certauth_gensio_accepter_alloc(struct gensio_accepter *child, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **accepter) { struct certauthna_data *nadata = NULL; int err; struct gensio_base_parms *parms = NULL; GENSIO_DECLARE_PPACCEPTER(p, o, cb, "certauth", user_data); if (!gensio_acc_is_reliable(child)) /* Cowardly refusing to run over an unreliable connection. */ return GE_NOTSUP; err = gensio_base_parms_alloc(o, true, "certauth", &parms); if (err) goto out_err; nadata = o->zalloc(o, sizeof(*nadata)); if (!nadata) goto out_nomem; err = gensio_certauth_filter_config(&p, o, args, false, parms, &nadata->data); if (err) goto out_err; nadata->o = o; err = gensio_gensio_accepter_alloc(child, o, "certauth", cb, user_data, gensio_gensio_acc_certauth_cb, nadata, &nadata->acc); if (err) goto out_err; err = gensio_acc_base_parms_set(nadata->acc, &parms); if (err) goto out_err; gensio_acc_set_is_packet(nadata->acc, gensio_acc_is_packet(child)); gensio_acc_set_is_reliable(nadata->acc, gensio_acc_is_reliable(child)); *accepter = nadata->acc; return 0; out_nomem: err = GE_NOMEM; out_err: if (nadata) { if (nadata->acc) gensio_acc_free(nadata->acc); else certauthna_free(nadata); } if (parms) gensio_base_parms_free(&parms); return err; } static int str_to_certauth_gensio_accepter(const char *str, const char * const args[], struct gensio_os_funcs *o, gensio_accepter_event cb, void *user_data, struct gensio_accepter **acc) { int err; struct gensio_accepter *acc2 = NULL; /* cb is passed in for parmerr handling, it will be overriden later. */ err = str_to_gensio_accepter(str, o, cb, user_data, &acc2); if (!err) { err = certauth_gensio_accepter_alloc(acc2, args, o, cb, user_data, acc); if (err) gensio_acc_free(acc2); } return err; } int gensio_init_certauth(struct gensio_os_funcs *o) { int rv; rv = register_filter_gensio(o, "certauth", str_to_certauth_gensio, certauth_gensio_alloc); if (rv) return rv; rv = register_filter_gensio_accepter(o, "certauth", str_to_certauth_gensio_accepter, certauth_gensio_accepter_alloc); if (rv) return rv; return 0; } gensio-3.0.0/lib/gensio_net.h0000664000175000017500000000050414736057357011552 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #ifndef GENSIO_NET_H #define GENSIO_NET_H enum gensio_tcpd_options { GENSIO_TCPD_ON, GENSIO_TCPD_PRINT, GENSIO_TCPD_OFF, }; #endif /* GENSIO_NET_H */ gensio-3.0.0/lib/avahi_watcher.c0000664000175000017500000002557214664224267012230 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2020 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ /* * This file provides an Avahi poll structure based upon * gensio_os_funcs. It's a pretty straightforward translation. */ #include "config.h" #if HAVE_AVAHI #include #include #include #include #include "avahi_watcher.h" struct gensio_avahi_userdata { struct gensio_os_funcs *o; AvahiPoll *ap; /* This lock is used for all callbacks. Only one callback at a time. */ struct gensio_lock *lock; gensio_avahi_done stop_done; void *stop_userdata; struct gensio_runner *runner; bool disabled; unsigned int refcount; struct gensio_list watches; struct gensio_list timers; bool stopped; }; static void gensio_avahi_poll_deref(AvahiPoll *ap) { struct gensio_avahi_userdata *u = ap->userdata; struct gensio_os_funcs *o = u->o; assert(u->refcount > 0); u->refcount--; if (u->refcount == 0) o->run(u->runner); } void gensio_avahi_lock(AvahiPoll *ap) { struct gensio_avahi_userdata *u = ap->userdata; struct gensio_os_funcs *o = u->o; o->lock(u->lock); } void gensio_avahi_unlock(AvahiPoll *ap) { struct gensio_avahi_userdata *u = ap->userdata; struct gensio_os_funcs *o = u->o; o->unlock(u->lock); } struct AvahiWatch { struct gensio_avahi_userdata *u; int fd; struct gensio_iod *iod; AvahiWatchEvent events; AvahiWatchEvent revents; bool freed; AvahiWatchCallback callback; void *userdata; struct gensio_link link; }; static void gensio_avahi_read_handler(struct gensio_iod *iod, void *cb_data) { AvahiWatch *w = cb_data; struct gensio_avahi_userdata *u = w->u; struct gensio_os_funcs *o = u->o; o->lock(u->lock); if (u->disabled || w->freed) { o->set_read_handler(w->iod, false); } else if (w->events & AVAHI_WATCH_IN) { w->revents = AVAHI_WATCH_IN; w->callback(w, w->fd, w->revents, w->userdata); w->revents = 0; } o->unlock(u->lock); } static void gensio_avahi_write_handler(struct gensio_iod *iod, void *cb_data) { AvahiWatch *w = cb_data; struct gensio_avahi_userdata *u = w->u; struct gensio_os_funcs *o = u->o; o->lock(u->lock); if (u->disabled || w->freed) { o->set_write_handler(w->iod, false); } else if (w->events & AVAHI_WATCH_OUT) { w->revents = AVAHI_WATCH_OUT; w->callback(w, w->fd, w->revents, w->userdata); w->revents = 0; } o->unlock(u->lock); } static void gensio_avahi_except_handler(struct gensio_iod *iod, void *cb_data) { AvahiWatch *w = cb_data; struct gensio_avahi_userdata *u = w->u; struct gensio_os_funcs *o = u->o; o->lock(u->lock); if (u->disabled || w->freed) { o->set_except_handler(w->iod, false); } else if (w->events & AVAHI_WATCH_ERR) { w->revents = AVAHI_WATCH_ERR; w->callback(w, w->fd, w->revents, w->userdata); w->revents = 0; } o->unlock(u->lock); } static void gensio_avahi_cleared_handler(struct gensio_iod *iod, void *cb_data) { AvahiWatch *w = cb_data; struct gensio_avahi_userdata *u = w->u; struct gensio_os_funcs *o = u->o; gensio_list_rm(&u->watches, &w->link); o->release_iod(w->iod); o->free(o, w); o->lock(u->lock); gensio_avahi_poll_deref(u->ap); o->unlock(u->lock); } static void gensio_avahi_watch_update(AvahiWatch *w, AvahiWatchEvent event) { struct gensio_avahi_userdata *u = w->u; struct gensio_os_funcs *o = u->o; w->events = event; o->set_read_handler(w->iod, !!(event & AVAHI_WATCH_IN)); o->set_write_handler(w->iod, !!(event & AVAHI_WATCH_OUT)); o->set_except_handler(w->iod, !!(event & AVAHI_WATCH_ERR)); } static AvahiWatch * gensio_avahi_watch_new(const AvahiPoll *ap, int fd, AvahiWatchEvent event, AvahiWatchCallback callback, void *userdata) { struct gensio_avahi_userdata *u = ap->userdata; struct gensio_os_funcs *o = u->o; AvahiWatch *aw; int err; aw = o->zalloc(o, sizeof(*aw)); if (!aw) return NULL; err = o->add_iod(o, GENSIO_IOD_SOCKET, fd, &aw->iod); if (err) { free(aw); return NULL; } aw->u = u; aw->fd = fd; aw->events = event; aw->callback = callback; aw->userdata = userdata; err = o->set_fd_handlers(aw->iod, aw, gensio_avahi_read_handler, gensio_avahi_write_handler, gensio_avahi_except_handler, gensio_avahi_cleared_handler); if (err) { o->release_iod(aw->iod); o->free(o, aw); return NULL; } u->refcount++; gensio_list_add_tail(&u->watches, &aw->link); gensio_avahi_watch_update(aw, event); return aw; } static AvahiWatchEvent gensio_avahi_watch_get_events(AvahiWatch *w) { return w->events; } static void gensio_avahi_watch_free(AvahiWatch *w) { struct gensio_avahi_userdata *u = w->u; struct gensio_os_funcs *o = u->o; assert(!w->freed); gensio_avahi_watch_update(w, 0); w->freed = true; o->clear_fd_handlers(w->iod); } struct AvahiTimeout { struct gensio_avahi_userdata *u; struct gensio_timer *t; AvahiTimeoutCallback callback; struct timeval tv; void *userdata; bool stopped; bool in_update; bool freed; struct gensio_link link; }; static void gensio_avahi_timeout(struct gensio_timer *t, void *cb_data) { AvahiTimeout *at = cb_data; struct gensio_avahi_userdata *u = at->u; struct gensio_os_funcs *o = u->o; o->lock(u->lock); if (!at->stopped && !u->disabled) at->callback(at, at->userdata); o->unlock(u->lock); } static int tv_cmp(struct timeval *tv1, struct timeval *tv2) { if (tv1->tv_sec < tv2->tv_sec) return -1; if (tv1->tv_sec > tv2->tv_sec) return 1; if (tv1->tv_usec < tv2->tv_usec) return -1; if (tv1->tv_usec > tv2->tv_usec) return 1; return 0; } static void do_timer_start(AvahiTimeout *at) { struct gensio_avahi_userdata *u = at->u; struct gensio_os_funcs *o = u->o; struct timeval now, *tv = &at->tv; gensio_time gt; int rv; gettimeofday(&now, NULL); if (tv_cmp(tv, &now) <= 0) { gt.secs = 0; gt.nsecs = 0; } else { gt.secs = tv->tv_sec - now.tv_sec; gt.nsecs = (tv->tv_usec - now.tv_usec) * 1000; if (gt.nsecs < 0) { gt.nsecs += 1000000000; gt.secs -= 1; } } rv = o->start_timer(at->t, >); assert(rv == 0); } static void finish_free_timeout(AvahiTimeout *at) { struct gensio_avahi_userdata *u = at->u; struct gensio_os_funcs *o = u->o; gensio_list_rm(&u->timers, &at->link); o->free_timer(at->t); o->free(o, at); gensio_avahi_poll_deref(u->ap); } static void i_gensio_avahi_timer_stopped(AvahiTimeout *at) { if (at->freed) { finish_free_timeout(at); } else if (at->in_update) { at->in_update = false; if (!at->stopped) do_timer_start(at); } } static void gensio_avahi_timer_stopped(struct gensio_timer *timer, void *userdata) { AvahiTimeout *at = userdata; struct gensio_avahi_userdata *u = at->u; struct gensio_os_funcs *o = u->o; o->lock(u->lock); i_gensio_avahi_timer_stopped(at); o->unlock(u->lock); } static void gensio_avahi_timeout_update(AvahiTimeout *at, const struct timeval *tv) { struct gensio_avahi_userdata *u = at->u; struct gensio_os_funcs *o = u->o; if (tv) { at->tv = *tv; at->stopped = false; } else { if (at->stopped) return; at->stopped = true; } if (!at->in_update) { at->in_update = true; if (o->stop_timer_with_done(at->t, gensio_avahi_timer_stopped, at) == GE_TIMEDOUT) i_gensio_avahi_timer_stopped(at); } } static AvahiTimeout * gensio_avahi_timeout_new(const AvahiPoll *ap, const struct timeval *tv, AvahiTimeoutCallback callback, void *userdata) { struct gensio_avahi_userdata *u = ap->userdata; struct gensio_os_funcs *o = u->o; AvahiTimeout *at; at = o->zalloc(o, sizeof(*at)); if (!at) return NULL; at->t = o->alloc_timer(o, gensio_avahi_timeout, at); if (!at->t) { o->free(o, at); return NULL; } at->u = u; at->callback = callback; at->userdata = userdata; u->refcount++; at->stopped = true; gensio_list_add_tail(&u->timers, &at->link); gensio_avahi_timeout_update(at, tv); return at; } static void gensio_avahi_timeout_free(AvahiTimeout *at) { struct gensio_avahi_userdata *u = at->u; struct gensio_os_funcs *o = u->o; if (at->freed) return; at->freed = true; at->stopped = true; if (o->stop_timer_with_done(at->t, gensio_avahi_timer_stopped, at) == GE_TIMEDOUT) { finish_free_timeout(at); } } static void gensio_avahi_poll_runner(struct gensio_runner *runner, void *userdata) { struct AvahiPoll *ap = userdata; struct gensio_avahi_userdata *u = ap->userdata; struct gensio_os_funcs *o = u->o; /* Make sure all users are out of their locks. */ o->lock(u->lock); o->unlock(u->lock); if (u->stop_done) u->stop_done(ap, u->stop_userdata); o->free_runner(u->runner); o->free_lock(u->lock); o->free(o, u); o->free(o, ap); } struct AvahiPoll * alloc_gensio_avahi_poll(struct gensio_os_funcs *o) { struct gensio_avahi_userdata *u; struct AvahiPoll *ap; ap = o->zalloc(o, sizeof(*ap)); if (!ap) return NULL; u = o->zalloc(o, sizeof(*u)); if (!u) { o->free(o, ap); return NULL; } u->o = o; u->refcount = 1; u->ap = ap; u->lock = o->alloc_lock(o); if (!u->lock) { o->free(o, u); o->free(o, ap); return NULL; } u->runner = o->alloc_runner(o, gensio_avahi_poll_runner, ap); if (!u->runner) { o->free_lock(u->lock); o->free(o, u); o->free(o, ap); return NULL; } gensio_list_init(&u->timers); gensio_list_init(&u->watches); ap->userdata = u; ap->watch_new = gensio_avahi_watch_new; ap->watch_update = gensio_avahi_watch_update; ap->watch_get_events = gensio_avahi_watch_get_events; ap->watch_free = gensio_avahi_watch_free; ap->timeout_new = gensio_avahi_timeout_new; ap->timeout_update = gensio_avahi_timeout_update; ap->timeout_free = gensio_avahi_timeout_free; return ap; } void gensio_avahi_poll_disable(AvahiPoll *ap) { struct gensio_avahi_userdata *u = ap->userdata; u->disabled = true; } void gensio_avahi_poll_free(AvahiPoll *ap, gensio_avahi_done done, void *userdata) { struct gensio_avahi_userdata *u = ap->userdata; struct gensio_link *l, *l2; if (u->stopped) return; u->disabled = true; u->stopped = true; u->stop_done = done; u->stop_userdata = userdata; gensio_list_for_each_safe(&u->timers, l, l2) { AvahiTimeout *at = gensio_container_of(l, AvahiTimeout, link); if (!at->freed) gensio_avahi_timeout_free(at); } gensio_list_for_each_safe(&u->watches, l, l2) { AvahiWatch *aw = gensio_container_of(l, AvahiWatch, link); if (!aw->freed) gensio_avahi_watch_free(aw); } gensio_avahi_poll_deref(ap); } #else int no_avahi=1; #endif gensio-3.0.0/lib/utils.h0000664000175000017500000000145014664224267010555 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #ifndef UTILS #define UTILS #include #include #include #ifndef HAVE_STRCASECMP int strcasecmp(const char *s1, const char *s2); #endif #ifndef HAVE_STRNCASECMP int strncasecmp(const char *s1, const char *s2, int n); #endif struct enum_val { char *str; int val; }; #if ENABLE_PRBUF #include static void prbuf(const unsigned char *buf, unsigned int len) { unsigned int i; for (i = 0; i < len; i++) { if (i % 16 == 0) printf("\r\n"); printf(" %2.2x", buf[i]); } printf("\r\n"); fflush(stdout); } #endif #endif /* UTILS */ gensio-3.0.0/config.h.in0000664000175000017500000001365715061121664010522 /* config.h.in. Generated from configure.ac by autoheader. */ /* PSELECT call is not atomic */ #undef BROKEN_PSELECT /* Enable internal tracing */ #undef ENABLE_INTERNAL_TRACE /* Set to 1 to enable alsa, 0 to disable */ #undef HAVE_ALSA /* Set to 1 to enable MDNS support through avahi, 0 to disable */ #undef HAVE_AVAHI /* Define to 1 if you have the `cfmakeraw' function. */ #undef HAVE_CFMAKERAW /* define if the compiler supports basic C++11 syntax */ #undef HAVE_CXX11 /* Define to 1 if you have the declaration of `SIGWINCH', and to 0 if you don't. */ #undef HAVE_DECL_SIGWINCH /* Define to 1 if you have the declaration of `TIOCSRS485', and to 0 if you don't. */ #undef HAVE_DECL_TIOCSRS485 /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Set to 1 to enable MDNS support through dnssd, 0 to disable */ #undef HAVE_DNSSD /* This platform supports epoll(7) with epoll_pwait(2). */ #undef HAVE_EPOLL_PWAIT /* Define to 1 if you have the `fnmatch' function. */ #undef HAVE_FNMATCH /* Define if getrandom is available. */ #undef HAVE_GETRANDOM_FUNC /* Have GLIB libraries */ #undef HAVE_GLIB /* Have go installed */ #undef HAVE_GO /* Define to 1 if you have the `initgroups' function. */ #undef HAVE_INITGROUPS /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `isatty' function. */ #undef HAVE_ISATTY /* Define to 1 if you have the `kevent' function. */ #undef HAVE_KEVENT /* PAM libraries are present */ #undef HAVE_LIBPAM /* Set to 1 to enable SCTP, 0 to disable */ #undef HAVE_LIBSCTP /* Set to 1 to enable MDNS support, 0 to disable */ #undef HAVE_MDNS /* Set to 1 to enable IPMI support through OpenIPMI, 0 to disable */ #undef HAVE_OPENIPMI /* Set to 1 to enable SSL support through OpenSSL, 0 to disable */ #undef HAVE_OPENSSL /* Have PCRE POSIX regex */ #undef HAVE_PCRE_POSIX /* Set to 1 to enable portaudio, 0 to disable */ #undef HAVE_PORTAUDIO /* Define to 1 if you have the `posix_openpt' function. */ #undef HAVE_POSIX_OPENPT /* Define to 1 if you have the `prctl' function. */ #undef HAVE_PRCTL /* Have PTHREAD_PRIO_INHERIT. */ #undef HAVE_PTHREAD_PRIO_INHERIT /* Set to 1 if ptsname_r is available, 0 if not */ #undef HAVE_PTSNAME_R /* Enable PTY gensio */ #undef HAVE_PTY /* If available, contains the Python version number currently in use. */ #undef HAVE_PYTHON /* Set to 1 to new random support in SSL, 0 to disable */ #undef HAVE_RAND_SET_DRBG_TYPE /* Define to 1 if you have the `recvmsg' function. */ #undef HAVE_RECVMSG /* Define to 1 if you have the `regexec' function. */ #undef HAVE_REGEXEC /* Set to 1 if sctp_sendv() is available, 0 if not */ #undef HAVE_SCTP_SENDV /* Define to 1 if you have the `sendmsg' function. */ #undef HAVE_SENDMSG /* Define to 1 if you have the `setutxent' function. */ #undef HAVE_SETUTXENT /* Define to 1 if you have the `signalfd' function. */ #undef HAVE_SIGNALFD /* Define to 1 if you have the `sigtimedwait' function. */ #undef HAVE_SIGTIMEDWAIT /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDIO_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strncasecmp' function. */ #undef HAVE_STRNCASECMP /* Have swig installed */ #undef HAVE_SWIG /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Have TCL libraries */ #undef HAVE_TCL /* Define to 1 if you have the header file. */ #undef HAVE_TCPD_H /* termios2 is present */ #undef HAVE_TERMIOS2 /* Set to 1 if Unix credentials (permissions) enabled, 0 if not */ #undef HAVE_UCRED /* Set to 1 to enable udev, 0 to disable */ #undef HAVE_UDEV /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Enable unix socket file handling */ #undef HAVE_UNIX /* Set to 1 to enable windows , 0 to disable */ #undef HAVE_WIN32SOUND /* Set to 1 to enable MDNS support through winmdns, 0 to disable */ #undef HAVE_WINMDNS /* Set to 1 if binding with port 0 picks an ephemeral address */ #undef HAVE_WORKING_PORT0 /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to necessary symbol if this constant uses a non-standard name on your system. */ #undef PTHREAD_CREATE_JOINABLE /* Define to 1 if all of the C90 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #undef STDC_HEADERS /* Use stdio for the file gensio */ #undef USE_FILE_STDIO /* Enable device locking */ #undef USE_FLOCK_LOCKING /* Set to 1 to use gid_t, 0 to use int for groups */ #undef USE_GGL_INT /* Set to 1 to use login, 0 to directly execute the shell on login */ #undef USE_LOGIN_PROGRAM /* Set to 1 to use openpty, 0 to use posix_openpt */ #undef USE_OPENPTY /* Enable multithreaded support */ #undef USE_PTHREADS /* Enable device locking */ #undef USE_UUCP_LOCKING /* Directory holding UUCP locks */ #undef UUCP_LOCK_DIR /* Version number of package */ #undef VERSION gensio-3.0.0/c++/0000775000175000017500000000000015061121734007111 5gensio-3.0.0/c++/Makefile.in0000664000175000017500000005460115061121657011110 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = c++ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = include lib $(SWIG_CPP_DIR) tests examples DIST_SUBDIRS = include lib swig tests examples all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/c++/lib/0000775000175000017500000000000015061121734007657 5gensio-3.0.0/c++/lib/libgensiomdnscpp.pc.in0000664000175000017500000000037514664224267014112 prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libgensiomdnscpp Description: A C++ library wrapper around gensio MDNS Version: @VERSION@ Libs: -L${libdir} -lgensiomdnscpp -lgensiomdns -lgensiooshcpp -lgensioosh gensio-3.0.0/c++/lib/gensio.cc0000664000175000017500000007052615045153771011414 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only #include #include #include #include namespace gensios { #include int Event::new_channel(Gensio *new_channel, const char *const *auxdata) { return GE_NOTSUP; } struct gensio_cpp_data { struct gensio_frdata frdata; Gensio *g; }; Gensio *gensio_alloc(struct gensio *io, Os_Funcs &o, class Event *cb); class GENSIOCPP_DLL_PUBLIC Main_Raw_Event_Handler: public Raw_Event_Handler { public: Main_Raw_Event_Handler() { } int handle(Gensio *g, struct gensio *io, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) override { Event *cb = g->get_cb(); Gensio *g2; if (!cb) return GE_NOTSUP; try { if (event >= GENSIO_EVENT_USER_MIN && event <= GENSIO_EVENT_USER_MAX) { std::vector val(buf, buf + *buflen); return cb->user_event(event, err, val, auxdata); } if (event >= SERGENSIO_EVENT_BASE && event <= SERGENSIO_EVENT_MAX) { unsigned int *val = (unsigned int *) buf; if (event == GENSIO_EVENT_SER_SIGNATURE) { std::vector sig(buf, buf + *buflen); cb->signature(std::move(sig)); return 0; } switch (event) { case GENSIO_EVENT_SER_MODEMSTATE: cb->modemstate(*val); break; case GENSIO_EVENT_SER_MODEMSTATE_MASK: cb->modemstate_mask(*val); break; case GENSIO_EVENT_SER_LINESTATE: cb->linestate(*val); break; case GENSIO_EVENT_SER_LINESTATE_MASK: cb->linestate_mask(*val); break; case GENSIO_EVENT_SER_FLOW_STATE: cb->flow_state(*val); break; case GENSIO_EVENT_SER_FLUSH: cb->flush(*val); break; case GENSIO_EVENT_SER_SYNC: cb->sync(); break; case GENSIO_EVENT_SER_BAUD: cb->baud(*val); break; case GENSIO_EVENT_SER_DATASIZE: cb->datasize(*val); break; case GENSIO_EVENT_SER_PARITY: cb->parity(*val); break; case GENSIO_EVENT_SER_STOPBITS: cb->stopbits(*val); break; case GENSIO_EVENT_SER_FLOWCONTROL: cb->flowcontrol(*val); break; case GENSIO_EVENT_SER_IFLOWCONTROL: cb->iflowcontrol(*val); break; case GENSIO_EVENT_SER_SBREAK: cb->sbreak(*val); break; case GENSIO_EVENT_SER_DTR: cb->dtr(*val); break; case GENSIO_EVENT_SER_RTS: cb->rts(*val); break; default: return GE_NOTSUP; } return 0; } switch (event) { case GENSIO_EVENT_READ: { if (buflen) { SimpleUCharVector vdata(buf, *buflen); *buflen = cb->read(err, vdata, auxdata); } else { SimpleUCharVector vdata(NULL, 0); cb->read(err, vdata, auxdata); } return 0; } case GENSIO_EVENT_WRITE_READY: cb->write_ready(); return 0; case GENSIO_EVENT_NEW_CHANNEL: g2 = gensio_alloc((struct gensio *) buf, g->get_os_funcs(), NULL); return g->raw_event_handler->new_channel(cb, g2, auxdata); case GENSIO_EVENT_SEND_BREAK: cb->send_break(); return 0; case GENSIO_EVENT_AUTH_BEGIN: return cb->auth_begin(); case GENSIO_EVENT_PRECERT_VERIFY: return cb->precert_verify(); case GENSIO_EVENT_POSTCERT_VERIFY: return cb->postcert_verify(err, auxdata ? auxdata[0] : NULL); case GENSIO_EVENT_PASSWORD_VERIFY: { std::string pwstr((char *) buf); return cb->password_verify(std::move(pwstr)); } case GENSIO_EVENT_REQUEST_PASSWORD: { int rv; std::string pwstr(""); rv = cb->request_password(*buflen, pwstr); if (rv) return rv; if (pwstr.size() > *buflen) return GE_TOOBIG; *buflen = (gensiods) pwstr.size(); memcpy(buf, pwstr.c_str(), *buflen); return 0; } case GENSIO_EVENT_2FA_VERIFY: { std::vector val(buf, buf + *buflen); return cb->verify_2fa(std::move(val)); } case GENSIO_EVENT_REQUEST_2FA: { int rv; std::vector val(0); Os_Funcs o = g->get_os_funcs(); unsigned char *rbuf; rv = cb->request_2fa(val); if (rv) return rv; rbuf = (unsigned char *) o->zalloc(o, (gensiods) val.size()); if (!rbuf) return GE_NOMEM; *buflen = (gensiods) val.size(); memcpy(rbuf, val.data(), *buflen); *((unsigned char **) buf) = rbuf; return 0; } case GENSIO_EVENT_PARMLOG: { struct gensio_parmlog_data *d = (struct gensio_parmlog_data *) buf; va_list argcopy; va_copy(argcopy, d->args); size_t len = vsnprintf(NULL, 0, d->log, argcopy); va_end(argcopy); std::string outstr(len + 1, '\0'); vsnprintf(&outstr[0], len + 1, d->log, d->args); cb->parmlog(std::move(outstr)); return 0; } case GENSIO_EVENT_WIN_SIZE: { unsigned int height = 0, width = 0; sscanf((char *) buf, "%u:%u", &height, &width); cb->win_size(height, width); return 0; } case GENSIO_EVENT_LOG: { struct gensio_log_data *d = (struct gensio_log_data *) buf; va_list argcopy; va_copy(argcopy, d->args); size_t len = vsnprintf(NULL, 0, d->log, argcopy); va_end(argcopy); std::string outstr(len + 1, '\0'); // Copy args again, in case the user doesn't handle them // and returns GE_NOTSUP. va_copy(argcopy, d->args); vsnprintf(&outstr[0], len + 1, d->log, argcopy); va_end(argcopy); return cb->log(d->level, std::move(outstr)); } } return GE_NOTSUP; } catch (std::exception &e) { gensio_log(g->get_os_funcs(), GENSIO_LOG_ERR, "Received C++ exception in callback handler: %s", e.what()); return GE_APPERR; } } int new_channel(Event *e, Gensio *new_chan, const char *const *auxdata) override { if (e) return e->new_channel(new_chan, auxdata); return GE_NOTSUP; } void freed(Event *e) override { if (e) e->freed(); } }; static int gensio_cpp_cb(struct gensio *io, void *user_data, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) { Gensio *g = static_cast(user_data); return g->raw_event_handler->handle(g, io, event, err, buf, buflen, auxdata); } void gensio_cpp_freed(struct gensio *io, struct gensio_frdata *frdata) { struct gensio_cpp_data *d = gensio_container_of(frdata, struct gensio_cpp_data, frdata); Event *cb = d->g->get_cb(); // Disable callbacks from here out. d->g->set_event_handler(NULL); // Gensios that are not top-level will not have a raw event // handler. This only matters for freed, as the freed call // doesn't come in from the gensio event handler, but from the // frdata handler. if (d->g->raw_event_handler) d->g->raw_event_handler->freed(cb); else if (cb) cb->freed(); delete d->g; delete d; } // Note - If this fails, it deletes the object it is part of and // throws an exception. Most of the time that's what you want, // but some places needs special handling. void Gensio::set_gensio(struct gensio *io, bool set_cb) { struct gensio_cpp_data *d; try { d = new struct gensio_cpp_data; } catch (...) { delete this; throw; } this->io = io; d->g = this; d->frdata.freed = gensio_cpp_freed; gensio_set_frdata(io, &d->frdata); if (set_cb) { gensio_set_callback(io, gensio_cpp_cb, this); try { this->raw_event_handler = new Main_Raw_Event_Handler(); } catch (...) { delete d; delete this; throw; } } } Gensio * gensio_alloc(struct gensio *io, Os_Funcs &o) { struct gensio *cio; struct sergensio *sio; unsigned int i; struct gensio_frdata *f; struct gensio_cpp_data *d; Gensio *g; // Set frdata for the gensio and all children. for (i = 0; (cio = gensio_get_child(io, i)); i++) { if (gensio_get_frdata(cio)) break; // It's already been set. g = new Gensio(o, NULL); g->set_gensio(cio, i == 0); } f = gensio_get_frdata(io); d = gensio_container_of(f, struct gensio_cpp_data, frdata); return d->g; } Gensio * gensio_alloc(struct gensio *io, Os_Funcs &o, Event *cb) { Gensio *g; g = gensio_alloc(io, o); g->set_event_handler(cb); return g; } static int init_gensio_eventh(struct gensio *io, void *user_data, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) { Event *cb = static_cast(user_data); switch(event) { case GENSIO_EVENT_PARMLOG: { struct gensio_parmlog_data *p = (struct gensio_parmlog_data *) buf; va_list argcopy; va_copy(argcopy, p->args); size_t len = vsnprintf(NULL, 0, p->log, argcopy); va_end(argcopy); std::string outstr(len, '\0'); vsnprintf(&outstr[0], len + 1, p->log, p->args); cb->parmlog(std::move(outstr)); return 0; } case GENSIO_EVENT_LOG: { struct gensio_log_data *p = (struct gensio_log_data *) buf; va_list argcopy; va_copy(argcopy, p->args); size_t len = vsnprintf(NULL, 0, p->log, argcopy); va_end(argcopy); std::string outstr(len, '\0'); vsnprintf(&outstr[0], len + 1, p->log, p->args); cb->log(p->level, std::move(outstr)); return 0; } default: return GE_NOTSUP; } } Gensio * gensio_alloc(std::string str, Os_Funcs &o, Event *cb) { struct gensio *io; int err; Gensio *g; err = str_to_gensio(str.c_str(), o, init_gensio_eventh, cb, &io); if (err) throw gensio_error(err); g = gensio_alloc(io, o, cb); return g; } Gensio * gensio_alloc(Gensio *child, std::string str, Os_Funcs &o, Event *cb) { struct gensio *io; int err; Gensio *g; err = str_to_gensio_child(child->get_gensio(), str.c_str(), o, init_gensio_eventh, cb, &io); if (err) throw gensio_error(err); g = gensio_alloc(io, o, cb); return g; } Gensio * gensio_alloc(const char *gensiotype, const void *gdata, const char * const args[], Os_Funcs &o, Event *cb) { struct gensio *io; int err; Gensio *g; err = gensio_terminal_alloc(gensiotype, gdata, args, o, NULL, NULL, &io); if (err) throw gensio_error(err); g = gensio_alloc(io, o, cb); return g; } void Gensio::free() { gensio_free(io); } static void gensio_cpp_open_done(struct gensio *io, int err, void *user_data) { if (!user_data) return; struct gensio_frdata *f = gensio_get_frdata(io); struct gensio_cpp_data *d = gensio_container_of(f, struct gensio_cpp_data, frdata); Gensio *g = d->g; Gensio_Open_Done *done = static_cast(user_data); try { done->open_done(err); } catch (const std::exception &e) { gensio_log(g->get_os_funcs(), GENSIO_LOG_ERR, "Received C++ exception in open done handler: %s", e.what()); } } void Gensio::open(Gensio_Open_Done *done) { int err; err = gensio_open(io, gensio_cpp_open_done, done); if (err) throw gensio_error(err); } void Gensio::open_s() { int err = gensio_open_s(io); if (err) throw gensio_error(err); } void Gensio::open_nochild(Gensio_Open_Done *done) { int err; err = gensio_open_nochild(io, gensio_cpp_open_done, done); if (err) throw gensio_error(err); } void Gensio::open_nochild_s() { int err = gensio_open_nochild_s(io); if (err) throw gensio_error(err); } gensiods Gensio::write(const void *data, gensiods datalen, const char *const *auxdata) { gensiods count; int err = gensio_write(io, &count, data, datalen, auxdata); if (err) throw gensio_error(err); return count; } gensiods Gensio::write(const std::vector data, const char *const *auxdata) { return write(data.data(), (gensiods) data.size(), auxdata); } gensiods Gensio::write(const SimpleUCharVector data, const char *const *auxdata) { return write(data.data(), (gensiods) data.size(), auxdata); } gensiods Gensio::write(const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata) { gensiods count; int err = gensio_write_sg(io, &count, sg, sglen, auxdata); if (err) throw gensio_error(err); return count; } int Gensio::write_s(gensiods *count, const void *data, gensiods datalen, gensio_time *timeout, bool intr) { int err; if (intr) err = gensio_write_s_intr(io, count, data, datalen, timeout); else err = gensio_write_s(io, count, data, datalen, timeout); if (err == GE_TIMEDOUT || err == GE_INTERRUPTED) return err; if (err) throw gensio_error(err); return 0; } int Gensio::write_s(gensiods *count, std::vector data, gensio_time *timeout, bool intr) { return write_s(count, data.data(), (gensiods) data.size(), timeout, intr); } int Gensio::write_s(gensiods *count, SimpleUCharVector data, gensio_time *timeout, bool intr) { return write_s(count, data.data(), (gensiods) data.size(), timeout, intr); } Gensio *Gensio::alloc_channel(const char *const args[], Event *cb) { struct gensio *nio; int err = gensio_alloc_channel(io, args, NULL, NULL, &nio); Gensio *g; if (err) throw gensio_error(err); g = gensio_alloc(nio, go, cb); return g; } static void gensio_cpp_close_done(struct gensio *io, void *user_data) { if (!user_data) return; struct gensio_frdata *f = gensio_get_frdata(io); struct gensio_cpp_data *d = gensio_container_of(f, struct gensio_cpp_data, frdata); Gensio *g = d->g; Gensio_Close_Done *done = static_cast(user_data); try { done->close_done(); } catch (std::exception &e) { gensio_log(g->get_os_funcs(), GENSIO_LOG_ERR, "Received C++ exception in close done handler: %s", e.what()); } } void Gensio::close(Gensio_Close_Done *done) { int err; if (done) err = gensio_close(io, gensio_cpp_close_done, done); else err = gensio_close(io, NULL, NULL); if (err) throw gensio_error(err); } void Gensio::close_s() { int err = gensio_close_s(io); if (err) throw gensio_error(err); } int Gensio::control(int depth, bool get, unsigned int option, char *data, gensiods *datalen) { return gensio_control(io, depth, get, option, data, datalen); } static void gensio_cpp_control_done(struct gensio *io, int err, const char *buf, gensiods len, void *user_data) { if (!user_data) return; struct gensio_frdata *f = gensio_get_frdata(io); struct gensio_cpp_data *d = gensio_container_of(f, struct gensio_cpp_data, frdata); Gensio *g = d->g; Gensio_Control_Done *done = static_cast(user_data); std::vector valv(buf, buf + len); try { done->control_done(err, std::move(valv)); } catch (std::exception &e) { gensio_log(g->get_os_funcs(), GENSIO_LOG_ERR, "Received C++ exception in control done handler: %s", e.what()); } } int Gensio::acontrol(int depth, bool get, unsigned int option, const char *data, gensiods datalen, Gensio_Control_Done *done, gensio_time *timeout) { int err; if (done) err = gensio_acontrol(io, depth, get, option, data, datalen, gensio_cpp_control_done, done, timeout); else err = gensio_acontrol(io, depth, get, option, data, datalen, NULL, NULL, timeout); return err; } int Gensio::acontrol_s(int depth, bool get, unsigned int option, char *data, gensiods *datalen, gensio_time *timeout, bool intr) { if (intr) return gensio_acontrol_s_intr(io, depth, get, option, data, datalen, timeout); else return gensio_acontrol_s(io, depth, get, option, data, datalen, timeout); } int Gensio::read_s(std::vector &rvec, gensio_time *timeout, bool intr) { int err; gensiods len = (gensiods) rvec.capacity(), count = 0; unsigned char *buf = rvec.data(); rvec.resize(len); if (intr) err = gensio_read_s_intr(io, &count, buf, len, timeout); else err = gensio_read_s(io, &count, buf, len, timeout); if (err == GE_TIMEDOUT || err== GE_INTERRUPTED) return err; if (err) throw gensio_error(err); rvec.resize(count); return 0; } int Gensio::read_s(SimpleUCharVector &data, gensio_time *timeout, bool intr) { int err; gensiods len = data.capacity(), count = 0; if (intr) err = gensio_read_s_intr(io, &count, data.data(), len, timeout); else err = gensio_read_s(io, &count, data.data(), len, timeout); data.resize(count); if (err == GE_TIMEDOUT || err== GE_INTERRUPTED) return err; if (err) throw gensio_error(err); return 0; } struct gensio_acc_cpp_data { struct gensio_acc_frdata frdata; Accepter *a; }; class GENSIOCPP_DLL_PUBLIC Main_Raw_Accepter_Event_Handler: public Raw_Accepter_Event_Handler { public: Main_Raw_Accepter_Event_Handler() { } int handle(Accepter *a, int event, void *data) override { Accepter_Event *cb = a->get_cb(); struct gensio *io; try { switch (event) { case GENSIO_ACC_EVENT_NEW_CONNECTION: { io = (struct gensio *) data; Gensio *g = gensio_alloc(io, a->get_os_funcs(), NULL); a->raw_event_handler->new_connection(cb, g); break; } case GENSIO_ACC_EVENT_PARMLOG: { struct gensio_parmlog_data *d = (struct gensio_parmlog_data *) data; va_list argcopy; va_copy(argcopy, d->args); size_t len = vsnprintf(NULL, 0, d->log, argcopy); va_end(argcopy); std::string outstr(len + 1, '\0'); vsnprintf(&outstr[0], len + 1, d->log, d->args); cb->parmlog(std::move(outstr)); break; } case GENSIO_ACC_EVENT_LOG: { struct gensio_loginfo *l = (struct gensio_loginfo *) data; va_list argcopy; va_copy(argcopy, l->args); size_t len = vsnprintf(NULL, 0, l->str, argcopy); va_end(argcopy); std::string outstr(len + 1, '\0'); vsnprintf(&outstr[0], len + 1, l->str, l->args); cb->log(l->level, std::move(outstr)); break; } case GENSIO_ACC_EVENT_PRECERT_VERIFY: { io = (struct gensio *) data; Gensio g(io, a->get_os_funcs()); return cb->precert_verify(&g); } case GENSIO_ACC_EVENT_AUTH_BEGIN: { io = (struct gensio *) data; Gensio g(io, a->get_os_funcs()); return cb->auth_begin(&g); } case GENSIO_ACC_EVENT_PASSWORD_VERIFY: { struct gensio_acc_password_verify_data *p = (struct gensio_acc_password_verify_data *) data; std::string pwstr((char *) p->password); Gensio g(p->io, a->get_os_funcs()); return cb->password_verify(&g, std::move(pwstr)); } case GENSIO_ACC_EVENT_REQUEST_PASSWORD: { struct gensio_acc_password_verify_data *p = (struct gensio_acc_password_verify_data *) data; std::string pwstr(""); int rv; Gensio g(p->io, a->get_os_funcs()); rv = cb->request_password(&g, p->password_len, pwstr); if (rv) return rv; if (pwstr.size() > p->password_len) return GE_TOOBIG; p->password_len = (gensiods) pwstr.size(); memcpy(p->password, pwstr.c_str(), p->password_len); return 0; } case GENSIO_ACC_EVENT_2FA_VERIFY: { struct gensio_acc_password_verify_data *p = (struct gensio_acc_password_verify_data *) data; std::vector val(p->password, p->password + p->password_len); Gensio g(p->io, a->get_os_funcs()); return cb->verify_2fa(&g, std::move(val)); } case GENSIO_ACC_EVENT_REQUEST_2FA: { struct gensio_acc_password_verify_data *p = (struct gensio_acc_password_verify_data *) data; int rv; std::vector val(0); Gensio g(p->io, a->get_os_funcs()); Os_Funcs o = a->get_os_funcs(); unsigned char *rbuf; rv = cb->request_2fa(&g, val); if (rv) return rv; rbuf = (unsigned char *) o->zalloc(o, (gensiods) val.size()); if (!rbuf) return GE_NOMEM; p->password_len = (gensiods) val.size(); memcpy(rbuf, val.data(), p->password_len); *((unsigned char **) p->password) = rbuf; return 0; } case GENSIO_ACC_EVENT_POSTCERT_VERIFY: { struct gensio_acc_postcert_verify_data *p = (struct gensio_acc_postcert_verify_data *) data; Gensio g(p->io, a->get_os_funcs()); return cb->postcert_verify(&g, p->err, p->errstr); } default: return GE_NOTSUP; } } catch (std::exception &e) { gensio_log(a->get_os_funcs(), GENSIO_LOG_ERR, "Received C++ exception in accepter callback handler: %s", e.what()); return GE_APPERR; } return 0; } void new_connection(Accepter_Event *e, Gensio *new_g) override { if (e) e->new_connection(new_g); } void freed(Accepter_Event *e) override { if (e) e->freed(); } }; static int gensio_acc_cpp_cb(struct gensio_accepter *acc, void *user_data, int event, void *data) { Accepter *a = static_cast(user_data); return a->raw_event_handler->handle(a, event, data); } void gensio_acc_cpp_freed(struct gensio_accepter *acc, struct gensio_acc_frdata *frdata) { struct gensio_acc_cpp_data *d = gensio_container_of(frdata, struct gensio_acc_cpp_data, frdata); Accepter_Event *cb = d->a->get_cb(); d->a->set_event_handler(NULL); // See comments in gensio_cpp_freed if (d->a->raw_event_handler) d->a->raw_event_handler->freed(cb); else if (cb) cb->freed(); delete d->a; delete d; } void Accepter::set_accepter(struct gensio_accepter *acc, bool set_cb) { struct gensio_acc_cpp_data *d; try { d = new struct gensio_acc_cpp_data; } catch (...) { delete this; throw; } this->acc = acc; d->a = this; d->frdata.freed = gensio_acc_cpp_freed; gensio_acc_set_frdata(acc, &d->frdata); if (set_cb) { gensio_acc_set_callback(acc, gensio_acc_cpp_cb, this); try { this->raw_event_handler = new Main_Raw_Accepter_Event_Handler(); } catch (...) { delete d; delete this; throw; } } } Accepter *gensio_acc_alloc(struct gensio_accepter *acc, Os_Funcs &o) { struct gensio_accepter *cacc; unsigned int i; struct gensio_acc_frdata *f; struct gensio_acc_cpp_data *d; Accepter *a; // Set frdata for the gensio and all children. for (i = 0; (cacc = gensio_acc_get_child(acc, i)); i++) { if (gensio_acc_get_frdata(cacc)) break; // It's already been set. a = new Accepter(o, NULL); a->set_accepter(cacc, i == 0); } f = gensio_acc_get_frdata(acc); d = gensio_container_of(f, struct gensio_acc_cpp_data, frdata); return d->a; } static int init_gensio_acc_eventh(struct gensio_accepter *iacc, void *user_data, int event, void *data) { Accepter_Event *cb = static_cast(user_data); struct gensio_parmlog_data *p; if (event != GENSIO_ACC_EVENT_PARMLOG) return GE_NOTSUP; p = (struct gensio_parmlog_data *) data; va_list argcopy; va_copy(argcopy, p->args); size_t len = vsnprintf(NULL, 0, p->log, argcopy); va_end(argcopy); std::string outstr(len, '\0'); vsnprintf(&outstr[0], len + 1, p->log, p->args); cb->parmlog(std::move(outstr)); return 0; } Accepter *gensio_acc_alloc(std::string str, Os_Funcs &o, Accepter_Event *cb) { struct gensio_accepter *acc; int err; Accepter *a; err = str_to_gensio_accepter(str.c_str(), o, init_gensio_acc_eventh, cb, &acc); if (err) throw gensio_error(err); a = gensio_acc_alloc(acc, o); a->set_event_handler(cb); gensio_acc_set_callback(acc, gensio_acc_cpp_cb, a); return a; } Accepter *gensio_acc_alloc(Accepter *child, std::string str, Os_Funcs &o, Accepter_Event *cb) { struct gensio_accepter *acc; int err; Accepter *a; err = str_to_gensio_accepter_child(child->get_accepter(), str.c_str(), o, init_gensio_acc_eventh, cb, &acc); if (err) throw gensio_error(err); a = gensio_acc_alloc(acc, o); a->set_event_handler(cb); gensio_acc_set_callback(acc, gensio_acc_cpp_cb, a); return a; } Accepter * gensio_acc_alloc(const char *gensiotype, const void *gdata, const char * const args[], Os_Funcs &o, Accepter_Event *cb) { struct gensio_accepter *acc; int err; Accepter *a; err = gensio_terminal_acc_alloc(gensiotype, gdata, args, o, NULL, NULL, &acc); if (err) throw gensio_error(err); a = gensio_acc_alloc(acc, o); a->set_event_handler(cb); gensio_acc_set_callback(acc, gensio_acc_cpp_cb, a); return a; } Accepter *gensio_acc_alloc(const char *gensiotype, Accepter *child, const char * const args[], Os_Funcs &o, Accepter_Event *cb) { struct gensio_accepter *acc; int err; Accepter *a; err = gensio_filter_acc_alloc(gensiotype, child->get_accepter(), args, o, NULL, NULL, &acc); if (err) throw gensio_error(err); a = gensio_acc_alloc(acc, o); a->set_event_handler(cb); gensio_acc_set_callback(acc, gensio_acc_cpp_cb, a); return a; } void Accepter::free() { gensio_acc_free(acc); } void Accepter::startup() { int err = gensio_acc_startup(acc); if (err) throw gensio_error(err); } static void gensio_acc_cpp_shutdown_done(struct gensio_accepter *acc, void *user_data) { if (!user_data) return; struct gensio_acc_frdata *f = gensio_acc_get_frdata(acc); struct gensio_acc_cpp_data *d = gensio_container_of(f, struct gensio_acc_cpp_data, frdata); Accepter *a = d->a; Accepter_Shutdown_Done *done = static_cast(user_data); try { done->shutdown_done(); } catch (std::exception &e) { gensio_log(a->get_os_funcs(), GENSIO_LOG_ERR, "Received C++ exception in accepter done handler: %s", e.what()); } } void Accepter::shutdown(Accepter_Shutdown_Done *done) { int err; if (done) err = gensio_acc_shutdown(acc, gensio_acc_cpp_shutdown_done, done); else err = gensio_acc_shutdown(acc, NULL, NULL);; if (err) throw gensio_error(err); } void Accepter::shutdown_s() { int err = gensio_acc_shutdown_s(acc); if (err) throw gensio_error(err); } static void gensio_acc_cpp_enable_done(struct gensio_accepter *acc, void *user_data) { if (!user_data) return; struct gensio_acc_frdata *f = gensio_acc_get_frdata(acc); struct gensio_acc_cpp_data *d = gensio_container_of(f, struct gensio_acc_cpp_data, frdata); Accepter *a = d->a; Accepter_Enable_Done *done = static_cast(user_data); try { done->enable_done(); } catch (std::exception &e) { gensio_log(a->get_os_funcs(), GENSIO_LOG_ERR, "Received C++ exception in accepter done handler: %s", e.what()); } } void Accepter::set_callback_enable(bool enabled, Accepter_Enable_Done *done) { int err; if (done) err = gensio_acc_set_accept_callback_enable_cb(acc, enabled, gensio_acc_cpp_enable_done, done); else err = gensio_acc_set_accept_callback_enable_cb(acc, enabled, NULL, NULL); if (err) throw gensio_error(err); } void Accepter::set_callback_enable_s(bool enabled) { int err = gensio_acc_set_accept_callback_enable_s(acc, enabled); if (err) throw gensio_error(err); } int Accepter::control(int depth, bool get, unsigned int option, char *data, gensiods *datalen) { return gensio_acc_control(acc, depth, get, option, data, datalen); } int Accepter::accept_s(Gensio **g, gensio_time *timeout, bool intr) { struct gensio *io; int err; if (intr) err = gensio_acc_accept_s_intr(acc, timeout, &io); else err = gensio_acc_accept_s(acc, timeout, &io); if (err == GE_TIMEDOUT || err == GE_INTERRUPTED) return err; if (err) throw gensio_error(err); *g = gensio_alloc(io, go, NULL); return 0; } Gensio *Accepter::str_to_gensio(std::string str, Event *cb) { struct gensio *io; Gensio *g; int err = gensio_acc_str_to_gensio(acc, str.c_str(), init_gensio_eventh, cb, &io); if (err) throw gensio_error(err); g = gensio_alloc(io, go, cb); return g; } std::string Accepter::get_port() const { char portbuf[100]; gensiods len = sizeof(portbuf); portbuf[0] = '0'; portbuf[1] = '\0'; int err = gensio_acc_control(acc, GENSIO_CONTROL_DEPTH_FIRST, true, GENSIO_ACC_CONTROL_LPORT, portbuf, &len); if (err) throw gensio_error(err); return std::string(portbuf, len); } } gensio-3.0.0/c++/lib/gensioosh.cc0000664000175000017500000001514314666640102012115 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only #include #include namespace gensios { #include #include #include #include std::string err_to_string(int err) { return std::string(gensio_err_to_str(err)); } std::string log_level_to_str(enum gensio_log_levels level) { return std::string(gensio_log_level_to_str(level)); } void set_log_mask(int mask) { gensio_set_log_mask(mask); } int get_log_mask() { return gensio_get_log_mask(); } void gensio_cpp_vlog_handler(struct gensio_os_funcs *io, enum gensio_log_levels level, const char *log, va_list args) { class Os_Funcs *o = static_cast(gensio_os_funcs_get_data(io)); Os_Funcs_Log_Handler *logger = o->get_log_handler(); if (logger) { va_list argcopy; va_copy(argcopy, args); size_t len = vsnprintf(NULL, 0, log, argcopy); va_end(argcopy); std::string outstr(len + 1, '\0'); vsnprintf(&outstr[0], len + 1, log, args); logger->log(level, std::move(outstr)); } } void Os_Funcs::init(struct gensio_os_funcs *o, Os_Funcs_Log_Handler *ilogger) { logger = ilogger; refcnt = new std::atomic(1); osf = o; gensio_os_funcs_set_vlog(osf, gensio_cpp_vlog_handler); gensio_os_funcs_set_data(osf, this); } Os_Funcs::Os_Funcs(int wait_sig, Os_Funcs_Log_Handler *logger) { int err; struct gensio_os_funcs *o; if (wait_sig == -1) wait_sig = GENSIO_DEF_WAKE_SIG; err = gensio_alloc_os_funcs(wait_sig, &o, 0); if (err) throw gensio_error(err); this->init(o, logger); } Os_Funcs::Os_Funcs(int wait_sig, Os_Funcs_Log_Handler *logger, unsigned int flags, ...) { int err; struct gensio_os_funcs *o; va_list ap; if (wait_sig == -1) wait_sig = GENSIO_DEF_WAKE_SIG; va_start(ap, flags); err = gensio_valloc_os_funcs(wait_sig, &o, flags, ap); va_end(ap); if (err) throw gensio_error(err); this->init(o, logger); } void Os_Funcs::proc_setup() { int err; err = gensio_os_proc_setup(osf, &proc_data); if (err) throw gensio_error(err); } void Os_Funcs::thread_setup() { int err; err = gensio_os_thread_setup(osf); if (err) throw gensio_error(err); } void thread_start_func(void *data) { Os_Funcs_Thread_Func *start_func = static_cast(data); start_func->start(); } struct gensio_thread * Os_Funcs::new_thread(Os_Funcs_Thread_Func *start_func) { int err; struct gensio_thread *id; err = gensio_os_new_thread(*this, thread_start_func, start_func, &id); if (err) throw gensio_error(err); return id; } void Os_Funcs::wait_thread(struct gensio_thread *thread_id) { int err = gensio_os_wait_thread(thread_id); if (err) throw gensio_error(err); } void Os_Funcs::refcount_from(const Os_Funcs *o) { std::atomic *old_refcnt = refcnt; struct gensio_os_funcs *old_osf = osf; refcnt = o->refcnt; osf = o->osf; logger = o->logger; ++*refcnt; if (old_refcnt) { if (old_refcnt->fetch_sub(1) == 1) { gensio_os_funcs_free(old_osf); delete old_refcnt; } } } Os_Funcs& Os_Funcs::operator=(const Os_Funcs &o) { refcount_from(&o); return *this; } Os_Funcs::Os_Funcs(const Os_Funcs &o) { refcount_from(&o); } Os_Funcs::~Os_Funcs() { if (proc_data) gensio_os_proc_cleanup(proc_data); if (refcnt->fetch_sub(1) == 1) { gensio_os_funcs_free(osf); if (logger) delete logger; delete refcnt; } } Addr::Addr(Os_Funcs &o, std::string str, bool listen, int *protocol, int *argc, const char ***args) { int err; err = gensio_scan_network_port(o, str.c_str(), listen, &gaddr, protocol, &is_port_set, argc, args); if (err) throw gensio_error(err); } Addr::Addr(Os_Funcs &o, std::string str, bool listen, int protocol) { int err; is_port_set = true; err = gensio_os_scan_netaddr(o, str.c_str(), listen, protocol, &gaddr); if (err) throw gensio_error(err); } Addr::Addr(Os_Funcs &o, int nettype, const void *iaddr, gensiods len, unsigned int port) { int err; this->is_port_set = port != 0; err = gensio_addr_create(o, nettype, iaddr, len, port, &gaddr); if (err) throw gensio_error(err); } Addr::~Addr() { if (gaddr) gensio_addr_free(gaddr); } std::string do_to_string(struct gensio_addr *addr, bool all) { int err; gensiods len = 0; char *buf = NULL; std::string s; if (all) err = gensio_addr_to_str_all(addr, buf, &len, 0); else err = gensio_addr_to_str(addr, buf, &len, 0); if (err) throw gensio_error(err); buf = new char[len + 1]; if (all) err = gensio_addr_to_str_all(addr, buf, NULL, len + 1); else err = gensio_addr_to_str(addr, buf, NULL, len + 1); if (err) { delete[] buf; throw gensio_error(err); } try { s = std::string(buf); } catch (...) { delete[] buf; throw; } delete[] buf; return s; } std::string Addr::to_string() const { return do_to_string(gaddr, false); } std::string Addr::to_string_all() const { return do_to_string(gaddr, true); } void Addr::getaddr(std::vector &rvec) { gensiods len = (gensiods) rvec.capacity(), count = len; gensio_addr_getaddr(gaddr, rvec.data(), &count); rvec.resize(count); if (count > len) gensio_addr_getaddr(gaddr, rvec.data(), &count); } void Addr::get_data(std::vector &rvec) { gensiods len = (gensiods) rvec.capacity(), count = len; unsigned char *buf = rvec.data(); gensio_addr_get_data(gaddr, buf, &count); rvec.resize(count); if (count > len) gensio_addr_get_data(gaddr, buf, &count); } Waiter::Waiter(Os_Funcs &io) : o(io) { waiter = gensio_os_funcs_alloc_waiter(o); if (!waiter) throw std::bad_alloc(); } Waiter::~Waiter() { gensio_os_funcs_free_waiter(o, waiter); } void Waiter::wake() { gensio_os_funcs_wake(o, waiter); } int Waiter::wait(unsigned int count, gensio_time *timeout, bool intr) { int rv; if (intr) rv = gensio_os_funcs_wait_intr_sigmask(o, waiter, count, timeout, o.get_proc_data()); else rv = gensio_os_funcs_wait(o, waiter, count, timeout); if (rv == GE_TIMEDOUT || rv == GE_INTERRUPTED) return rv; if (rv) throw gensio_error(rv); return 0; } } gensio-3.0.0/c++/lib/Makefile.in0000664000175000017500000010144415061121657011654 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = c++/lib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = libgensiooshcpp.pc libgensiocpp.pc \ libgensiomdnscpp.pc CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" \ "$(DESTDIR)$(pkgconfigexecdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libgensiocpp_la_DEPENDENCIES = libgensiooshcpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la am_libgensiocpp_la_OBJECTS = libgensiocpp_la-gensio.lo libgensiocpp_la_OBJECTS = $(am_libgensiocpp_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libgensiocpp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(AM_CXXFLAGS) $(CXXFLAGS) $(libgensiocpp_la_LDFLAGS) \ $(LDFLAGS) -o $@ libgensiomdnscpp_la_DEPENDENCIES = libgensiooshcpp.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/lib/libgensiomdns.la am_libgensiomdnscpp_la_OBJECTS = libgensiomdnscpp_la-gensiomdns.lo libgensiomdnscpp_la_OBJECTS = $(am_libgensiomdnscpp_la_OBJECTS) libgensiomdnscpp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(AM_CXXFLAGS) $(CXXFLAGS) $(libgensiomdnscpp_la_LDFLAGS) \ $(LDFLAGS) -o $@ libgensiooshcpp_la_DEPENDENCIES = $(top_builddir)/lib/libgensioosh.la am_libgensiooshcpp_la_OBJECTS = libgensiooshcpp_la-gensioosh.lo libgensiooshcpp_la_OBJECTS = $(am_libgensiooshcpp_la_OBJECTS) libgensiooshcpp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(AM_CXXFLAGS) $(CXXFLAGS) $(libgensiooshcpp_la_LDFLAGS) \ $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/libgensiocpp_la-gensio.Plo \ ./$(DEPDIR)/libgensiomdnscpp_la-gensiomdns.Plo \ ./$(DEPDIR)/libgensiooshcpp_la-gensioosh.Plo am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(libgensiocpp_la_SOURCES) $(libgensiomdnscpp_la_SOURCES) \ $(libgensiooshcpp_la_SOURCES) DIST_SOURCES = $(libgensiocpp_la_SOURCES) \ $(libgensiomdnscpp_la_SOURCES) $(libgensiooshcpp_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(pkgconfigexec_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/libgensiocpp.pc.in \ $(srcdir)/libgensiomdnscpp.pc.in \ $(srcdir)/libgensiooshcpp.pc.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ lib_LTLIBRARIES = libgensiooshcpp.la libgensiocpp.la \ libgensiomdnscpp.la pkgconfigexecdir = $(libdir)/pkgconfig libgensiooshcpp_la_SOURCES = gensioosh.cc libgensiooshcpp_la_CPPFLAGS = -DBUILDING_GENSIOOSHCPP_DLL libgensiooshcpp_la_LIBADD = $(top_builddir)/lib/libgensioosh.la libgensiooshcpp_la_LDFLAGS = -no-undefined -rpath $(libdir) \ -version-info $(GENSIO_LIB_VERSION) -fvisibility=hidden # This variable must have 'exec' in its name, in order to be installed # by 'install-exec' target (instead of default 'install-data') pkgconfigexec_DATA = libgensiooshcpp.pc libgensiocpp.pc \ libgensiomdnscpp.pc libgensiocpp_la_SOURCES = gensio.cc libgensiocpp_la_CPPFLAGS = -DBUILDING_GENSIOCPP_DLL libgensiocpp_la_LIBADD = libgensiooshcpp.la $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la libgensiocpp_la_LDFLAGS = -no-undefined -rpath $(libdir) \ -version-info $(GENSIO_LIB_VERSION) -fvisibility=hidden libgensiomdnscpp_la_SOURCES = gensiomdns.cc libgensiomdnscpp_la_CPPFLAGS = -DBUILDING_GENSIOMDNSCPP_DLL libgensiomdnscpp_la_LIBADD = libgensiooshcpp.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/lib/libgensiomdns.la libgensiomdnscpp_la_LDFLAGS = -no-undefined -rpath $(libdir) \ -version-info $(GENSIO_LIB_VERSION) -fvisibility=hidden EXTRA_DIST = libgensiooshcpp.pc.in libgensiocpp.pc.in libgensiomdnscpp.pc.in all: all-am .SUFFIXES: .SUFFIXES: .cc .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/lib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/lib/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): libgensiooshcpp.pc: $(top_builddir)/config.status $(srcdir)/libgensiooshcpp.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ libgensiocpp.pc: $(top_builddir)/config.status $(srcdir)/libgensiocpp.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ libgensiomdnscpp.pc: $(top_builddir)/config.status $(srcdir)/libgensiomdnscpp.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libgensiocpp.la: $(libgensiocpp_la_OBJECTS) $(libgensiocpp_la_DEPENDENCIES) $(EXTRA_libgensiocpp_la_DEPENDENCIES) $(AM_V_CXXLD)$(libgensiocpp_la_LINK) -rpath $(libdir) $(libgensiocpp_la_OBJECTS) $(libgensiocpp_la_LIBADD) $(LIBS) libgensiomdnscpp.la: $(libgensiomdnscpp_la_OBJECTS) $(libgensiomdnscpp_la_DEPENDENCIES) $(EXTRA_libgensiomdnscpp_la_DEPENDENCIES) $(AM_V_CXXLD)$(libgensiomdnscpp_la_LINK) -rpath $(libdir) $(libgensiomdnscpp_la_OBJECTS) $(libgensiomdnscpp_la_LIBADD) $(LIBS) libgensiooshcpp.la: $(libgensiooshcpp_la_OBJECTS) $(libgensiooshcpp_la_DEPENDENCIES) $(EXTRA_libgensiooshcpp_la_DEPENDENCIES) $(AM_V_CXXLD)$(libgensiooshcpp_la_LINK) -rpath $(libdir) $(libgensiooshcpp_la_OBJECTS) $(libgensiooshcpp_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensiocpp_la-gensio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensiomdnscpp_la-gensiomdns.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgensiooshcpp_la-gensioosh.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< libgensiocpp_la-gensio.lo: gensio.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensiocpp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libgensiocpp_la-gensio.lo -MD -MP -MF $(DEPDIR)/libgensiocpp_la-gensio.Tpo -c -o libgensiocpp_la-gensio.lo `test -f 'gensio.cc' || echo '$(srcdir)/'`gensio.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensiocpp_la-gensio.Tpo $(DEPDIR)/libgensiocpp_la-gensio.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gensio.cc' object='libgensiocpp_la-gensio.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensiocpp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libgensiocpp_la-gensio.lo `test -f 'gensio.cc' || echo '$(srcdir)/'`gensio.cc libgensiomdnscpp_la-gensiomdns.lo: gensiomdns.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensiomdnscpp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libgensiomdnscpp_la-gensiomdns.lo -MD -MP -MF $(DEPDIR)/libgensiomdnscpp_la-gensiomdns.Tpo -c -o libgensiomdnscpp_la-gensiomdns.lo `test -f 'gensiomdns.cc' || echo '$(srcdir)/'`gensiomdns.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensiomdnscpp_la-gensiomdns.Tpo $(DEPDIR)/libgensiomdnscpp_la-gensiomdns.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gensiomdns.cc' object='libgensiomdnscpp_la-gensiomdns.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensiomdnscpp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libgensiomdnscpp_la-gensiomdns.lo `test -f 'gensiomdns.cc' || echo '$(srcdir)/'`gensiomdns.cc libgensiooshcpp_la-gensioosh.lo: gensioosh.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensiooshcpp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libgensiooshcpp_la-gensioosh.lo -MD -MP -MF $(DEPDIR)/libgensiooshcpp_la-gensioosh.Tpo -c -o libgensiooshcpp_la-gensioosh.lo `test -f 'gensioosh.cc' || echo '$(srcdir)/'`gensioosh.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgensiooshcpp_la-gensioosh.Tpo $(DEPDIR)/libgensiooshcpp_la-gensioosh.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gensioosh.cc' object='libgensiooshcpp_la-gensioosh.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgensiooshcpp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libgensiooshcpp_la-gensioosh.lo `test -f 'gensioosh.cc' || echo '$(srcdir)/'`gensioosh.cc mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkgconfigexecDATA: $(pkgconfigexec_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfigexec_DATA)'; test -n "$(pkgconfigexecdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigexecdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigexecdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigexecdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigexecdir)" || exit $$?; \ done uninstall-pkgconfigexecDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfigexec_DATA)'; test -n "$(pkgconfigexecdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigexecdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(DATA) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigexecdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/libgensiocpp_la-gensio.Plo -rm -f ./$(DEPDIR)/libgensiomdnscpp_la-gensiomdns.Plo -rm -f ./$(DEPDIR)/libgensiooshcpp_la-gensioosh.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-pkgconfigexecDATA install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libgensiocpp_la-gensio.Plo -rm -f ./$(DEPDIR)/libgensiomdnscpp_la-gensiomdns.Plo -rm -f ./$(DEPDIR)/libgensiooshcpp_la-gensioosh.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES uninstall-pkgconfigexecDATA .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-libLTLIBRARIES install-man install-pdf \ install-pdf-am install-pkgconfigexecDATA install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-libLTLIBRARIES \ uninstall-pkgconfigexecDATA .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/c++/lib/libgensiocpp.pc.in0000664000175000017500000000033514664224267013224 prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libgensiocpp Description: A C++ library wrapper around gensio Version: @VERSION@ Libs: -L${libdir} -lgensiocpp -lgensio -lgensioosh gensio-3.0.0/c++/lib/libgensiooshcpp.pc.in0000664000175000017500000000035614664224267013741 prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libgensiooshcpp Description: A C++ library wrapper around gensio OS handler Version: @VERSION@ Libs: -L${libdir} -lgensiooshcpp -lgensio -lgensioosh gensio-3.0.0/c++/lib/Makefile.am0000664000175000017500000000262114664224267011651 lib_LTLIBRARIES = libgensiooshcpp.la libgensiocpp.la pkgconfigexecdir = $(libdir)/pkgconfig libgensiooshcpp_la_SOURCES = gensioosh.cc libgensiooshcpp_la_CPPFLAGS = -DBUILDING_GENSIOOSHCPP_DLL libgensiooshcpp_la_LIBADD = $(top_builddir)/lib/libgensioosh.la libgensiooshcpp_la_LDFLAGS = -no-undefined -rpath $(libdir) \ -version-info $(GENSIO_LIB_VERSION) -fvisibility=hidden pkgconfigexec_DATA = libgensiooshcpp.pc libgensiocpp_la_SOURCES = gensio.cc libgensiocpp_la_CPPFLAGS = -DBUILDING_GENSIOCPP_DLL libgensiocpp_la_LIBADD = libgensiooshcpp.la $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la libgensiocpp_la_LDFLAGS = -no-undefined -rpath $(libdir) \ -version-info $(GENSIO_LIB_VERSION) -fvisibility=hidden # This variable must have 'exec' in its name, in order to be installed # by 'install-exec' target (instead of default 'install-data') pkgconfigexec_DATA += libgensiocpp.pc lib_LTLIBRARIES += libgensiomdnscpp.la libgensiomdnscpp_la_SOURCES = gensiomdns.cc libgensiomdnscpp_la_CPPFLAGS = -DBUILDING_GENSIOMDNSCPP_DLL libgensiomdnscpp_la_LIBADD = libgensiooshcpp.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/lib/libgensiomdns.la libgensiomdnscpp_la_LDFLAGS = -no-undefined -rpath $(libdir) \ -version-info $(GENSIO_LIB_VERSION) -fvisibility=hidden pkgconfigexec_DATA += libgensiomdnscpp.pc EXTRA_DIST = libgensiooshcpp.pc.in libgensiocpp.pc.in libgensiomdnscpp.pc.in gensio-3.0.0/c++/lib/gensiomdns.cc0000664000175000017500000001535614664224267012303 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only #include #include namespace gensios { MDNS::MDNS(Os_Funcs &o): go(o) { int rv; rv = gensio_alloc_mdns(o, &this->m); if (rv) throw gensio_error(rv); } void mdns_free_done(struct gensio_mdns *m, void *user_data) { if (!user_data) return; MDNS_Free_Done *done = static_cast(user_data); MDNS *mdns = done->m; try { done->mdns_free_done(); } catch (std::exception &e) { gensio_log(done->m->get_os_funcs(), GENSIO_LOG_ERR, "Received C++ exception in mdns open done handler: %s", e.what()); } delete mdns; } void MDNS::free(MDNS_Free_Done *done) { int rv; if (done) { done->m = this; rv = gensio_free_mdns(this->m, mdns_free_done, done); } else { rv = gensio_free_mdns(this->m, NULL, NULL); } if (rv) throw gensio_error(rv); } MDNS_Service *MDNS::add_service(int interfacenum, int ipdomain, const char *name, const char *type, const char *domain, const char *host, int port, const char * const *txt, MDNS_Service_Event *event, Raw_MDNS_Service_Event_Handler *evh) { return new MDNS_Service(this, interfacenum, ipdomain, name, type, domain, host, port, txt, event, evh); } MDNS_Watch *MDNS::add_watch(int interfacenum, int ipdomain, const char *name, const char *type, const char *domain, const char *host, MDNS_Watch_Event *event, Raw_MDNS_Event_Handler *evh) { return new MDNS_Watch(this, interfacenum, ipdomain, name, type, domain, host, event, evh); } class GENSIOMDNSCPP_DLL_PUBLIC Main_Raw_MDNS_Service_Event_Handler: public Raw_MDNS_Service_Event_Handler { public: Main_Raw_MDNS_Service_Event_Handler(Os_Funcs io): o(io) { } Os_Funcs o; void handle(MDNS_Service_Event *event, enum gensio_mdns_service_event ev, const char *info) override { try { if (event) event->event(ev, info); } catch (std::exception &e) { gensio_log(o, GENSIO_LOG_ERR, "Received C++ exception in mdns service event handler: %s", e.what()); } } }; void mdns_service_event(struct gensio_mdns_service *se, enum gensio_mdns_service_event ev, const char *info, void *userdata) { MDNS_Service *s = static_cast(userdata); try { s->raw_event_handler->handle(s->event, ev, info); } catch (std::exception &e) { gensio_log(s->get_os_funcs(), GENSIO_LOG_ERR, "Received C++ exception in mdns service event handler: %s", e.what()); } if (ev == GENSIO_MDNS_SERVICE_REMOVED) delete s; } MDNS_Service::MDNS_Service(MDNS *m, int interfacenum, int ipdomain, const char *name, const char *type, const char *domain, const char *host, int port, const char * const *txt, MDNS_Service_Event *event, Raw_MDNS_Service_Event_Handler *raw_event_handler) { int rv; this->m = m; this->event = event; if (event) event->s = this; this->raw_event_handler = new Main_Raw_MDNS_Service_Event_Handler(m->go); if (raw_event_handler) { raw_event_handler->set_parent(this->raw_event_handler); this->raw_event_handler = raw_event_handler; } rv = gensio_mdns_add_service2(m->m, interfacenum, ipdomain, name, type, domain, host, port, txt, mdns_service_event, this, &this->s); if (rv) { delete this->raw_event_handler; throw gensio_error(rv); } } void MDNS_Service::free() { /* FIXME - no return code handling from this, C++ gives an error. */ gensio_mdns_remove_service(this->s); } class GENSIOMDNSCPP_DLL_PUBLIC Main_Raw_MDNS_Event_Handler: public Raw_MDNS_Event_Handler { public: Main_Raw_MDNS_Event_Handler(Os_Funcs io): o(io) { } Os_Funcs o; void handle(MDNS_Watch_Event *event, enum gensio_mdns_data_state state, int interfacenum, int ipdomain, const char *name, const char *type, const char *domain, const char *host, const struct gensio_addr *addr, const char * const *txt) override { struct gensio_addr *naddr = NULL; if (addr) { naddr = gensio_addr_dup(addr); if (!naddr) { gensio_log(o, GENSIO_LOG_ERR, "Memory allocation failure in mdns watch event"); return; } } try { if (naddr) { Addr a(naddr); event->event(state, interfacenum, ipdomain, name, type, domain, host, &a, txt); } else { event->event(state, interfacenum, ipdomain, name, type, domain, host, NULL, txt); } } catch (std::exception &e) { gensio_log(o, GENSIO_LOG_ERR, "Received C++ exception in mdns watch event handler: %s", e.what()); } } }; void mdns_watch_event(struct gensio_mdns_watch *w, enum gensio_mdns_data_state state, int interfacenum, int ipdomain, const char *name, const char *type, const char *domain, const char *host, const struct gensio_addr *addr, const char * const *txt, void *userdata) { MDNS_Watch_Event *event = static_cast(userdata); event->w->raw_event_handler->handle(event, state, interfacenum, ipdomain, name, type, domain, host, addr, txt); } MDNS_Watch::MDNS_Watch(MDNS *m, int interfacenum, int ipdomain, const char *name, const char *type, const char *domain, const char *host, MDNS_Watch_Event *event, Raw_MDNS_Event_Handler *raw_event_handler) { int rv; this->m = m; this->event = event; event->w = this; this->raw_event_handler = new Main_Raw_MDNS_Event_Handler(m->go); if (raw_event_handler) { raw_event_handler->set_parent(this->raw_event_handler); this->raw_event_handler = raw_event_handler; } rv = gensio_mdns_add_watch(m->m, interfacenum, ipdomain, name, type, domain, host, mdns_watch_event, event, &this->w); if (rv) { delete this->raw_event_handler; throw gensio_error(rv); } } void mdns_watch_free_done(struct gensio_mdns_watch *w, void *user_data) { if (!user_data) return; MDNS_Watch_Free_Done *done = static_cast(user_data); MDNS_Watch *watch = done->w; try { done->mdns_watch_free_done(); } catch (std::exception &e) { gensio_log(done->w->get_os_funcs(), GENSIO_LOG_ERR, "Received C++ exception in mdns watch done handler: %s", e.what()); } delete watch; } void MDNS_Watch::free(MDNS_Watch_Free_Done *done) { if (done) { done->w = this; gensio_mdns_remove_watch(this->w, mdns_watch_free_done, done); } else { gensio_mdns_remove_watch(this->w, NULL, NULL); } } } gensio-3.0.0/c++/examples/0000775000175000017500000000000015061121734010727 5gensio-3.0.0/c++/examples/mdns.cc0000664000175000017500000001005714666640102012127 // // Copyright 2021 Corey Minyard // // SPDX-License-Identifier: Apache-2.0 // This does some basic MDNS operations. #include #include #include #include #include using namespace std; using namespace gensios; class Watch_Event: public MDNS_Watch_Event { public: Watch_Event(Waiter *w) { waiter = w; } private: void event(enum gensio_mdns_data_state state, int interfacenum, int ipdomain, const char *name, const char *type, const char *domain, const char *host, const Addr *addr, const char * const *txt) override { if (state != GENSIO_MDNS_WATCH_NEW_DATA) return; cout << "Got MDNS interface " << interfacenum << " ipdomain " << ipdomain << endl; cout << " name:" << name << endl; cout << " type:" << type << endl; cout << " domain:" << domain << endl; cout << " host:" << host << endl; cout << " addr:" << addr->to_string() << endl; if (txt) { cout << " txt:" << endl; for (unsigned int i = 0; txt[i]; i++) cout << " " << txt[i] << endl; } if (!woken) { woken = true; waiter->wake(); } } bool woken = false; Waiter *waiter; }; class Watch_Done: public MDNS_Watch_Free_Done { public: Watch_Done(Waiter *w) { waiter = w; } private: void mdns_watch_free_done() { waiter->wake(); } Waiter *waiter; }; class Service_Event: public MDNS_Service_Event { public: Service_Event(Waiter *w) { waiter = w; } private: void event(enum gensio_mdns_service_event ev, const char *info) override { if (ev == GENSIO_MDNS_SERVICE_REMOVED) { cout << "MDNS service removed" << endl; waiter->wake(); return; } if (ev == GENSIO_MDNS_SERVICE_READY) { cout << "MDNS service ready with name " << info << endl; waiter->wake(); } else if (ev == GENSIO_MDNS_SERVICE_READY_NEW_NAME) { cout << "MDNS service ready with new name " << info << endl; waiter->wake(); } else if (ev == GENSIO_MDNS_SERVICE_ERROR) { cout << "MDNS service error: " << info << endl; } } Waiter *waiter; }; class Done: public MDNS_Free_Done { public: Done(Waiter *w) { waiter = w; } private: void mdns_free_done() { waiter->wake(); } Waiter *waiter; }; // Internal gensio errors come in through this mechanism. class MDNS_Logger: public Os_Funcs_Log_Handler { void log(enum gensio_log_levels level, const std::string log) override { std::cerr << "gensio " << gensio_log_level_to_str(level) << " log: " << log << std::endl; } }; int main(int argc, char *argv[]) { int err = 1; try { Os_Funcs o(0, new MDNS_Logger); Waiter w(o); Waiter w2(o); Watch_Event e(&w); Service_Event s(&w2); Watch_Done d(&w); Done d2(&w); MDNS *m; const char *txt[3] = { "k1=gensio1-1", "k2=gensio1-2", NULL }; MDNS_Service *serv; MDNS_Watch *watch; gensio_time timeout; int rv; o.proc_setup(); m = new MDNS(o); serv = m->add_service(-1, GENSIO_NETTYPE_UNSPEC, "gensio1", "_gensio1._tcp", NULL, NULL, 5001, txt, &s); watch = m->add_watch(-1, GENSIO_NETTYPE_UNSPEC, "gensio1", "_gensio1._tcp", NULL, NULL, &e); timeout.secs = 2; timeout.nsecs = 0; rv = w2.wait(1, &timeout); // Wait for the service to be done if (rv) { std::cerr << "Error waiting for service to be ready: " << gensio_err_to_str(rv) << std::endl; goto out; } timeout.secs = 2; timeout.nsecs = 0; rv = w.wait(1, &timeout); if (rv) { std::cerr << "Error waiting for watch to be ready: " << gensio_err_to_str(rv) << std::endl; goto out; } serv->free(); watch->free(&d); m->free(&d2); timeout.secs = 2; timeout.nsecs = 0; rv = w.wait(1, &timeout); if (rv) { std::cerr << "Error waiting for watch to be freed: " << gensio_err_to_str(rv) << std::endl; goto out; } rv = w2.wait(1, &timeout); if (rv) { std::cerr << "Error waiting for service to be freed: " << gensio_err_to_str(rv) << std::endl; goto out; } err = 0; } catch (gensio_error &e) { cerr << "gensio error: " << e.what() << endl; } out: return err; } gensio-3.0.0/c++/examples/Makefile.in0000664000175000017500000006003015061121657012717 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ noinst_PROGRAMS = telnet_server$(EXEEXT) telnet_client$(EXEEXT) \ mdns$(EXEEXT) subdir = c++/examples ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) am_mdns_OBJECTS = mdns.$(OBJEXT) mdns_OBJECTS = $(am_mdns_OBJECTS) mdns_DEPENDENCIES = $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/c++/lib/libgensiomdnscpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am_telnet_client_OBJECTS = telnet_client.$(OBJEXT) telnet_client_OBJECTS = $(am_telnet_client_OBJECTS) telnet_client_DEPENDENCIES = \ $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/lib/libgensio.la am_telnet_server_OBJECTS = telnet_server.$(OBJEXT) telnet_server_OBJECTS = $(am_telnet_server_OBJECTS) telnet_server_DEPENDENCIES = \ $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/lib/libgensio.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/mdns.Po ./$(DEPDIR)/telnet_client.Po \ ./$(DEPDIR)/telnet_server.Po am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(mdns_SOURCES) $(telnet_client_SOURCES) \ $(telnet_server_SOURCES) DIST_SOURCES = $(mdns_SOURCES) $(telnet_client_SOURCES) \ $(telnet_server_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_srcdir)/c++/include telnet_server_SOURCES = telnet_server.cc telnet_server_LDADD = $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/lib/libgensio.la telnet_client_SOURCES = telnet_client.cc telnet_client_LDADD = $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/lib/libgensio.la mdns_SOURCES = mdns.cc mdns_LDADD = $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/c++/lib/libgensiomdnscpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la all: all-am .SUFFIXES: .SUFFIXES: .cc .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/examples/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/examples/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list mdns$(EXEEXT): $(mdns_OBJECTS) $(mdns_DEPENDENCIES) $(EXTRA_mdns_DEPENDENCIES) @rm -f mdns$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(mdns_OBJECTS) $(mdns_LDADD) $(LIBS) telnet_client$(EXEEXT): $(telnet_client_OBJECTS) $(telnet_client_DEPENDENCIES) $(EXTRA_telnet_client_DEPENDENCIES) @rm -f telnet_client$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(telnet_client_OBJECTS) $(telnet_client_LDADD) $(LIBS) telnet_server$(EXEEXT): $(telnet_server_OBJECTS) $(telnet_server_DEPENDENCIES) $(EXTRA_telnet_server_DEPENDENCIES) @rm -f telnet_server$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(telnet_server_OBJECTS) $(telnet_server_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mdns.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/telnet_client.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/telnet_server.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/mdns.Po -rm -f ./$(DEPDIR)/telnet_client.Po -rm -f ./$(DEPDIR)/telnet_server.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/mdns.Po -rm -f ./$(DEPDIR)/telnet_client.Po -rm -f ./$(DEPDIR)/telnet_server.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/c++/examples/telnet_client.cc0000664000175000017500000000735714666640102014030 // // Copyright 2021 Corey Minyard // // SPDX-License-Identifier: Apache-2.0 // This is a basic telnet client, it makes a telnet connection and in // line mode sends anything typed on stdin to the telnet server and // prints anything that comes back to stdout. // // This demonstrates using an GensioW. #include #include #include using namespace gensios; // This is a Gensio event handler for the client. It transfers read // data from it's gensio (io) to the other gensio (otherio). class Client_Event: public Event { public: Client_Event(Waiter *w) { waiter = w; } // This allows the user to determine if the event handler had an // error. int get_err() { return err; } void set_gensios(Gensio *g, Gensio *og) { io = g; otherio = og; } private: // Handle errors, and if no error write the read data into the // other gensio. gensiods read(int ierr, const SimpleUCharVector data, const char *const *auxdata) override { gensiods count; if (ierr) { err = ierr; io->set_read_callback_enable(false); io->set_write_callback_enable(false); waiter->wake(); return 0; } try { count = otherio->write(data.data(), data.size(), NULL); } catch (gensio_error &e) { err = e.get_error(); io->set_read_callback_enable(false); io->set_write_callback_enable(false); otherio->set_read_callback_enable(false); otherio->set_write_callback_enable(false); waiter->wake(); return 0; } if (count < data.size()) { // We couldn't write all the data, so the write side is in // flow control. Enable the write callback so we know // when we can write again. io->set_read_callback_enable(false); otherio->set_write_callback_enable(true); } return count; } void write_ready() override { // We were flow controlled on write and we can write again. // Kick back off the reads. otherio->set_read_callback_enable(true); io->set_write_callback_enable(false); } int err = 0; Gensio *io = NULL; Gensio *otherio = NULL; Waiter *waiter; }; // Internal gensio errors come in through this mechanism. class Telnet_Logger: public Os_Funcs_Log_Handler { void log(enum gensio_log_levels level, const std::string log) override { std::cerr << "gensio " << gensio_log_level_to_str(level) << " log: " << log << std::endl; } }; int main(int argc, char *argv[]) { try { // Note that Telnet_Logger must be dynamically allocated. // Os_Funcs will delete it when the Os_Funcs is destroyed. Os_Funcs o(0, new Telnet_Logger); std::string constr(argv[1]); Waiter waiter(o); o.proc_setup(); Client_Event telnet_evh(&waiter); Client_Event user_evh(&waiter); GensioW tgensio("telnet," + constr, o, &telnet_evh); GensioW ugensio("stdio(self)", o, &user_evh); telnet_evh.set_gensios(&tgensio, &ugensio); user_evh.set_gensios(&ugensio, &tgensio); ugensio->open_s(); tgensio->open_s(); tgensio->set_read_callback_enable(true); ugensio->set_read_callback_enable(true); waiter.wait(1); int terr = telnet_evh.get_err(); int uerr = user_evh.get_err(); if (terr && terr != GE_REMCLOSE) { std::cerr << "Error from telnet connection: " << err_to_string(terr) << std::endl; } if (uerr && uerr != GE_REMCLOSE) { std::cerr << "Error from stdio: " << err_to_string(uerr) << std::endl; } // It's better to close these before they are destroyed, but // the close must complete before the destruction. tgensio->close_s(); ugensio->close_s(); // Destruction happens in reverse order, so the gensios are // freed, then the user events, the waiter, and the OS funcs. } catch (gensio_error &e) { std::cerr << "gensio error: " << e.what() << std::endl; return 1; } return 0; } gensio-3.0.0/c++/examples/telnet_server.cc0000664000175000017500000001751414666663072014067 // // Copyright 2021 Corey Minyard // // SPDX-License-Identifier: Apache-2.0 // This is a basic telnet server, it accepts one connection and echos // back everything it receives. It takes an accepter string as an // argument. #include #include #include #include using namespace std; using namespace gensios; // This is a Gensio event handler for the server. It's job is to echo // received characters. class Server_Event: public Event { public: // Allocate an event handler for a gensio. When the gensio // closes, wake the waiter. Server_Event(Waiter *w, string *errstr) : waiter(w), errstr(errstr) {} // Due to initialation order, we have to create this object and // pass it to the constructor of the gensio, but we need the // gensio, too. So we have to set this after the gensio is // created. void set_gensio(Gensio *g) { io = g; } private: // Handle errors, and if no error write the read data back into // the gensio for echoing. Note that read calls are guaranteed by // gensio to be single-threaded, so a lock is not required here // because it doesn't interact with anything else. gensiods read(int err, const SimpleUCharVector data, const char *const *auxdata) override { gensiods count; if (err) { if (err != GE_REMCLOSE) *errstr = gensio_err_to_str(err); io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->free(); return 0; } try { count = io->write(data, NULL); } catch (gensio_error &e) { *errstr = e.what(); io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->free(); return 0; } if (count < data.size()) { // We couldn't write all the data, so the write side is in // flow control. Enable the write callback so we know // when we can write again. io->set_read_callback_enable(false); io->set_write_callback_enable(true); } return count; } // Like read(), write_ready() is guaranteed to be single-threaded // against other write_ready() calls on the same gensio (but not // against the read() callback). void write_ready() override { // We were flow controlled on write and we can write again. // Kick back off the reads. io->set_read_callback_enable(true); io->set_write_callback_enable(false); } // Called when the free is complete. We wake up whatever is // waiting on us. void freed() override { waiter->wake(); delete this; } Gensio *io = NULL; Waiter *waiter; string *errstr; }; // Handle accept events from the accepter stack. Basically, just kick // off the handling on the new gensio, using the event handler passed // in to the constructor. class Acc_Event: public Accepter_Event { public: Acc_Event(Waiter *w, string *errstr) : waiter(w), errstr(errstr) { } // Like Server_Event, initialization order forces us to set the // accepter separately. void set_accepter(Accepter *iacc) { acc = iacc; } private: Accepter *acc = NULL; // If errors occur in the accepter stack, they generally can't be // reported through normal mechanisms. So those types of errors // come in through this mechanism. void log(enum gensio_log_levels level, const std::string log) override { std::cerr << "accepter " << gensio_log_level_to_str(level) << " log: " << log << std::endl; } // New connection, kick off the new connection's echo handling. void new_connection(Gensio *g) override { if (connected) { // We got a second connection, this can happen due to a // race. Just shut it down. g->free(); return; } connected = true; Server_Event *ev = new Server_Event(waiter, errstr); g->set_event_handler(ev); ev->set_gensio(g); g->set_read_callback_enable(true); g->set_write_callback_enable(true); // Don't accept any more connections, but inform that we are done. acc->shutdown(); waiter->wake(); } bool connected = false; Waiter *waiter; string *errstr; }; // We demo three different ways to allocate an accepter. The first is // a hand-created stack, which demos how we can hand create and stack // gensios or accepters on top of existing gensios/accepters. This is // not so useful here, but is if you accept a gensio then need to put // another one on top of it. // // The second is the normal way to allocate an accepter with a string. // // The last is using RAII, which is the right way to do it in this // case. //#define HAND_CREATE_STACK //#define NORMAL_ALLOCATION #define USE_RAII // The basic server handling. Allocate the gensio stack, tcp and // telnet, and kick off processing. Wait until the accepter and new // gensio are freed. static int do_server(Os_Funcs &o, const Addr &addr) { Waiter w(o); string errstr; Acc_Event ae(&w, &errstr); #ifdef HAND_CREATE_STACK Accepter *atcp, *atelnet; // An example of hand-creating a stack instead of using the normal // allocation method. atcp = gensio_acc_alloc("tcp", (void *) ((struct gensio_addr *) addr), NULL, o, NULL); atelnet = gensio_acc_alloc("telnet", atcp, NULL, o, &ae); ae.set_accepter(atelnet); #endif #ifdef NORMAL_ALLOCATION Accepter *atelnet; // Allocate it more normally. atelnet = gensio_acc_alloc("telnet,tcp," + addr.to_string(), o, &ae); ae.set_accepter(atelnet); #endif #ifdef USE_RAII AccepterW atelnet("telnet,tcp," + addr.to_string(), o, &ae); ae.set_accepter(&atelnet); #endif try { atelnet->startup(); } catch (gensio_error &e) { cerr << "Error opening: " << e.what() << endl; return 1; } cout << "Port is: " << atelnet->get_port() << endl; atelnet->set_callback_enable(true); w.wait(2, NULL); #if defined(NORMAL_ALLOCATION) || defined(HAND_CREATE_STACK) // No need with RAII, it handles the deallocation automatically. atelnet->free(); #endif if (errstr.length() > 0) { cerr << "Server error: " << errstr << endl; } return 0; } // Internal gensio errors come in through this mechanism. class Telnet_Logger: public Os_Funcs_Log_Handler { void log(enum gensio_log_levels level, const std::string log) override { std::cerr << "gensio " << gensio_log_level_to_str(level) << " log: " << log << std::endl; } }; // This is a demo of an extra thread we start, using the RAII principle. class Telnet_Thread: public Os_Funcs_Thread_Func { public: Telnet_Thread(Os_Funcs &o) : w(o), o(o) { tid = o.new_thread(this); } ~Telnet_Thread() { w.wake(); try { o.wait_thread(tid); } catch (gensio_error &e) { cerr << "Error waiting for thread: " << e.what() << endl; } } void start() { w.wait(1, NULL); } private: Os_Funcs o; struct gensio_thread *tid; Waiter w; }; int main(int argc, char *argv[]) { int err = 1; if (argc < 2) { cerr << "Takes a single gensio accepter as an argument" << endl; return 1; } try { // -1 (or a specific signal) is required for threads. It chooses // the default wake signal. Os_Funcs o(-1, new Telnet_Logger); o.proc_setup(); // Add a thread for handling capacity. Telnet_Thread thread1(o); // Wrap this so we can print a nicer error if the address // conversion fails. Addr addr; try { Addr taddr(o, argv[1], true, NULL, NULL, NULL); addr = taddr; } catch (gensio_error &e) { cerr << "Invalid gensio address: " << e.what() << endl; return 1; } err = do_server(o, addr); // This is not necessary, but can be used to make sure everything // got freed properly. refcount on the os handler should be 3, // one for the thread, one for the Addr, and one for the Os_Funcs. if (o.get_refcount() != 3) { cerr << "Invalid refcount: " << o.get_refcount() << endl; return 1; } } catch (gensio_error &e) { cerr << "gensio error: " << e.what() << endl; } return !!err; } gensio-3.0.0/c++/examples/Makefile.am0000664000175000017500000000135614664224267012725 AM_CPPFLAGS = -I$(top_srcdir)/c++/include noinst_PROGRAMS = telnet_server telnet_client mdns telnet_server_SOURCES = telnet_server.cc telnet_server_LDADD = $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/lib/libgensio.la telnet_client_SOURCES = telnet_client.cc telnet_client_LDADD = $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/lib/libgensio.la mdns_SOURCES = mdns.cc mdns_LDADD = $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/c++/lib/libgensiomdnscpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la gensio-3.0.0/c++/tests/0000775000175000017500000000000015061121734010253 5gensio-3.0.0/c++/tests/Makefile.in0000664000175000017500000011226415061121657012252 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ TESTS = basic_cpp_test$(EXEEXT) serial_test$(EXEEXT) check_PROGRAMS = basic_cpp_test$(EXEEXT) serial_test$(EXEEXT) subdir = c++/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am_basic_cpp_test_OBJECTS = basic_cpp_test.$(OBJEXT) basic_cpp_test_OBJECTS = $(am_basic_cpp_test_OBJECTS) am__DEPENDENCIES_1 = basic_cpp_test_DEPENDENCIES = \ $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am_serial_test_OBJECTS = serial_test.$(OBJEXT) serial_test_OBJECTS = $(am_serial_test_OBJECTS) serial_test_DEPENDENCIES = $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/basic_cpp_test.Po \ ./$(DEPDIR)/serial_test.Po am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(basic_cpp_test_SOURCES) $(serial_test_SOURCES) DIST_SOURCES = $(basic_cpp_test_SOURCES) $(serial_test_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_srcdir)/c++/include basic_cpp_test_SOURCES = basic_cpp_test.cc basic_cpp_test_LDADD = $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(OPENSSL_LIBS) serial_test_SOURCES = serial_test.cc serial_test_LDADD = $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(OPENSSL_LIBS) all: all-am .SUFFIXES: .SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/tests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list basic_cpp_test$(EXEEXT): $(basic_cpp_test_OBJECTS) $(basic_cpp_test_DEPENDENCIES) $(EXTRA_basic_cpp_test_DEPENDENCIES) @rm -f basic_cpp_test$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(basic_cpp_test_OBJECTS) $(basic_cpp_test_LDADD) $(LIBS) serial_test$(EXEEXT): $(serial_test_OBJECTS) $(serial_test_DEPENDENCIES) $(EXTRA_serial_test_DEPENDENCIES) @rm -f serial_test$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(serial_test_OBJECTS) $(serial_test_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basic_cpp_test.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serial_test.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: $(check_PROGRAMS) @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? basic_cpp_test.log: basic_cpp_test$(EXEEXT) @p='basic_cpp_test$(EXEEXT)'; \ b='basic_cpp_test'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) serial_test.log: serial_test$(EXEEXT) @p='serial_test$(EXEEXT)'; \ b='serial_test'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/basic_cpp_test.Po -rm -f ./$(DEPDIR)/serial_test.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/basic_cpp_test.Po -rm -f ./$(DEPDIR)/serial_test.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/c++/tests/serial_test.cc0000664000175000017500000000565315045153771013041 // // Copyright 2021 Corey Minyard // // SPDX-License-Identifier: GPL-2.0-only // Some systems want C includes first. #ifndef _WIN32 #include #include #include #include #include #endif #include #include #include using namespace std; using namespace gensios; #include // Internal gensio errors come in through this mechanism. class Logger: public Os_Funcs_Log_Handler { void log(enum gensio_log_levels level, const std::string log) override { std::cerr << "gensio " << gensio_log_level_to_str(level) << " log: " << log << std::endl; } }; #define ECHO_DEV_ENV "GENSIO_TEST_ECHO_DEV" #define DEFAULT_ECHO_COMMPORT "/dev/ttyEcho0" static int get_echo_dev(Os_Funcs &o, char *echo_dev, gensiods len) { int rv; rv = gensio_os_env_get(ECHO_DEV_ENV, echo_dev, &len); #ifdef _WIN32 if (rv) return rv; #else if (rv == GE_NOTFOUND) { if (len < strlen(DEFAULT_ECHO_COMMPORT) + 1) return GE_TOOBIG; strncpy(echo_dev, DEFAULT_ECHO_COMMPORT, len); } else if (rv) { return rv; } struct stat sb; rv = stat(echo_dev, &sb); if (rv == -1) return gensio_os_err_to_err(o, errno); if (!S_ISCHR(sb.st_mode)) return GE_INVAL; rv = open(echo_dev, O_RDWR); if (rv < 0) return gensio_os_err_to_err(o, errno); close(rv); #endif return 0; } int main(int argc, char *argv[]) { Os_Funcs o(0, new Logger); char echo_dev[100]; int err; err = get_echo_dev(o, echo_dev, sizeof(echo_dev)); if (err) { printf("Unable to get echo dev, test skipped: %s\n", gensio_err_to_str(err)); return 77; } std::string devstr(echo_dev); devstr.append(",9600n81"); Waiter w(o); static const char *serial_parms[] = { "nouucplock=false", NULL }; Gensio *bg = gensio_alloc("serialdev", devstr.c_str(), serial_parms, o, NULL); GensioW g(bg); // Take over lifetime of the gensio char data[100]; gensiods datalen; int rv; o.proc_setup(); err = 0; g->open_s(); cout << "Allocated" << endl; cout << "Validating baud is 9600" << endl; strcpy(data, "0"); datalen = sizeof(data); rv = g->acontrol_s(0, GENSIO_CONTROL_GET, GENSIO_ACONTROL_SER_BAUD, data, &datalen); if (rv) { err = 1; cout << "*** Error getting baud" << endl; } if (strcmp(data, "9600") != 0) { err = 1; cout << "*** Baud was not 9600" << endl; } cout << "Setting baud to 19200" << endl; strcpy(data, "19200"); datalen = sizeof(data); rv = g->acontrol_s(0, GENSIO_CONTROL_SET, GENSIO_ACONTROL_SER_BAUD, data, &datalen); if (rv) { err = 1; cout << "*** Error getting baud" << endl; } else { cout << "baud set to 19200" << endl; } if (strcmp(data, "19200") != 0) { err = 1; cout << "*** Baud was not set to 19200" << endl; } cout << "Closing" << endl; return 0; } gensio-3.0.0/c++/tests/basic_cpp_test.cc0000664000175000017500000002313714664224267013507 // // Copyright 2021 Corey Minyard // // SPDX-License-Identifier: GPL-2.0-only #include #include #include #include using namespace std; using namespace gensios; class Open_Done: public Gensio_Open_Done { public: Open_Done(Waiter *w) { waiter = w; } const char *get_err() { return errstr; } private: const char *errstr = NULL; void open_done(int err) override { if (err) errstr = gensio_err_to_str(err); waiter->wake(); } Waiter *waiter; }; class Close_Done: public Gensio_Close_Done { public: Close_Done(Waiter *w): waiter(w) { } void set_gensio(Gensio *g) { io = g; } private: void close_done() override { io->free(); } Gensio *io = NULL; Waiter *waiter; }; class Client_Event: public Event { public: Client_Event(Waiter *w, const unsigned char *data, gensiods datalen, Close_Done *ce) { waiter = w; this->data = data; this->datalen = datalen; this->ce = ce; } void set_gensio(Gensio *g) { io = g; } const char *get_err() { return errstr; } private: Gensio *io = NULL; gensiods read(int err, SimpleUCharVector idata, const char *const *auxdata) override { if (err) { errstr = gensio_err_to_str(err); io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->close(ce); return 0; } string str((char *) idata.data(), idata.size()); if (readpos + idata.size() > datalen) { errstr = "Too much data"; io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->close(ce); return idata.size(); } if (memcmp(data + readpos, idata.data(), idata.size()) != 0) { errstr = "Data mismatch"; io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->close(ce); return idata.size(); } readpos += idata.size(); if (readpos == datalen) { io->set_read_callback_enable(false); io->close(ce); } return idata.size(); } void write_ready() override { gensiods count; try { count = io->write(data + writepos, datalen - writepos, NULL); } catch (gensio_error &e) { errstr = e.what(); io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->close(ce); return; } writepos += count; if (writepos == datalen) io->set_write_callback_enable(false); } void freed() override { waiter->wake(); } const char *errstr = NULL; const unsigned char *data; gensiods datalen; gensiods readpos = 0; gensiods writepos = 0; Close_Done *ce; Waiter *waiter; }; static int do_client_test(Os_Funcs &o, string ios) { Waiter w(o); Gensio *g; string s("This is a test!\r\n"); Open_Done oe(&w); Close_Done ce(&w); Client_Event e(&w, (unsigned char *) s.c_str(), (gensiods) s.size(), &ce); const char *errstr; gensio_time waittime = { 2, 0 }; int err; g = gensio_alloc(ios, o, &e); e.set_gensio(g); try { g->open(&oe); } catch (gensio_error &e) { cerr << "Error opening '" << ios << "': " << e.what() << endl; return 1; } ce.set_gensio(g); err = w.wait(1, &waittime); if (err) { g->free(); cerr << "Error from open wait for '" << ios << "': " << gensio_err_to_str(err) << endl; return 1; } errstr = oe.get_err(); if (errstr) { g->free(); cerr << "Error from open for '" << ios << "': " << errstr << endl; return 1; } g->set_read_callback_enable(true); g->set_write_callback_enable(true); waittime = { 2, 0 }; err = w.wait(1, &waittime); if (err) { cerr << "Error from wait for '" << ios << "': " << gensio_err_to_str(err) << endl; return 1; } errstr = e.get_err(); if (errstr) { cerr << "Error handler '" << ios << "': " << errstr << endl; return 1; } return 0; } class Server_Event: public Event { public: Server_Event(Waiter *w, Gensio *g): waiter(w), io(g) { } const char *get_err() { return errstr; } void set_gensio(Gensio *g) { io = g; } private: gensiods read(int err, const SimpleUCharVector data, const char *const *auxdata) override { gensiods count; if (err) { if (err != GE_REMCLOSE) errstr = gensio_err_to_str(err); io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->free(); return 0; } try { count = io->write(data, NULL); } catch (gensio_error &e) { errstr = e.what(); io->set_read_callback_enable(false); io->set_write_callback_enable(false); io->free(); return data.size(); } if (count < data.size()) { io->set_read_callback_enable(false); io->set_write_callback_enable(true); } return data.size(); } void write_ready() override { io->set_read_callback_enable(true); io->set_write_callback_enable(false); } void freed() override { if (errstr) { cerr << "Server error: " << errstr << endl; } waiter->wake(); } const char *errstr = NULL; Waiter *waiter; Gensio *io; }; class Acc_Event: public Accepter_Event { public: Acc_Event(Waiter *w) { waiter = w; } void set_accepter(Accepter *iacc) { acc = iacc; } private: Accepter *acc = NULL; void log(enum gensio_log_levels level, const std::string log) override { std::cerr << "accepter " << gensio_log_level_to_str(level) << " log: " << log << std::endl; } void new_connection(Gensio *g) override { Server_Event *ev = new Server_Event(waiter, g); g->set_event_handler(ev); g->set_read_callback_enable(true); g->set_write_callback_enable(true); acc->free(); } void freed() override { waiter->wake(); } Waiter *waiter; }; static void do_server_test(Os_Funcs &o, string ios) { Waiter w(o); Accepter *a; Acc_Event ae(&w); cerr << "Opening " << ios << endl; a = gensio_acc_alloc(ios, o, &ae); ae.set_accepter(a); try { a->startup(); } catch (gensio_error &e) { cerr << "Error opening '" << ios << "': " << e.what() << endl; return; } cout << a->get_port() << endl << flush; a->set_callback_enable(true); w.wait(2, NULL); } // Internal gensio errors come in through this mechanism. class Logger: public Os_Funcs_Log_Handler { void log(enum gensio_log_levels level, const std::string log) override { std::cerr << "gensio " << gensio_log_level_to_str(level) << " log: " << log << std::endl; } }; class Sub_Event: public Event { public: Sub_Event(Waiter *w) { waiter = w; } const char *get_err() { return errstr; } void set_gensio(Gensio *g) { io = g; } string get_port() { return string(port, portpos); } private: Gensio *io = NULL; gensiods read(int err, const SimpleUCharVector data, const char *const *auxdata) override { gensiods i; if (portfound) { io->set_read_callback_enable(false); return 0; } if (err) { io->set_read_callback_enable(false); waiter->wake(); errstr = "subprogram failed before reading port"; return 0; } for (i = 0; i < data.size(); i++) { if (portpos >= sizeof(port)) { errstr = "Port from sub too large"; waiter->wake(); io->set_read_callback_enable(false); return i; } if (data[i] == '\n' || data[i] == '\r') { port[portpos] = '\0'; portfound = true; waiter->wake(); io->set_read_callback_enable(false); return i; } port[portpos++] = data[i]; } return i; } void write_ready() override { io->set_write_callback_enable(false); } void freed() override { waiter->wake(); } char port[100] = ""; gensiods portpos = 0; bool portfound = false; const char *errstr = NULL; Waiter *waiter; }; int main(int argc, char *argv[]) { int err = 0; Os_Funcs o(0, new Logger); const char *test = "mux,tcp,localhost,"; const char *errstr; o.proc_setup(); if (argc > 1) { do_server_test(o, argv[1]); } else { char *s; string ios("stdio(noredir-stderr),"); string ioc(test); Gensio *sub; Waiter w(o); Sub_Event se(&w); gensio_time waittime = { 2, 0 }; int err2; char buf[10]; gensiods len = sizeof(buf); cout << "Starting subprogram to act as a server" << endl; s = gensio_quote_string(o, argv[0]); if (!s) { cerr << "Out of memory duplicating argv[0]" << endl; err = 1; goto out; } ios += s; gensio_os_funcs_zfree(o, s); ios += " "; ios += test; ios += "0"; try { sub = gensio_alloc(ios, o, &se); } catch (gensio_error &e) { cerr << "Unable to open " << ios << ": " << e.what() << endl; err = 1; goto out; } se.set_gensio(sub); sub->open_s(); sub->set_read_callback_enable(true); err = w.wait(1, &waittime); if (err) { cerr << "Error from sub wait for '" << ios << "': " << gensio_err_to_str(err) << endl; err = 1; } else { errstr = se.get_err(); if (errstr) { cerr << "Unable to handle sub " << ios << ": " << errstr << endl; err = 1; } else { ioc += se.get_port(); cout << "Connecting to " << ioc << endl; err = do_client_test(o, ioc); } } cout << "Closing sub program" << endl; sub->close_s(); err2 = sub->control(0, true, GENSIO_CONTROL_EXIT_CODE, buf, &len); if (err2) { cerr << "Error getting exit code: " << gensio_err_to_str(err2) << endl; err = 1; } err2 = strtoul(buf, NULL, 0); if (err2) { cerr << "Error from subprogram: " << err2 << endl; err = 1; } sub->free(); waittime = { 2, 0 }; err2 = w.wait(1, &waittime); if (err2) { cerr << "Error from sub wait for '" << ios << "': " << gensio_err_to_str(err2) << endl; err = 1; } } out: if (!err) cout << "Success!" << endl; return err; } gensio-3.0.0/c++/tests/Makefile.am0000664000175000017500000000114314664224267012243 AM_CPPFLAGS = -I$(top_srcdir)/c++/include TESTS = basic_cpp_test serial_test basic_cpp_test_SOURCES = basic_cpp_test.cc basic_cpp_test_LDADD = $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(OPENSSL_LIBS) serial_test_SOURCES = serial_test.cc serial_test_LDADD = $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensioosh.la \ $(OPENSSL_LIBS) check_PROGRAMS = basic_cpp_test serial_test gensio-3.0.0/c++/swig/0000775000175000017500000000000015061121734010062 5gensio-3.0.0/c++/swig/go/0000775000175000017500000000000015061121734010467 5gensio-3.0.0/c++/swig/go/Makefile.in0000664000175000017500000005547615061121657012501 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = c++/swig/go ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = gensio examples tests # A helper to transfer info to where it needs to go and rename everything # properly. GOLANG_INSTALLDIR = /personal/git/go/gensio all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/swig/go/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/swig/go/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile golang-install: cp $(srcdir)/README.rst $(GOLANG_INSTALLDIR) cp $(srcdir)/gensio/gensio.srcswigcxx \ $(GOLANG_INSTALLDIR)/gensio.swigcxx cp $(srcdir)/gensio/gensioapi.srcgo $(GOLANG_INSTALLDIR)/gensioapi.go cp $(srcdir)/gensio/go.srcmod $(GOLANG_INSTALLDIR)/go.mod cp $(srcdir)/../include/gensio_base.i $(GOLANG_INSTALLDIR) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/c++/swig/go/examples/0000775000175000017500000000000015061121734012305 5gensio-3.0.0/c++/swig/go/examples/srcexample.go0000664000175000017500000001022015045153771014722 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only package main import ( "fmt" "runtime" "github.com/cminyard/go/gensio" ) type AccGEvHnd struct { gensio.EventBase g gensio.Gensio } func (e *AccGEvHnd) Read(err int, data []byte, auxdata []string) uint64 { fmt.Printf("acc read: %s\n", string(data)) fmt.Printf("aux: %v\n", auxdata) e.g.Write(data, nil) return uint64(len(data)) } func (e *AccGEvHnd) WriteReady() { fmt.Println("acc write ready") e.g.SetWriteCallbackEnable(false) } type AccEvHnd struct { gensio.AccepterEventBase } func (ae *AccEvHnd) NewConnection(g gensio.Gensio) { fmt.Println("Acc New connection") gev := &AccGEvHnd{} gev.g = g g.SetEvent(gev) g.SetReadCallbackEnable(true) } type EvHnd struct { gensio.EventBase g gensio.Gensio writedata []byte readdata []byte w *gensio.Waiter } func (e *EvHnd) IsEvHndGo() { } func (e *EvHnd) destroy() { //gensio.DeleteWaiter(e.w) //gensio.DeleteDirectorEvent(e.Event) } func (e *EvHnd) Read(err int, data []byte, auxdata []string) uint64 { e.g.SetReadCallbackEnable(false) e.readdata = data fmt.Printf("read: %s\n", string(data)) fmt.Printf("aux: %v\n", auxdata) e.w.Wake() return uint64(len(data)) } func (e *EvHnd) WriteReady() { fmt.Println("write ready") e.g.SetWriteCallbackEnable(false) e.g.Write(e.writedata, nil) e.g.SetReadCallbackEnable(true) } func (e *EvHnd) Freed() { fmt.Println("freed two") } func (e *EvHnd) wait(count uint, timeout *gensio.Time) { e.w.Wait(count, timeout) } func (e *EvHnd) set_write_data(data []byte) { e.writedata = data } func NewEvHnd(o *gensio.OsFuncs) *EvHnd { e := &EvHnd{} e.w = gensio.NewWaiter(o) return e } type EvHndDelI interface { destroy() } type asdf struct{ x int64 } func (e *asdf) destroy() { fmt.Println("asdf destroy") } func check() int64 { a := &asdf{10} return a.x } type Open_Done struct { gensio.GensioOpenDoneBase w *gensio.Waiter err int } func NewOpen_Done(o *gensio.OsFuncs) *Open_Done { od := &Open_Done{} od.w = gensio.NewWaiter(o) od.err = gensio.GE_TIMEDOUT return od } func (od *Open_Done) wait(count uint, timeout *gensio.Time) { od.w.Wait(count, timeout) } func (od *Open_Done) OpenDone(err int) { od.err = err od.w.Wake() } type LogHandler struct { gensio.LoggerBase } func (l *LogHandler) Log(level int, log string) { fmt.Printf("LOG(%s): %s\n", gensio.LogLevelToStr(level), log) } func main() { o := gensio.NewOsFuncs(&LogHandler{}) gensio.SetLogMask(gensio.LOG_MASK_ALL) o.Log(gensio.LOG_INFO, "Test Log") acch := &AccEvHnd{} acc := gensio.NewAccepter("tcp,localhost,0", o, acch) acc.Startup() port := acc.GetPort() fmt.Printf("Accepter port: %s\n", port) e := NewEvHnd(o) g := gensio.NewGensio("tcp,localhost," + port, o, e) e.g = g e.set_write_data([]byte("Test1")) od := NewOpen_Done(o) g.Open(od) od.wait(1, gensio.NewTime(1, 0)) if od.err != 0 { fmt.Printf("Error opening gensio: %d\n", od.err) return } od = nil var rv int var newdata []byte data := make([]byte, 0, 100) data = append(data, "0"...) rv, newdata, _ = g.Control(0, true, gensio.GENSIO_CONTROL_LADDR, data) fmt.Printf("laddr(%d): %s\n", rv, newdata) rv, newdata, _ = g.Control(0, true, gensio.GENSIO_CONTROL_RADDR, data) fmt.Printf("raddr(%d): %s\n", rv, newdata) fmt.Println("Testing sync I/O") g.SetSync() count := uint64(0) rv, count = g.WriteS([]byte("Sync I/O"), nil, false) fmt.Printf("Sync Write(%d): %d\n", rv, count) rv, newdata = g.ReadS(data, gensio.NewTime(1, 0), false) fmt.Printf("Sync Read(%d): %s\n", rv, newdata) g.ClearSync() g.SetWriteCallbackEnable(true) t := gensio.NewTime(check(), 0) e.wait(1, t) fmt.Printf("Done (%d %d): %s\n", t.GetSecs(), t.GetNsecs(), string(e.readdata)) g.CloseS() e.g = nil // Break the circular link e = nil g = nil t = nil acch = nil acc.ShutdownS() acc = nil e = NewEvHnd(o) g = gensio.NewGensio("serialdev,/dev/ttyEcho0,115200n81", o, e) g = nil runtime.GC() w := gensio.NewWaiter(o) w.Wait(uint(1), gensio.NewTime(1, 0)) runtime.GC() w.Wait(uint(1), gensio.NewTime(1, 0)) runtime.GC() w.Wait(uint(1), gensio.NewTime(1, 0)) } gensio-3.0.0/c++/swig/go/examples/Makefile.in0000664000175000017500000004400015061121657014274 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @BUILTIN_MDNS_TRUE@am__append_1 = $(MDNS_LIBS) @BUILTIN_SOUND_TRUE@am__append_2 = $(SOUND_LIBS) @BUILTIN_SCTP_TRUE@am__append_3 = $(LIBSCTP_LIBS) @BUILTIN_SSL_TRUE@am__append_4 = $(OPENSSL_LIBS) @BUILTIN_IPMISOL_TRUE@am__append_5 = $(OPENIPMI_LIBS) subdir = c++/swig/go/examples ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SCRIPTS = $(noinst_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_SCRIPTS = example telnet_server telnet_client GOMOD = github.com/cminyard/go/gensio MORE_LIBS = $(am__append_1) $(am__append_2) $(am__append_3) \ $(am__append_4) $(am__append_5) EXTRA_DIST = srcexample.go srctelnet_server.go srctelnet_client.go all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/swig/go/examples/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/swig/go/examples/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(SCRIPTS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile example.go: $(srcdir)/srcexample.go cp $(srcdir)/srcexample.go example.go telnet_server.go: $(srcdir)/srctelnet_server.go cp $(srcdir)/srctelnet_server.go telnet_server.go telnet_client.go: $(srcdir)/srctelnet_client.go cp $(srcdir)/srctelnet_client.go telnet_client.go go.mod: example.go rm -f go.mod go mod init examples go mod edit -replace $(GOMOD)=../gensio go mod tidy export CXX export CC export CGO_CXXFLAGS = $(CXXFLAGS) $(AM_CXXFLAGS) \ -I$(top_srcdir)/c++/swig/include export CGO_CPPFLAGS = $(CPPFLAGS) -I$(top_srcdir)/c++/swig/include export CGO_LDFLAGS = -L$(top_builddir)/c++/lib/.libs \ -lgensiooshcpp -lgensiocpp -lgensiomdnscpp \ -L$(top_builddir)/lib/.libs -lgensioosh -lgensio -lgensiomdns \ $(MORE_LIBS) example: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx ../gensio/gensio_wrap.h \ example.go ../gensio/gensioapi.go go.mod go build example.go telnet_server: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx ../gensio/gensio_wrap.h \ telnet_server.go ../gensio/gensioapi.go go.mod go build telnet_server.go telnet_client: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx ../gensio/gensio_wrap.h \ telnet_client.go ../gensio/gensioapi.go go.mod go build telnet_client.go clean-local: rm -rf go.mod example example.go telnet_server telnet_server.go \ telnet_client telnet_client.go # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/c++/swig/go/examples/srctelnet_server.go0000664000175000017500000000462414666633411016165 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only // This is an example telnet server in Go package main import ( "fmt" "github.com/cminyard/go/gensio" ) type closeDone struct { gensio.GensioCloseDoneBase g gensio.Gensio w *gensio.Waiter se *serverEvent } func (cd *closeDone) CloseDone() { cd.w.Wake() cd.g = nil cd.w = nil cd.se.g = nil cd.se = nil } type serverEvent struct { gensio.EventBase g gensio.Gensio w *gensio.Waiter errstr *string } func (se *serverEvent) startClose() { se.g.SetReadCallbackEnable(false) se.g.SetWriteCallbackEnable(false) cdh := &closeDone{} cdh.g = se.g cdh.w = se.w cdh.se = se se.g.Close(cdh) } func (se *serverEvent) Read(err int, data []byte, auxdata []string) uint64 { if err != 0 { *se.errstr = gensio.ErrToStr(err) se.startClose() return 0 } defer func() { if r := recover(); r != nil { *se.errstr = fmt.Sprintf("%s", r) se.startClose() } }() count := se.g.Write(data, nil) if count < uint64(len(data)) { se.g.SetReadCallbackEnable(false) se.g.SetWriteCallbackEnable(true) } return count } func (se *serverEvent) WriteReady() { se.g.SetReadCallbackEnable(true) se.g.SetWriteCallbackEnable(false) } type accepterShutdownDone struct { gensio.AccepterShutdownDoneBase w *gensio.Waiter ae *accepterEvent } func (asd *accepterShutdownDone) AccShutdownDone() { asd.ae.acc = nil asd.ae = nil asd.w.Wake() } type accepterEvent struct { gensio.AccepterEventBase acc gensio.Accepter w *gensio.Waiter errstr *string } func (ae *accepterEvent) Log(level int, log string) { fmt.Printf("LOG(%s): %s\n", gensio.LogLevelToStr(level), log) } func (ae *accepterEvent) NewConnection(g gensio.Gensio) { se := &serverEvent{} se.g = g se.w = ae.w se.errstr = ae.errstr g.SetEvent(se) g.SetReadCallbackEnable(true) asd := &accepterShutdownDone{} asd.w = ae.w asd.ae = ae ae.acc.Shutdown(asd) } type LogHandler struct { gensio.LoggerBase } func (l *LogHandler) Log(level int, log string) { fmt.Printf("LOG(%s): %s\n", gensio.LogLevelToStr(level), log) } func main() { o := gensio.NewOsFuncs(&LogHandler{}) w := gensio.NewWaiter(o) errstr := "" ae := &accepterEvent{} ae.w = w ae.errstr = &errstr ae.acc = gensio.NewAccepter("telnet,tcp,1234", o, ae) ae.acc.Startup() w.Wait(2, nil) fmt.Println("Shut down due to:", errstr); } gensio-3.0.0/c++/swig/go/examples/Makefile.am0000664000175000017500000000334714664224267014305 noinst_SCRIPTS = example telnet_server telnet_client GOMOD = github.com/cminyard/go/gensio example.go: $(srcdir)/srcexample.go cp $(srcdir)/srcexample.go example.go telnet_server.go: $(srcdir)/srctelnet_server.go cp $(srcdir)/srctelnet_server.go telnet_server.go telnet_client.go: $(srcdir)/srctelnet_client.go cp $(srcdir)/srctelnet_client.go telnet_client.go go.mod: example.go rm -f go.mod go mod init examples go mod edit -replace $(GOMOD)=../gensio go mod tidy MORE_LIBS= if BUILTIN_MDNS MORE_LIBS += $(MDNS_LIBS) endif if BUILTIN_SOUND MORE_LIBS += $(SOUND_LIBS) endif if BUILTIN_SCTP MORE_LIBS += $(LIBSCTP_LIBS) endif if BUILTIN_SSL MORE_LIBS += $(OPENSSL_LIBS) endif if BUILTIN_IPMISOL MORE_LIBS += $(OPENIPMI_LIBS) endif export CXX export CC export CGO_CXXFLAGS = $(CXXFLAGS) $(AM_CXXFLAGS) \ -I$(top_srcdir)/c++/swig/include export CGO_CPPFLAGS = $(CPPFLAGS) -I$(top_srcdir)/c++/swig/include export CGO_LDFLAGS = -L$(top_builddir)/c++/lib/.libs \ -lgensiooshcpp -lgensiocpp -lgensiomdnscpp \ -L$(top_builddir)/lib/.libs -lgensioosh -lgensio -lgensiomdns \ $(MORE_LIBS) example: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx ../gensio/gensio_wrap.h \ example.go ../gensio/gensioapi.go go.mod go build example.go telnet_server: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx ../gensio/gensio_wrap.h \ telnet_server.go ../gensio/gensioapi.go go.mod go build telnet_server.go telnet_client: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx ../gensio/gensio_wrap.h \ telnet_client.go ../gensio/gensioapi.go go.mod go build telnet_client.go EXTRA_DIST = srcexample.go srctelnet_server.go srctelnet_client.go clean-local: rm -rf go.mod example example.go telnet_server telnet_server.go \ telnet_client telnet_client.go gensio-3.0.0/c++/swig/go/examples/srctelnet_client.go0000664000175000017500000000450014664224267016131 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only // This is an example telnet client in Go. It reads line-at-a time. package main import ( "fmt" "github.com/cminyard/go/gensio" ) type closeDone struct { gensio.GensioCloseDoneBase ie *ioEvent } func (cd *closeDone) CloseDone() { cd.ie.info.w.Wake() cd.ie.g = nil cd.ie.otherie.g = nil cd.ie.otherie = nil cd.ie = nil } type ioInfo struct { w *gensio.Waiter errstr string inClose bool } type ioEvent struct { gensio.EventBase g gensio.Gensio otherie *ioEvent info *ioInfo } func (ie *ioEvent) startClose() { if ie.info.inClose { return } ie.info.inClose = true ie.g.SetReadCallbackEnable(false) ie.g.SetWriteCallbackEnable(false) ie.otherie.g.SetReadCallbackEnable(false) ie.otherie.g.SetWriteCallbackEnable(false) cdh := &closeDone{} cdh.ie = ie ie.g.Close(cdh) cdh = &closeDone{} cdh.ie = ie.otherie ie.otherie.g.Close(cdh) } func (ie *ioEvent) Read(err int, data []byte, auxdata []string) uint64 { if err != 0 { ie.info.errstr = gensio.ErrToStr(err) ie.startClose() return 0 } defer func() { if r := recover(); r != nil { ie.info.errstr = fmt.Sprintf("%s", r) ie.startClose() } }() count := ie.g.Write(data, nil) if count < uint64(len(data)) { ie.g.SetReadCallbackEnable(false) ie.otherie.g.SetWriteCallbackEnable(true) } return count } func (ie *ioEvent) WriteReady() { ie.otherie.g.SetReadCallbackEnable(true) ie.g.SetWriteCallbackEnable(false) } type LogHandler struct { gensio.LoggerBase } func (l *LogHandler) Log(level int, log string) { fmt.Printf("LOG(%s): %s\n", gensio.LogLevelToStr(level), log) } func main() { o := gensio.NewOsFuncs(&LogHandler{}) w := gensio.NewWaiter(o) info := ioInfo{w, "", false} telnetEvent := &ioEvent{} telnetEvent.info = &info; userEvent := &ioEvent{} userEvent.info = &info; userEvent.g = gensio.NewGensio("stdio(self)", o, userEvent) userEvent.g.OpenS() telnetEvent.g = gensio.NewGensio("telnet,tcp,localhost,1234", o, telnetEvent) telnetEvent.g.OpenS() userEvent.otherie = telnetEvent telnetEvent.otherie = userEvent userEvent.g.SetReadCallbackEnable(true) telnetEvent.g.SetReadCallbackEnable(true) w.Wait(2, nil) fmt.Println("Shut down due to:", info.errstr); } gensio-3.0.0/c++/swig/go/tests/0000775000175000017500000000000015061121734011631 5gensio-3.0.0/c++/swig/go/tests/srctest_basic.go0000664000175000017500000001147314666635622014756 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only package main import ( "fmt" "github.com/cminyard/go/gensio" "testbase" ) type TelnetReflEvHnd struct { testbase.ReflEvHnd gotBreak bool w *gensio.Waiter } func (treh *TelnetReflEvHnd) SendBreak() { treh.gotBreak = true treh.w.Wake() } type OpenDone struct { gensio.GensioOpenDoneBase err int w *gensio.Waiter } func (oh *OpenDone) OpenDone(err int) { oh.err = err oh.w.Wake() } type CloseDone struct { gensio.GensioCloseDoneBase w *gensio.Waiter } func (oh *CloseDone) CloseDone() { oh.w.Wake() } type ParmlogEvHnd struct { gensio.EventBase log string paniced bool } func (eh *ParmlogEvHnd) Parmlog(s string) { eh.log = s } func testParmlog1(o *gensio.OsFuncs, eh *ParmlogEvHnd) gensio.Gensio { defer func() { if err := recover(); err != nil { eh.paniced = true } }() // This will fail and not create an object. return gensio.NewGensio("tcp(asdf=x),localhost,123", o, eh) } type ParmlogAccEvHnd struct { gensio.AccepterEventBase log string paniced bool } func (eh *ParmlogAccEvHnd) Parmlog(s string) { eh.log = s } func testParmlog2(o *gensio.OsFuncs, eh *ParmlogAccEvHnd) gensio.Accepter { defer func() { if err := recover(); err != nil { eh.paniced = true } }() // This will fail and not create an object. return gensio.NewAccepter("tcp(asdf=x),localhost,123", o, eh) } func testParmlog(o *gensio.OsFuncs) { fmt.Println("Test Parmlog") //testbase.ObjCount++ eh := &ParmlogEvHnd{} testParmlog1(o, eh) if !eh.paniced { panic("Did not panic on error") } if eh.log != "gensio tcp: unknown parameter asdf=x" { panic("Wrong parmlog error: " + eh.log) } //testbase.ObjCount++ eha := &ParmlogAccEvHnd{} testParmlog2(o, eha) if !eha.paniced { panic("Did not panic on error") } if eha.log != "accepter tcp: unknown parameter asdf=x" { panic("Wrong parmlog error: " + eha.log) } } func testSync(o *gensio.OsFuncs) { fmt.Println("Test sync I/O") testbase.ObjCount++ r := testbase.NewReflector(o, "tcp,localhost,0", nil) r.Startup() port := r.GetPort() testbase.ObjCount++ t := gensio.NewTime(0, 0) testbase.ObjCount++ g := gensio.NewGensio("tcp,localhost," + port, o, nil) g.OpenS() g.SetSync() outstr := []byte("Test sync string") t.SetTime(1, 0) rv, count := g.WriteS(outstr, t, false) if rv != 0 { panic("WriteS returned error: " + gensio.ErrToStr(rv)) } if count != uint64(len(outstr)) { panic("WriteS returned too few bytes: ") } data := make([]byte, 100) t.SetTime(1, 0) rv, newdata := g.ReadS(data, t, false) if rv != 0 { panic("ReadS returned error: " + gensio.ErrToStr(rv)) } if ! testbase.Cmpbytes(newdata, outstr) { panic("Data mismatch") } g.CloseS() r.CloseS() r.ShutdownS() } func testAsync(o *gensio.OsFuncs) { fmt.Println("Test async I/O") testbase.ObjCount++ t := gensio.NewTime(0, 0) testbase.ObjCount++ treh := &TelnetReflEvHnd{} testbase.ObjCount++ r := testbase.NewReflector(o, "telnet,tcp,localhost,0", treh) r.Startup() port := r.GetPort() r.SetEnableCb(false) t.SetTime(1, 0) rv := r.Wait(1, t) if rv != 0 { panic("Error waiting for cb disable: " + gensio.ErrToStr(rv)) } r.SetEnableS(false) r.SetEnable(true) testbase.ObjCount++ h := &testbase.EvHnd{} h.Setup(o) testbase.ObjCount++ g := gensio.NewGensio("telnet,tcp,localhost," + port, o, h) h.SetGensio(g) testbase.ObjCount++ st := g.GetType(0) if st != "telnet" { panic(fmt.Sprintf("Wrong gensio type, expected telnet, got %s\n", st)) } st = g.GetType(1) if st != "tcp" { panic(fmt.Sprintf("Wrong gensio type, expected tcp, got %s\n", st)) } st = g.GetType(2) if len(st) != 0 { panic("Got a gensio type when exceeding depth") } oh := &OpenDone{} testbase.ObjCount++ oh.w = gensio.NewWaiter(o) g.Open(oh) t.SetTime(1, 0) rv = oh.w.Wait(1, t) if rv != 0 { panic("Error waiting for open: " + gensio.ErrToStr(rv)) } if oh.err != 0 { panic("Error from open: " + gensio.ErrToStr(oh.err)) } oh = nil teststr := []byte("Test string") h.SetData(teststr) t.SetTime(1, 0) rv = h.Wait(1, t) if rv != 0 { panic("Error waiting for data: " + gensio.ErrToStr(rv)) } testbase.ObjCount++ ch := &CloseDone{} testbase.ObjCount++ ch.w = gensio.NewWaiter(o) g.Close(ch) t.SetTime(1, 0) rv = ch.w.Wait(1, t) if rv != 0 { panic("Error waiting for close: " + gensio.ErrToStr(rv)) } ch = nil r.CloseS() r.Shutdown() t.SetTime(1, 0) rv = r.Wait(1, t) if rv != 0 { panic("Error waiting for shutdown: " + gensio.ErrToStr(rv)) } } func main() { fmt.Println("Starting basic Go tests") o := testbase.O gensio.SetLogMask(gensio.LOG_MASK_ALL) o.Log(gensio.LOG_INFO, "Test Log") testParmlog(o) testSync(o) testAsync(o) o = nil gensio.Debug = true testbase.TestShutdown() fmt.Println("Pass") } gensio-3.0.0/c++/swig/go/tests/Makefile.in0000664000175000017500000012056015061121657013626 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @BUILTIN_MDNS_TRUE@am__append_1 = $(MDNS_LIBS) @BUILTIN_SOUND_TRUE@am__append_2 = $(SOUND_LIBS) @BUILTIN_SCTP_TRUE@am__append_3 = $(LIBSCTP_LIBS) @BUILTIN_SSL_TRUE@am__append_4 = $(OPENSSL_LIBS) @BUILTIN_IPMISOL_TRUE@am__append_5 = $(OPENIPMI_LIBS) subdir = c++/swig/go/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = runtest CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ check recheck distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/runtest.in \ $(top_srcdir)/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = testbase LOG_COMPILER = $(SHELL) $(builddir)/runtest TESTS = test_basic test_ax25 test_crypto test_serial test_mdns test_netifs TEST_SRCS = test_basic.go test_ax25.go test_crypto.go test_serial.go \ test_mdns.go test_netifs.go GOMOD = github.com/cminyard/go/gensio MORE_LIBS = $(am__append_1) $(am__append_2) $(am__append_3) \ $(am__append_4) $(am__append_5) EXTRA_DIST = srctest_basic.go srctest_ax25.go srctest_crypto.go \ srctest_serial.go srctest_mdns.go srctest_netifs.go all: all-recursive .SUFFIXES: .SUFFIXES: .log .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/swig/go/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/swig/go/tests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): runtest: $(top_builddir)/config.status $(srcdir)/runtest.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? test_basic.log: test_basic @p='test_basic'; \ b='test_basic'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_ax25.log: test_ax25 @p='test_ax25'; \ b='test_ax25'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_crypto.log: test_crypto @p='test_crypto'; \ b='test_crypto'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_serial.log: test_serial @p='test_serial'; \ b='test_serial'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_mdns.log: test_mdns @p='test_mdns'; \ b='test_mdns'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_netifs.log: test_netifs @p='test_netifs'; \ b='test_netifs'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) check-am install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-TESTS check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags ctags-am distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am .PRECIOUS: Makefile export VERBOSE = 1 test_crypto: ca/CA.key ca/CA.key: $(top_srcdir)/tests/make_keys test_basic.go: $(srcdir)/srctest_basic.go testbase/testbase.go cp $(srcdir)/srctest_basic.go test_basic.go test_ax25.go: $(srcdir)/srctest_ax25.go testbase/testbase.go cp $(srcdir)/srctest_ax25.go test_ax25.go test_crypto.go: $(srcdir)/srctest_crypto.go testbase/testbase.go cp $(srcdir)/srctest_crypto.go test_crypto.go test_serial.go: $(srcdir)/srctest_serial.go testbase/testbase.go cp $(srcdir)/srctest_serial.go test_serial.go test_mdns.go: $(srcdir)/srctest_mdns.go testbase/testbase.go cp $(srcdir)/srctest_mdns.go test_mdns.go test_netifs.go: $(srcdir)/srctest_netifs.go testbase/testbase.go cp $(srcdir)/srctest_netifs.go test_netifs.go go.mod: $(TEST_SRCS) rm -f go.mod go mod init tests go mod edit -replace $(GOMOD)=../gensio go mod edit -replace testbase=./testbase go mod tidy export CXX export CC export CGO_CXXFLAGS = $(CXXFLAGS) $(AM_CXXFLAGS) \ -I$(top_srcdir)/c++/swig/include export CGO_CPPFLAGS = $(CPPFLAGS) -I$(top_srcdir)/c++/swig/include export CGO_LDFLAGS = -L$(top_builddir)/c++/lib/.libs \ -lgensiooshcpp -lgensiocpp -lgensiomdnscpp \ -L$(top_builddir)/lib/.libs -lgensioosh -lgensio -lgensiomdns \ $(MORE_LIBS) test_basic: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx \ ../gensio/gensio_wrap.h \ test_basic.go ../gensio/gensioapi.go go.mod echo $(MORE_LIBS) go build test_basic.go test_ax25: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx \ ../gensio/gensio_wrap.h \ test_ax25.go ../gensio/gensioapi.go go.mod go build test_ax25.go test_crypto: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx \ ../gensio/gensio_wrap.h \ test_crypto.go ../gensio/gensioapi.go go.mod go build test_crypto.go test_serial: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx \ ../gensio/gensio_wrap.h \ test_serial.go ../gensio/gensioapi.go go.mod go build test_serial.go test_mdns: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx \ ../gensio/gensio_wrap.h \ test_mdns.go ../gensio/gensioapi.go go.mod go build test_mdns.go test_netifs: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx \ ../gensio/gensio_wrap.h \ test_netifs.go ../gensio/gensioapi.go go.mod go build test_netifs.go clean-local: rm -rf go.mod ca $(TESTS) $(TEST_SRCS) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/c++/swig/go/tests/srctest_netifs.go0000664000175000017500000000174014664224267015156 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only package main import ( "fmt" "github.com/cminyard/go/gensio" "testbase" ) func main() { netifs := gensio.NewNetIfs(testbase.O) numifs := netifs.GetNumIfs() var i uint for i = 0; i < numifs; i++ { name := netifs.GetName(i) up := "" if netifs.IsUp(i) { up = " up" } loopback := "" if netifs.IsLoopback(i) { loopback = " loopback" } multicast := "" if netifs.IsMulticast(i) { multicast = " multicast" } ifidx := netifs.GetIfIndex(i) numaddrs := netifs.GetNumAddrs(i) fmt.Printf("%s(%d):%s%s%s:\n", name, ifidx, up, loopback, multicast) var j uint for j = 0; j < numaddrs; j++ { netbits := netifs.GetAddrNetbits(i, j) family := netifs.GetAddrFamily(i, j) addrstr := netifs.GetAddrStr(i, j) fmt.Printf(" %s/%d %d\n", addrstr, netbits, family) } } testbase.TestShutdown() } gensio-3.0.0/c++/swig/go/tests/srctest_crypto.go0000664000175000017500000001310214664224267015201 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only package main import ( "fmt" "github.com/cminyard/go/gensio" "testbase" ) type CryptoReflector struct { testbase.ReflectorBase } func (r *CryptoReflector) AuthBegin(g gensio.Gensio) int { fmt.Println("Auth Begin") namedata := make([]byte, 256) rv, name, actlen := g.Control(gensio.GENSIO_CONTROL_DEPTH_FIRST, true, gensio.GENSIO_CONTROL_USERNAME, namedata) if rv != 0 { panic("Error from control: " + gensio.ErrToStr(rv)) } if actlen > 256 { panic("name data too large") } if string(name) != "asdf" { panic("Name mismatch") } return gensio.GE_NOTSUP } func (r *CryptoReflector) PrecertVerify(g gensio.Gensio) int { fmt.Println("Precert Verify") return gensio.GE_NOTSUP } func (r *CryptoReflector) PostcertVerify(g gensio.Gensio, err int, errstr string) int { fmt.Println("Postcert Verify") return gensio.GE_NOTSUP } func (r *CryptoReflector) PasswordVerify(g gensio.Gensio, password string) int { fmt.Println("Password Verify") if password != "jkl" { panic("Password mismatch") } return gensio.GE_NOTSUP } func (r *CryptoReflector) RequestPassword(g gensio.Gensio, maxsize uint64) (int, string) { fmt.Println("Request Password") return 0, "jkl" } func (r *CryptoReflector) Verify2fa(g gensio.Gensio, val []byte) int { fmt.Println("Verify 2fa") if string(val) != "1234" { panic("2fa mismatch") } return 0 } func (r *CryptoReflector) Request2fa(g gensio.Gensio) (int, []byte) { fmt.Println("Request 2fa") return 0, []byte("1234") } type CryptoEvFuncs struct { } func (r *CryptoEvFuncs) PrecertVerify() int { fmt.Println("Precert Verify 2") return gensio.GE_NOTSUP } func (r *CryptoEvFuncs) PostcertVerify(err int, errstr string) int { fmt.Println("Postcert Verify 2") return gensio.GE_NOTSUP } func (r *CryptoEvFuncs) PasswordVerify(password string) int { fmt.Println("Password Verify 2") if password != "jkl" { panic("Password mismatch") } return gensio.GE_NOTSUP } func (r *CryptoEvFuncs) RequestPassword(maxsize uint64) (int, string) { fmt.Println("Request Password 2") return 0, "jkl" } func (r *CryptoEvFuncs) Verify2fa(val []byte) int { fmt.Println("Verify 2fa 2") if string(val) != "1234" { panic("2fa mismatch") } return 0 } func (r *CryptoEvFuncs) Request2fa() (int, []byte) { fmt.Println("Request 2fa 2") return 0, []byte("1234") } type CryptoEvHnd struct { testbase.EvHnd CryptoEvFuncs } // Since this references r.G this can't be in CryptoEvFuncs. func (r *CryptoEvHnd) AuthBegin() int { fmt.Println("Auth Begin 2") namedata := make([]byte, 256) rv, name, actlen := r.G.Control(gensio.GENSIO_CONTROL_DEPTH_FIRST, true, gensio.GENSIO_CONTROL_USERNAME, namedata) if rv != 0 { panic("Error from control: " + gensio.ErrToStr(rv)) } if actlen > 256 { panic("Name data too large") } if string(name) != "asdf" { panic("Name mismatch") } return gensio.GE_NOTSUP } func testCryptoForward(o *gensio.OsFuncs) { fmt.Println("Testing Crypto forward interface") testbase.ObjCount++ r := &CryptoReflector{} r.Init(o, "certauth(enable-password,enable-2fa)," + "ssl(key=ca/key.pem,cert=ca/cert.pem),tcp,localhost,0", nil, r) r.Startup() port := r.GetPort() testbase.ObjCount++ h := &CryptoEvHnd{} h.Setup(o) testbase.ObjCount++ g := gensio.NewGensio("certauth(username=asdf,enable-password)," + "ssl(ca=ca/CA.pem),tcp,localhost," + port, o, h) h.SetGensio(g) g.OpenS() testbase.VerifyAccepter(r.GetAccepter(), "certauth", true, true, false) testbase.VerifyGensio(g, "certauth", true, true, true, true, true, false) tstdata := []byte("Crypto Test String") h.SetData(tstdata) testbase.ObjCount++ rv := h.Wait(1, gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for data: " + gensio.ErrToStr(rv)) } g.CloseS() r.CloseS() r.ShutdownS() } type CryptoReflEvHnd struct { testbase.ReflEvHnd CryptoEvFuncs } // Since this references r.G this can't be in CryptoEvFuncs. func (r *CryptoReflEvHnd) AuthBegin() int { fmt.Println("Auth Begin 2") rv, name, actlen := r.G.Control(gensio.GENSIO_CONTROL_DEPTH_FIRST, true, gensio.GENSIO_CONTROL_USERNAME, []byte("0")) if rv != 0 { panic("Error from control: " + gensio.ErrToStr(rv)) } if actlen > 256 { panic("Name data too large") } if string(name) != "asdf" { panic("Name mismatch") } return gensio.GE_NOTSUP } func testCryptoBackward(o *gensio.OsFuncs) { fmt.Println("Testing Crypto forward interface") testbase.ObjCount++ hr := &CryptoReflEvHnd{} testbase.ObjCount++ r := &CryptoReflector{} r.Init(o, "certauth(username=asdf,enable-password,mode=client)," + "ssl(ca=ca/CA.pem,mode=client),tcp,localhost,0", hr, r) r.Startup() port := r.GetPort() testbase.ObjCount++ h := &CryptoEvHnd{} h.Setup(o) testbase.ObjCount++ g := gensio.NewGensio( "certauth(enable-password,enable-2fa,mode=server)," + "ssl(key=ca/key.pem,cert=ca/cert.pem,mode=server),tcp,localhost," + port, o, h) h.SetGensio(g) testbase.VerifyAccepter(r.GetAccepter(), "certauth", true, true, false) g.OpenS() testbase.VerifyGensio(g, "certauth", false, true, true, true, true, false) tstdata := []byte("Crypto Test String") h.SetData(tstdata) testbase.ObjCount++ rv := h.Wait(1, gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for data: " + gensio.ErrToStr(rv)) } g.CloseS() r.CloseS() r.ShutdownS() } func main() { fmt.Println("Starting Crypto Go tests") o := testbase.O gensio.SetLogMask(gensio.LOG_MASK_ALL) testCryptoForward(o) testCryptoBackward(o) testbase.TestShutdown() } gensio-3.0.0/c++/swig/go/tests/srctest_mdns.go0000664000175000017500000000602214664224267014625 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only package main import ( "fmt" "github.com/cminyard/go/gensio" "testbase" "runtime" ) type FreeDone struct { gensio.MDNSFreeDoneBase w *gensio.Waiter } func (fd *FreeDone) MDNSFreeDone() { fd.w.Wake() } type WatchFreeDone struct { gensio.MDNSWatchFreeDoneBase w *gensio.Waiter } func (fd *WatchFreeDone) MDNSWatchFreeDone() { fd.w.Wake() } type WatchEvent struct { gensio.MDNSWatchEventBase w *gensio.Waiter watchCount int found bool } func (we *WatchEvent) Event(state int, interfacenum int, ipdomain int, name string, mtype string, domain string, host string, addr gensio.Addr, txt []string) { if state == gensio.MDNS_WATCH_ALL_FOR_NOW { /* Don't do a wake here, it's not reliable. */ } else if state == gensio.MDNS_WATCH_NEW_DATA { if !we.found { we.found = true we.w.Wake() } } else { we.watchCount++ } } type ServiceEvent struct { gensio.MDNSServiceEventBase w *gensio.Waiter } func (se *ServiceEvent) Event(ev int, info string) { if ev == gensio.MDNS_SERVICE_READY { fmt.Printf("Service ready: %s\n", info); } else if ev == gensio.MDNS_SERVICE_READY_NEW_NAME { fmt.Printf("Service ready with new name: %s\n", info); } else if ev == gensio.MDNS_SERVICE_REMOVED { fmt.Printf("Service removed\n"); se.w.Wake() } else { fmt.Printf("Error from service: %s\n", info); } } func main() { fmt.Println("Starting MDNS Go tests") o := testbase.O gensio.SetLogMask(gensio.LOG_MASK_ALL) testbase.ObjCount++ waiter := gensio.NewWaiter(o) testbase.ObjCount++ m := gensio.NewMDNS(o) testbase.ObjCount++ we := &WatchEvent{} we.w = waiter testbase.ObjCount++ var namestr string if runtime.GOOS == "windows" { // No glob support in windows. namestr = "gensio2" } else { namestr = "@gen*" } w := m.AddWatch(-1, gensio.GENSIO_NETTYPE_UNSPEC, namestr, "_gensio2._tcp", nil, nil, we) testbase.ObjCount++ se := &ServiceEvent{} se.w = waiter s := m.AddService(-1, gensio.GENSIO_NETTYPE_UNSPEC, "gensio2", "_gensio2._tcp", nil, nil, 5001, []string{"A=1", "B=2"}, se) testbase.ObjCount++ rv := waiter.Wait(1, gensio.NewTime(5, 0)) if rv != 0 { panic("Error waiting for watch: " + gensio.ErrToStr(rv)) } if (! we.found) { panic("Watch data not found") } testbase.ObjCount++ wfh := &WatchFreeDone{} wfh.w = waiter w.Free(wfh) testbase.ObjCount++ rv = waiter.Wait(1, gensio.NewTime(5, 0)) if rv != 0 { panic("Error waiting for watch free: " + gensio.ErrToStr(rv)) } wfh = nil w = nil s.Free() rv = waiter.Wait(1, gensio.NewTime(5, 0)) if rv != 0 { panic("Error waiting for service free: " + gensio.ErrToStr(rv)) } s = nil testbase.ObjCount++ fd := &FreeDone{} fd.w = waiter m.Free(fd) testbase.ObjCount++ rv = waiter.Wait(1, gensio.NewTime(5, 0)) if rv != 0 { panic("Error waiting for mdns free: " + gensio.ErrToStr(rv)) } fd = nil m = nil we = nil se = nil waiter = nil o = nil testbase.TestShutdown() } gensio-3.0.0/c++/swig/go/tests/runtest.in0000664000175000017500000000334114664224267013623 #!/bin/sh SRCDIR="@top_srcdir@" TEST_SRCDIR="${SRCDIR}/c++/swig/go/tests" BUILDDIR="@top_builddir@" TEST_BUILDDIR="${BUILDDIR}/c++/swig/go/tests" PRINT_MODE=false while echo $1 | grep '^-' >/dev/null; do if [ "X$1" = "X--print" ]; then PRINT_MODE=true elif [ "X$1" = "X--" ]; then break else echo "Unknown option: $1" 1>&2 exit 1 fi shift done if [ -z "$1" ]; then echo "No test given" 1>&2 exit 1 fi # See if we are skipping this test T1=`basename $1` if echo "$SKIP_TESTS" | grep -q "$T1"; then exit 77 fi TEST=$1 shift if [ -e "${TEST_BUILDDIR}/${TEST}" ]; then TEST="${TEST_BUILDDIR}/${TEST}" elif [ -e "${TEST_SRCDIR}/${TEST}" ]; then TEST="${TEST_SRCDIR}/${TEST}" else echo "Test ${TEST} not found" 1>&2 exit 1 fi if [ ! -x ${TEST} ]; then echo "Test ${TEST} is not executable" 1>&2 exit 1 fi # We need to put the DLL in PATH for MSYS on Windows if [ ! -z "$MSYSTEM" ]; then export PATH=${BUILDDIR}/lib:${BUILDDIR}/lib/.libs:${BUILDDIR}/c++/lib/.libs:${BUILDDIR}/glib/.libs:${BUILDDIR}/glib/c++/swig/pygensio/.libs:${BUILDDIR}/tcl/.libs:${BUILDDIR}/tcl/c++/swig/pygensio/.libs:$PATH else export LD_LIBRARY_PATH=${BUILDDIR}/lib:${BUILDDIR}/lib/.libs:${BUILDDIR}/c++/swig/python/.libs:${BUILDDIR}/glib/.libs:${BUILDDIR}/glib/c++/pygensio/.libs:${BUILDDIR}/tcl/.libs:${BUILDDIR}/tcl/c++/pygensio/.libs:${BUILDDIR}/c++/lib/.libs fi if test `uname` = Darwin; then TEST="DYLD_LIBRARY_PATH=${LD_LIBRARY_PATH} ${TEST}" fi if ${PRINT_MODE}; then echo export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" echo ${TEST} $* else # Run the test with each available OS handler eval "${TEST} $*" rv=$? if test $rv != 0; then # A test failed, exit exit $rv fi fi gensio-3.0.0/c++/swig/go/tests/testbase/0000775000175000017500000000000015061121734013443 5gensio-3.0.0/c++/swig/go/tests/testbase/Makefile.in0000664000175000017500000004110015061121657015430 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = c++/swig/go/tests/testbase ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SCRIPTS = $(noinst_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_SCRIPTS = go.mod GOMOD = github.com/cminyard/go/gensio EXTRA_DIST = testbase.srcgo all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/swig/go/tests/testbase/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/swig/go/tests/testbase/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(SCRIPTS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile go.mod: testbase.go rm -f go.mod go mod init testbase go mod edit -replace $(GOMOD)=$(abs_builddir)/../../gensio go mod tidy $(builddir)/testbase.go: $(srcdir)/testbase.srcgo cp $(srcdir)/testbase.srcgo testbase.go clean-local: rm -f testbase.go go.mod # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/c++/swig/go/tests/testbase/testbase.srcgo0000664000175000017500000001651415045153771016253 package testbase import "fmt" import "github.com/cminyard/go/gensio" import "runtime" // Count of allocated objects var ObjCount uint32 = 2 // For the OsFuncs and LogHandler blow type LogHandler struct { gensio.LoggerBase } func (l *LogHandler) Log(level int, log string) { fmt.Printf("LOG(%s): %s\n", gensio.LogLevelToStr(level), log) } var O *gensio.OsFuncs = gensio.NewOsFuncs(&LogHandler{}) type ReflEvent interface { gensio.Event BreakLinks() setup(r Reflector, w *gensio.Waiter) setGensio(g gensio.Gensio) } type ReflEvHnd struct { gensio.EventBase G gensio.Gensio r Reflector err int data []byte } func (re *ReflEvHnd) setGensio(g gensio.Gensio) { re.G = g } func (re *ReflEvHnd) setup(r Reflector, w *gensio.Waiter) { re.r = r } func (re *ReflEvHnd) BreakLinks() { re.r = nil re.G = nil } func (re *ReflEvHnd) Read(err int, data []byte, auxdata []string) uint64 { re.G.SetReadCallbackEnable(false) if err != 0 { if err != gensio.GE_REMCLOSE { re.err = err } re.G = nil re.r = nil return 0 } re.data = data re.G.SetWriteCallbackEnable(true) return uint64(len(data)) } func (re *ReflEvHnd) WriteReady() { if re.data == nil { re.G.SetWriteCallbackEnable(false) return } count := re.G.Write(re.data, nil) if count == uint64(len(re.data)) { re.data = nil re.G.SetWriteCallbackEnable(false) re.G.SetReadCallbackEnable(true) } else { re.data = re.data[count:] } } type ReflShutdownDone struct { gensio.AccepterShutdownDoneBase r Reflector } func (rsd *ReflShutdownDone) AccShutdownDone() { rsd.r.accShutdownDone() } type ReflEnableDone struct { gensio.AccepterEnableDoneBase r Reflector } func (red *ReflEnableDone) AccEnableDone() { red.r.accEnableDone() } type Reflector interface { gensio.AccepterEvent Init(o *gensio.OsFuncs, accstr string, evh ReflEvent, cb Reflector) CloseS() Startup() SetEnable(val bool) SetEnableS(val bool) SetEnableCb(val bool) accEnableDone() Shutdown() accShutdownDone() ShutdownS() GetPort() string breakLinks() Wait(count uint, timeout *gensio.Time) int GetAccepter() gensio.Accepter GetGensio() gensio.Gensio } type ReflectorBase struct { gensio.AccepterEventBase evh ReflEvent w *gensio.Waiter acc gensio.Accepter g gensio.Gensio } func (r *ReflectorBase) Log(level int, log string) { fmt.Printf("AccLOG(%s): %s\n", gensio.LogLevelToStr(level), log) } func (r *ReflectorBase) GetAccepter() gensio.Accepter { return r.acc } func (r *ReflectorBase) GetGensio() gensio.Gensio { return r.g } func (r *ReflectorBase) Init(o *gensio.OsFuncs, accstr string, evh ReflEvent, cb Reflector) { ObjCount++ r.w = gensio.NewWaiter(o) if evh == nil { ObjCount++ evh = &ReflEvHnd{} } evh.setup(r, r.w) // Circ ref, make sure to break r.evh = evh ObjCount++ r.acc = gensio.NewAccepter(accstr, o, cb) } func NewReflector(o *gensio.OsFuncs, accstr string, evh ReflEvent) Reflector { r := &ReflectorBase{} r.Init(o, accstr, evh, r) return r } func (r *ReflectorBase) NewConnection(g gensio.Gensio) { if r.g != nil { return } ObjCount++ r.g = g r.evh.setGensio(g) g.SetEvent(r.evh) g.SetReadCallbackEnable(true) } func (r *ReflectorBase) CloseS() { r.g.CloseS() r.g = nil } func (r *ReflectorBase) Startup() { r.acc.Startup() } func (r *ReflectorBase) SetEnable(val bool) { r.acc.SetCallbackEnable(val, nil) } func (r *ReflectorBase) SetEnableS(val bool) { r.acc.SetCallbackEnableS(val) } func (r *ReflectorBase) SetEnableCb(val bool) { ObjCount++ red := &ReflEnableDone{} red.r = r r.acc.SetCallbackEnable(val, red) } func (r *ReflectorBase) accEnableDone() { r.w.Wake() } func (r *ReflectorBase) Shutdown() { ObjCount++ reh := &ReflShutdownDone{} reh.r = r r.acc.Shutdown(reh) } func (r *ReflectorBase) accShutdownDone() { r.w.Wake() r.breakLinks() } func (r *ReflectorBase) ShutdownS() { r.acc.ShutdownS() r.breakLinks() } func (r *ReflectorBase) GetPort() string { return r.acc.GetPort() } func (r *ReflectorBase) breakLinks() { r.evh.BreakLinks() r.evh = nil r.g = nil r.acc = nil } func (r *ReflectorBase) Wait(count uint, timeout *gensio.Time) int { return r.w.Wait(count, timeout) } func Cmpbytes(b1 []byte, b2 []byte) bool { if len(b1) != len(b2) { return false } for i, v := range b1 { if b2[i] != v { return false } } return true } type Event interface { gensio.Event Setup(o *gensio.OsFuncs) SetGensio(g gensio.Gensio) } type EvHnd struct { gensio.EventBase o *gensio.OsFuncs Data []byte Readpos int Writepos int G gensio.Gensio W *gensio.Waiter } func (eh *EvHnd) Setup(o *gensio.OsFuncs) { eh.o = o ObjCount++ eh.W = gensio.NewWaiter(o) } func (eh *EvHnd) SetGensio(g gensio.Gensio) { eh.G = g } func (eh *EvHnd) Read(err int, data []byte, auxdata []string) uint64 { readlen := len(data) if readlen + eh.Readpos > len(eh.Data) { panic("Read too much data") } if ! Cmpbytes(data, eh.Data[eh.Readpos:eh.Readpos + readlen]) { panic("Data mismatch") } eh.Readpos += readlen if eh.Readpos == len(eh.Data) { eh.W.Wake() eh.G = nil } return uint64(readlen) } func (eh *EvHnd) WriteReady() { if eh.Data == nil || eh.Writepos >= len(eh.Data) { eh.G.SetWriteCallbackEnable(false) return } count := eh.G.Write(eh.Data[eh.Writepos:], nil) eh.Writepos += int(count) if eh.Writepos >= len(eh.Data) { eh.G.SetWriteCallbackEnable(false) } } func (eh *EvHnd) SetData(data []byte) { eh.Data = data eh.Readpos = 0 eh.Writepos = 0 eh.G.SetReadCallbackEnable(true) eh.G.SetWriteCallbackEnable(true) } func (eh *EvHnd) Wait(count uint, timeout *gensio.Time) int { return eh.W.Wait(count, timeout) } func TestShutdown() { ObjCount++ w := gensio.NewWaiter(O) ObjCount++ t := gensio.NewTime(0, 0) for count := 0; gensio.Gensio_num_alloced() > 0; count++ { if (count > 100) { panic(fmt.Sprintf( "All gensios not freed in time, still %d left", gensio.Gensio_num_alloced())) } t.SetTime(0, 1000000) w.Service(t) runtime.GC() } w = nil O.Set_log_handler(nil) runtime.GC() runtime.GC() for count := 0; O.Get_refcount() != 1; count++ { if (count > 100) { panic(fmt.Sprintf("OS funcs refcount was not 1, it was %d", O.Get_refcount())) } runtime.GC() } O.Cleanup_mem() O = nil for count := 0; gensio.GCCount != ObjCount; count++ { if (count > 100) { panic(fmt.Sprintf("GC-ed object count was %d, should be %d", gensio.GCCount, ObjCount)) } runtime.GC() } } func VerifyAccepter(acc gensio.Accepter, acctype string, isReliable bool, isPacket bool, isMessage bool) { if acc.GetType(0) != acctype { panic("Accepter type incorrect") } if acc.IsReliable() != isReliable { panic("IsReliable incorrect") } if acc.IsPacket() != isPacket { panic("IsPacket incorrect") } if acc.IsMessage() != isMessage { panic("IsMessage incorrect") } } func VerifyGensio(g gensio.Gensio, gentype string, isClient bool, isReliable bool, isPacket bool, isAuthenticated bool, isEncrypted bool, isMessage bool) { if g.GetType(0) != gentype { panic("Gensio type incorrect") } if g.IsClient() != isClient { panic("IsClient incorrect") } if g.IsReliable() != isReliable { panic("IsReliable incorrect") } if g.IsPacket() != isPacket { panic("IsPacket incorrect") } if g.IsAuthenticated() != isAuthenticated { panic("IsAuthenticated incorrect") } if g.IsEncrypted() != isEncrypted { panic("IsEncrypted incorrect") } if g.IsMessage() != isMessage { panic("IsMessage incorrect") } } gensio-3.0.0/c++/swig/go/tests/testbase/Makefile.am0000664000175000017500000000054314664224267015436 noinst_SCRIPTS = go.mod GOMOD = github.com/cminyard/go/gensio go.mod: testbase.go rm -f go.mod go mod init testbase go mod edit -replace $(GOMOD)=$(abs_builddir)/../../gensio go mod tidy $(builddir)/testbase.go: $(srcdir)/testbase.srcgo cp $(srcdir)/testbase.srcgo testbase.go EXTRA_DIST = testbase.srcgo clean-local: rm -f testbase.go go.mod gensio-3.0.0/c++/swig/go/tests/srctest_serial.go0000664000175000017500000003060715045153771015144 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only package main import ( "fmt" "bytes" "github.com/cminyard/go/gensio" "testbase" ) type STelnetReflEvHnd struct { testbase.ReflEvHnd gotBreak bool baudV uint sigV []byte datasizeV uint parityV uint stopbitsV uint flowcontrolV uint iflowcontrolV uint sbreakV uint dtrV uint rtsV uint } func (e *STelnetReflEvHnd) Signature(sig []byte) { if len(sig) > 0 { panic("Signature received on server") } e.G.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_SIGNATURE, e.sigV, nil, nil); } func (e *STelnetReflEvHnd) Flush(val uint) { // FIXME - how to detect? } func (e *STelnetReflEvHnd) Sync() { } func (e *STelnetReflEvHnd) Baud(val uint) { if val != 0 { e.baudV = val } e.G.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_BAUD, []byte(fmt.Sprint(e.baudV)), nil, nil); } func (e *STelnetReflEvHnd) Datasize(val uint) { if val != 0 { e.datasizeV = val } e.G.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_DATASIZE, []byte(fmt.Sprint(e.datasizeV)), nil, nil); } func (e *STelnetReflEvHnd) Parity(val uint) { fmt.Printf("Parity: %d\n", val) if val != 0 { e.parityV = val } spar := gensio.Gensio_parity_to_str(e.parityV) fmt.Printf("Parity2: %s\n", spar) e.G.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_PARITY, []byte(spar), nil, nil); } func (e *STelnetReflEvHnd) Stopbits(val uint) { if val != 0 { e.stopbitsV = val } e.G.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_STOPBITS, []byte(fmt.Sprint(e.stopbitsV)), nil, nil); } func (e *STelnetReflEvHnd) Flowcontrol(val uint) { if val != 0 { e.flowcontrolV = val } sflow := gensio.Gensio_flowcontrol_to_str(e.flowcontrolV) e.G.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_FLOWCONTROL, []byte(sflow), nil, nil); } func (e *STelnetReflEvHnd) Iflowcontrol(val uint) { if val != 0 { e.iflowcontrolV = val } sflow := gensio.Gensio_flowcontrol_to_str(e.iflowcontrolV) e.G.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_IFLOWCONTROL, []byte(sflow), nil, nil); } func (e *STelnetReflEvHnd) Sbreak(val uint) { if val != 0 { e.sbreakV = val } sval := gensio.Gensio_onoff_to_str(e.sbreakV) e.G.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_SBREAK, []byte(sval), nil, nil); } func (e *STelnetReflEvHnd) Dtr(val uint) { if val != 0 { e.dtrV = val } sval := gensio.Gensio_onoff_to_str(e.dtrV) e.G.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_DTR, []byte(sval), nil, nil); } func (e *STelnetReflEvHnd) Rts(val uint) { if val != 0 { e.rtsV = val } sval := gensio.Gensio_onoff_to_str(e.rtsV) e.G.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_RTS, []byte(sval), nil, nil); } func (e *STelnetReflEvHnd) SendBreak() { e.gotBreak = true } func (e *STelnetReflEvHnd) Modemstate(state uint) { } func (e *STelnetReflEvHnd) ModemstateMask(state uint) { } func (e *STelnetReflEvHnd) Linestate(state uint) { } func (e *STelnetReflEvHnd) LinestateMask(state uint) { } func (e *STelnetReflEvHnd) FlowState(state bool) { } type STelnetEvHnd struct { testbase.EvHnd gotBreak bool } func (e *STelnetEvHnd) Modemstate(state uint) { } func (e *STelnetEvHnd) ModemstateMask(state uint) { } func (e *STelnetEvHnd) Linestate(state uint) { } func (e *STelnetEvHnd) FlowState(state bool) { } func (e *STelnetEvHnd) SendBreak() { e.gotBreak = true e.W.Wake() } type SerControlDone struct { gensio.GensioControlDoneBase err int val []byte w *gensio.Waiter } func (d *SerControlDone) ControlDone(err int, val []byte) { fmt.Printf("Done!: %d %s\n", err, val) d.err = err d.val = val d.w.Wake() } var seb gensio.Event func main() { fmt.Println("Starting Serial Go tests") o := testbase.O gensio.SetLogMask(gensio.LOG_MASK_ALL) testbase.ObjCount++ tevh := &STelnetReflEvHnd{} seb = tevh testbase.ObjCount++ r := testbase.NewReflector(o, "telnet(rfc2217),tcp,localhost,0", tevh) r.Startup() port := r.GetPort() testbase.ObjCount++ h := &STelnetEvHnd{} h.Setup(o) testbase.ObjCount++ g := gensio.NewGensio("telnet(rfc2217),tcp,localhost," + port, o, h) h.SetGensio(g) testbase.VerifyAccepter(r.GetAccepter(), "telnet", true, false, false) g.OpenS() testbase.VerifyGensio(g, "telnet", true, true, false, false, false, false) tstdata := []byte("Telnet Test String") h.SetData(tstdata) testbase.ObjCount++ rv := h.Wait(1, gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for data: " + gensio.ErrToStr(rv)) } w := gensio.NewWaiter(o) tevh.sigV = []byte("mysig") testbase.ObjCount++ osd := &SerControlDone{} osd.w = w g.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_SIGNATURE, tevh.sigV, osd, nil) testbase.ObjCount++ rv = w.Wait(1, gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for signature: " + gensio.ErrToStr(rv)) } if osd.err != 0 { panic("Error from signature: " + gensio.ErrToStr(osd.err)) } if !testbase.Cmpbytes(osd.val, []byte("mysig")) { panic(fmt.Sprintf("Signature mismatch, expected %s got %s", "mysig", string(osd.val))) } osd = nil var stval []byte var stval2 []byte testbase.ObjCount++ osd = &SerControlDone{} osd.w = w stval = []byte("19200") g.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_BAUD, stval, osd, nil); testbase.ObjCount++ rv = w.Wait(1, gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for baud: " + gensio.ErrToStr(rv)) } if osd.err != 0 { panic("Error from baud: " + gensio.ErrToStr(osd.err)) } if !bytes.Equal(osd.val, stval) { panic(fmt.Sprintf("Baud mismatch, expected %s got %s", stval, osd.val)) } testbase.ObjCount++ rv, stval2, _ = g.AcontrolS(0, gensio.GENSIO_CONTROL_GET, gensio.GENSIO_ACONTROL_SER_BAUD, []byte("00000000"), gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for baud: " + gensio.ErrToStr(rv)) } if !bytes.Equal(stval2, stval) { panic(fmt.Sprintf("Baud mismatch2, expected %s got %s", stval, stval2)) } stval2 = nil stval = nil osd = nil testbase.ObjCount++ osd = &SerControlDone{} osd.w = w stval = []byte("7") g.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_DATASIZE, stval, osd, nil); testbase.ObjCount++ rv = w.Wait(1, gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for datasize: " + gensio.ErrToStr(rv)) } if osd.err != 0 { panic("Error from datasize: " + gensio.ErrToStr(osd.err)) } if !bytes.Equal(osd.val, stval) { panic(fmt.Sprintf("Datasize mismatch, expected %s got %s", stval, osd.val)) } testbase.ObjCount++ rv, stval2, _ = g.AcontrolS(0, gensio.GENSIO_CONTROL_GET, gensio.GENSIO_ACONTROL_SER_DATASIZE, []byte("00000000"), gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for datasize: " + gensio.ErrToStr(rv)) } if !bytes.Equal(stval2, stval) { panic(fmt.Sprintf("Datasize mismatch2, expected %s got %s", stval, stval2)) } osd = nil testbase.ObjCount++ osd = &SerControlDone{} osd.w = w stval = []byte("even") g.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_PARITY, stval, osd, nil); testbase.ObjCount++ rv = w.Wait(1, gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for parity: " + gensio.ErrToStr(rv)) } if osd.err != 0 { panic("Error from parity: " + gensio.ErrToStr(osd.err)) } if !bytes.Equal(osd.val, stval) { panic(fmt.Sprintf("Parity mismatch, expected %s got %s", stval, osd.val)) } testbase.ObjCount++ rv, stval2, _ = g.AcontrolS(0, gensio.GENSIO_CONTROL_GET, gensio.GENSIO_ACONTROL_SER_PARITY, []byte("000000"), gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for parity2: " + gensio.ErrToStr(rv)) } if !bytes.Equal(stval2, stval) { panic(fmt.Sprintf("Parity mismatch2, expected %s got %s", stval, stval2)) } osd = nil testbase.ObjCount++ osd = &SerControlDone{} osd.w = w stval = []byte("1") g.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_STOPBITS, stval, osd, nil); testbase.ObjCount++ rv = w.Wait(1, gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for stopbits: " + gensio.ErrToStr(rv)) } if osd.err != 0 { panic("Error from stopbits: " + gensio.ErrToStr(osd.err)) } if !bytes.Equal(osd.val, stval) { panic(fmt.Sprintf("Stopbits mismatch, expected %s got %s", stval, osd.val)) } testbase.ObjCount++ rv, stval2, _ = g.AcontrolS(0, gensio.GENSIO_CONTROL_GET, gensio.GENSIO_ACONTROL_SER_STOPBITS, []byte("00000000"), gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for stopbits: " + gensio.ErrToStr(rv)) } if !bytes.Equal(stval2, stval) { panic(fmt.Sprintf("Stopbits mismatch2, expected %s got %s", stval, stval2)) } osd = nil testbase.ObjCount++ osd = &SerControlDone{} osd.w = w stval = []byte("rtscts") g.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_FLOWCONTROL, stval, osd, nil); testbase.ObjCount++ rv = w.Wait(1, gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for flowcontrol: " + gensio.ErrToStr(rv)) } if osd.err != 0 { panic("Error from flowcontrol: " + gensio.ErrToStr(osd.err)) } if !bytes.Equal(osd.val, stval) { panic(fmt.Sprintf("Flowcontrol mismatch, expected %s got %s", stval, osd.val)) } testbase.ObjCount++ rv, stval2, _ = g.AcontrolS(0, gensio.GENSIO_CONTROL_GET, gensio.GENSIO_ACONTROL_SER_FLOWCONTROL, []byte("000000"), gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for flowcontrol: " + gensio.ErrToStr(rv)) } if !bytes.Equal(stval2, stval) { panic(fmt.Sprintf("Flowcontrol mismatch2, expected %s got %s", stval, stval2)) } osd = nil testbase.ObjCount++ osd = &SerControlDone{} osd.w = w stval = []byte("dsr") g.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_IFLOWCONTROL, stval, osd, nil); testbase.ObjCount++ rv = w.Wait(1, gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for iflowcontrol: " + gensio.ErrToStr(rv)) } if osd.err != 0 { panic("Error from iflowcontrol: " + gensio.ErrToStr(osd.err)) } if !bytes.Equal(osd.val, stval) { panic(fmt.Sprintf("Iflowcontrol mismatch, expected %s got %s", stval, osd.val)) } testbase.ObjCount++ rv, stval2, _ = g.AcontrolS(0, gensio.GENSIO_CONTROL_GET, gensio.GENSIO_ACONTROL_SER_IFLOWCONTROL, []byte("000000"), gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for iflowcontrol: " + gensio.ErrToStr(rv)) } if !bytes.Equal(stval2, stval) { panic(fmt.Sprintf("Iflowcontrol mismatch2, expected %s got %s", stval, stval2)) } osd = nil testbase.ObjCount++ osd = &SerControlDone{} osd.w = w stval = []byte("on") g.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_SBREAK, stval, osd, nil); testbase.ObjCount++ rv = w.Wait(1, gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for sbreak: " + gensio.ErrToStr(rv)) } if osd.err != 0 { panic("Error from sbreak: " + gensio.ErrToStr(osd.err)) } if !bytes.Equal(osd.val, stval) { panic(fmt.Sprintf("Sbreak mismatch, expected %s got %s", stval, osd.val)) } testbase.ObjCount++ rv, stval2, _ = g.AcontrolS(0, gensio.GENSIO_CONTROL_GET, gensio.GENSIO_ACONTROL_SER_SBREAK, []byte("000000"), gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for sbreak: " + gensio.ErrToStr(rv)) } if !bytes.Equal(stval2, stval) { panic(fmt.Sprintf("Sbreak mismatch2, expected %s got %s", stval, stval2)) } osd = nil testbase.ObjCount++ osd = &SerControlDone{} osd.w = w stval = []byte("off") g.Acontrol(0, gensio.GENSIO_CONTROL_SET, gensio.GENSIO_ACONTROL_SER_RTS, stval, osd, nil); testbase.ObjCount++ rv = w.Wait(1, gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for rts: " + gensio.ErrToStr(rv)) } if osd.err != 0 { panic("Error from rts: " + gensio.ErrToStr(osd.err)) } if !bytes.Equal(osd.val, stval) { panic(fmt.Sprintf("Rts mismatch, expected %s got %s", stval, osd.val)) } testbase.ObjCount++ rv, stval2, _ = g.AcontrolS(0, gensio.GENSIO_CONTROL_GET, gensio.GENSIO_ACONTROL_SER_RTS, []byte("000000"), gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for rts: " + gensio.ErrToStr(rv)) } if !bytes.Equal(stval2, stval) { panic(fmt.Sprintf("Rts mismatch2, expected %s got %s", stval, stval2)) } osd = nil // No tests for cts, dcd_dsr, ri. Those require ipmisol g.CloseS() r.CloseS() r.ShutdownS() g = nil r = nil tevh = nil h = nil w = nil o = nil testbase.TestShutdown() } gensio-3.0.0/c++/swig/go/tests/Makefile.am0000664000175000017500000000563214664224267013630 export VERBOSE = 1 SUBDIRS = testbase LOG_COMPILER = $(SHELL) $(builddir)/runtest TESTS = test_basic test_ax25 test_crypto test_serial test_mdns test_netifs test_crypto: ca/CA.key ca/CA.key: $(top_srcdir)/tests/make_keys TEST_SRCS = test_basic.go test_ax25.go test_crypto.go test_serial.go \ test_mdns.go test_netifs.go GOMOD = github.com/cminyard/go/gensio test_basic.go: $(srcdir)/srctest_basic.go testbase/testbase.go cp $(srcdir)/srctest_basic.go test_basic.go test_ax25.go: $(srcdir)/srctest_ax25.go testbase/testbase.go cp $(srcdir)/srctest_ax25.go test_ax25.go test_crypto.go: $(srcdir)/srctest_crypto.go testbase/testbase.go cp $(srcdir)/srctest_crypto.go test_crypto.go test_serial.go: $(srcdir)/srctest_serial.go testbase/testbase.go cp $(srcdir)/srctest_serial.go test_serial.go test_mdns.go: $(srcdir)/srctest_mdns.go testbase/testbase.go cp $(srcdir)/srctest_mdns.go test_mdns.go test_netifs.go: $(srcdir)/srctest_netifs.go testbase/testbase.go cp $(srcdir)/srctest_netifs.go test_netifs.go go.mod: $(TEST_SRCS) rm -f go.mod go mod init tests go mod edit -replace $(GOMOD)=../gensio go mod edit -replace testbase=./testbase go mod tidy MORE_LIBS= if BUILTIN_MDNS MORE_LIBS += $(MDNS_LIBS) endif if BUILTIN_SOUND MORE_LIBS += $(SOUND_LIBS) endif if BUILTIN_SCTP MORE_LIBS += $(LIBSCTP_LIBS) endif if BUILTIN_SSL MORE_LIBS += $(OPENSSL_LIBS) endif if BUILTIN_IPMISOL MORE_LIBS += $(OPENIPMI_LIBS) endif export CXX export CC export CGO_CXXFLAGS = $(CXXFLAGS) $(AM_CXXFLAGS) \ -I$(top_srcdir)/c++/swig/include export CGO_CPPFLAGS = $(CPPFLAGS) -I$(top_srcdir)/c++/swig/include export CGO_LDFLAGS = -L$(top_builddir)/c++/lib/.libs \ -lgensiooshcpp -lgensiocpp -lgensiomdnscpp \ -L$(top_builddir)/lib/.libs -lgensioosh -lgensio -lgensiomdns \ $(MORE_LIBS) test_basic: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx \ ../gensio/gensio_wrap.h \ test_basic.go ../gensio/gensioapi.go go.mod echo $(MORE_LIBS) go build test_basic.go test_ax25: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx \ ../gensio/gensio_wrap.h \ test_ax25.go ../gensio/gensioapi.go go.mod go build test_ax25.go test_crypto: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx \ ../gensio/gensio_wrap.h \ test_crypto.go ../gensio/gensioapi.go go.mod go build test_crypto.go test_serial: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx \ ../gensio/gensio_wrap.h \ test_serial.go ../gensio/gensioapi.go go.mod go build test_serial.go test_mdns: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx \ ../gensio/gensio_wrap.h \ test_mdns.go ../gensio/gensioapi.go go.mod go build test_mdns.go test_netifs: ../gensio/gensio.go \ ../gensio/gensio_wrap.cxx \ ../gensio/gensio_wrap.h \ test_netifs.go ../gensio/gensioapi.go go.mod go build test_netifs.go EXTRA_DIST = srctest_basic.go srctest_ax25.go srctest_crypto.go \ srctest_serial.go srctest_mdns.go srctest_netifs.go clean-local: rm -rf go.mod ca $(TESTS) $(TEST_SRCS) gensio-3.0.0/c++/swig/go/tests/srctest_ax25.go0000664000175000017500000000434314664224267014447 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only package main import ( "fmt" "github.com/cminyard/go/gensio" "testbase" ) type AuxdataEvHnd struct { testbase.EvHnd wrauxdata []string rdauxdata []string } func (adev *AuxdataEvHnd) SetWrAuxdata(auxdata []string) { adev.wrauxdata = auxdata } func (adev *AuxdataEvHnd) SetRdAuxdata(auxdata []string) { adev.rdauxdata = auxdata } func (eh *AuxdataEvHnd) Read(err int, data []byte, auxdata []string) uint64 { if err == 0 { if len(auxdata) != len(eh.rdauxdata) { panic(fmt.Sprintf("auxdata length mismatch, expected %s, got %s", len(eh.rdauxdata), len(auxdata))) } for i, v := range auxdata { if v != eh.rdauxdata[i] { panic(fmt.Sprintf("auxdata parameter mismatch on %d, expected %s, got %s", i, eh.rdauxdata[i], v)) } } } return eh.EvHnd.Read(err, data, auxdata) } func (eh *AuxdataEvHnd) WriteReady() { if eh.Data == nil || eh.Writepos >= len(eh.Data) { eh.G.SetWriteCallbackEnable(false) return } count := eh.G.Write(eh.Data[eh.Writepos:], eh.wrauxdata) eh.Writepos += int(count) if eh.Writepos >= len(eh.Data) { eh.G.SetWriteCallbackEnable(false) } } func main() { fmt.Println("Starting AX25 Go tests") o := testbase.O gensio.SetLogMask(gensio.LOG_MASK_ALL) testbase.ObjCount++ r := testbase.NewReflector(o, "tcp,localhost,0", nil) r.Startup() port := r.GetPort() testbase.ObjCount++ h := &AuxdataEvHnd{} h.Setup(o) testbase.ObjCount++ g := gensio.NewGensio("ax25(laddr=AE5KM-1,uiaddr=AE5KM-1),kiss(server=yes),tcp,localhost," + port, o, h) h.SetGensio(g) rv, _, _ := g.Control(0, false, gensio.GENSIO_CONTROL_ENABLE_OOB, []byte("1")) if rv != 0 { panic("Error enabling oob: " + gensio.ErrToStr(rv)) } g.OpenS() h.SetWrAuxdata([]string{"pid:33", "addr:0,AE5KM-1,AE5KM-1", "oob"}) h.SetRdAuxdata([]string{"oob", "addr:ax25:0,AE5KM-1,AE5KM-1", "pid:33"}) tstdata := []byte("AX25 Test String") h.SetData(tstdata) rv = h.Wait(1, gensio.NewTime(1, 0)) if rv != 0 { panic("Error waiting for data: " + gensio.ErrToStr(rv)) } g.CloseS() r.CloseS() r.ShutdownS() g = nil h = nil o = nil r = nil testbase.TestShutdown() } gensio-3.0.0/c++/swig/go/Makefile.am0000664000175000017500000000076114664224267012464 SUBDIRS = gensio examples tests # A helper to transfer info to where it needs to go and rename everything # properly. GOLANG_INSTALLDIR = /personal/git/go/gensio golang-install: cp $(srcdir)/README.rst $(GOLANG_INSTALLDIR) cp $(srcdir)/gensio/gensio.srcswigcxx \ $(GOLANG_INSTALLDIR)/gensio.swigcxx cp $(srcdir)/gensio/gensioapi.srcgo $(GOLANG_INSTALLDIR)/gensioapi.go cp $(srcdir)/gensio/go.srcmod $(GOLANG_INSTALLDIR)/go.mod cp $(srcdir)/../include/gensio_base.i $(GOLANG_INSTALLDIR) gensio-3.0.0/c++/swig/go/gensio/0000775000175000017500000000000015061121734011753 5gensio-3.0.0/c++/swig/go/gensio/gensio.srcswigcxx0000664000175000017500000002714015045153771015321 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only // This is the go-specific raw gensio wrapper %module(directors="1") gensio %go_import("reflect") // Renaming gensio_time doesn't, as the base code renames it. Just // live with it. %rename(rawOs_Funcs) gensios::Os_Funcs; %rename("raw%s") gensios::Os_Funcs::log; %rename(rawGensio) gensios::Gensio; %rename(rawAccepter) gensios::Accepter; %rename(rawEvent) gensios::Event; %rename(rawSerial_Event) gensios::Serial_Event; %rename(rawGensio_Open_Done) gensios::Gensio_Open_Done; %rename(rawGensio_Close_Done) gensios::Gensio_Close_Done; %rename(rawGensio_Control_Done) gensios::Gensio_Control_Done; %rename(rawSerial_Op_Done) gensios::Serial_Op_Done; %rename(rawSerial_Op_Sig_Done) gensios::Serial_Op_Sig_Done; %rename(rawAccepter_Event) gensios::Accepter_Event; %rename(rawAccepter_Shutdown_Done) gensios::Accepter_Shutdown_Done; %rename(rawAccepter_Enable_Done) gensios::Accepter_Enable_Done; %rename(rawWaiter) gensios::Waiter; %rename(rawWait) gensios::Waiter::wait; %rename(rawgensio_alloc) gensios::gensio_alloc; %rename(rawgensio_acc_alloc) gensios::gensio_acc_alloc; %rename(RawMDNS_Free_Done) gensios::MDNS_Free_Done; %rename(RawMDNS) gensios::MDNS; %rename(RawMDNS_Service_Event) gensios::MDNS_Service_Event; %rename(RawMDNS_Service) gensios::MDNS_Service; %rename(RawMDNS_Watch_Free_Done) gensios::MDNS_Watch_Free_Done; %rename(RawMDNS_Watch_Event) gensios::MDNS_Watch_Event; %rename(RawMDNS_Watch) gensios::MDNS_Watch; %ignore gensios::Addr::operator==; %ignore gensios::MDNS::add_service; %ignore gensios::MDNS::add_watch; %include %include %typemap(throws) gensios::gensio_error %{ std::string errstr = "gensio_error: "; errstr += $1.what(); _swig_gopanic(errstr.c_str()); %} // We use the simple uchar vector for go %ignore gensios::Gensio::write(const std::vector data, const char *const *auxdata); %ignore gensios::Gensio::read_s(std::vector &rvec, gensio_time *timeout = NULL, bool intr = false); // We do our own version of read_s that returns the new length. %ignore gensios::Gensio::read_s(SimpleUCharVector &data, gensio_time *timeout = NULL, bool intr = false); %ignore gensios::Gensio::control(int depth, bool get, unsigned int option, char *data, gensiods *datalen); %ignore gensios::Gensio::acontrol_s(int depth, bool get, unsigned int option, char *data, gensiods *datalen, gensio_time *timeout = NULL, bool intr = false); %ignore gensios::Accepter::control(int depth, bool get, unsigned int option, char *data, gensiods *datalen); // Ignore these for now. %ignore gensios::Addr::getaddr(std::vector &rvec); %ignore gensios::Addr::get_data(std::vector &rvec); %ignore gensios::Addr::getaddr(void *oaddr, gensiods *len); %ignore gensios::Addr::get_data(void *oaddr, gensiods *len); // Convert betwen byte arrays and unsigned char vectors. %typemap(gotype) (std::vector) "[]byte"; %typemap(in) (std::vector) { $1.assign((unsigned char *) $input.array, ((unsigned char *) $input.array) + $input.len); } %typemap(directorin) (std::vector) { $input.array = (void *) $1.data(); $input.len = $1.size(); $input.cap = $input.len; } %typemap(gotype) (gensios::SimpleUCharVector) "[]byte"; %typemap(in) (gensios::SimpleUCharVector) { $1.setbuf((unsigned char *) $input.array, $input.len); } %typemap(directorin) (gensios::SimpleUCharVector) { $input.array = (void *) $1.data(); $input.len = $1.size(); $input.cap = $input.len; } %typemap(gotype) (std::vector &) "*[]byte"; %typemap(directorin) (std::vector &) (_goslice_ temp) { $input = &temp; temp.array = (void *) $1.data(); temp.len = $1.size(); temp.cap = temp.len; } %typemap(directorargout) (std::vector &) { _goslice_ *tmp = (_goslice_ *) $input; $1.assign((unsigned char *) tmp->array, ((unsigned char *) tmp->array) + tmp->len); } %typemap(directorin) std::string &retval (_gostring_ temp) { $input = &temp; temp.p = (char *) $1.data(); temp.n = $1.size(); } %typemap(directorargout) std::string &retval { _gostring_ *tmp = (_gostring_ *) $input; $1.assign(tmp->p, tmp->p + tmp->n); } %typemap(directorin) gensios::Gensio *tmpg { $input = $1; gensio_ref($1->get_gensio()); } // Return data from read_s. You can't update an existing vector's // (well, you can, but it's ugly), but you can update the data. So // instead, create our own read_s function that takes the data and // returns a length, and on the go wrapper side you can slice and // return the data based on the return length. %typemap(gotype) (gensios::SimpleUCharVector &data) "[]byte"; %typemap(in) (gensios::SimpleUCharVector &data) (gensios::SimpleUCharVector temp) { $1 = &temp; $1->setbuf((unsigned char *) $input.array, $input.cap); } %extend gensios::Gensio { int read_s(SimpleUCharVector &data, gensiods *rlen, gensio_time *timeout = NULL, bool intr = false) { int rv = self->read_s(data, timeout, intr); *rlen = data.size(); return rv; } } // Data handling for control %typemap(gotype) (char *data, gensiods len) "[]byte"; %typemap(in) (char *data, gensiods len) { $1 = (char *) $input.array; $2 = $input.cap; } %typemap(gotype) (const char *data, gensiods datalen) "[]byte"; %typemap(in) (const char *data, gensiods datalen) { $1 = (char *) $input.array; $2 = $input.cap; } %extend gensios::Gensio { int control(int depth, bool get, unsigned int option, char *data, gensiods len, gensiods *rlen) { int rv = self->control(depth, get, option, data, &len); *rlen = len; return rv; } // Here so we can pass a NULL to the done parameters. You can't do // that otherwise in go. int acontrol_nodone(int depth, bool get, unsigned int option, const char *data, gensiods datalen, gensio_time *timeout = NULL) { return self->acontrol(depth, get, option, data, datalen, NULL, timeout); } int acontrol_s(int depth, bool get, unsigned int option, char *data, gensiods len, gensiods *rlen, gensio_time *timeout = NULL, bool intr = false) { int rv = self->acontrol_s(depth, get, option, data, &len, timeout, intr); *rlen = len; return rv; } void ref() { gensio_ref(self->get_gensio()); } } %extend gensios::Accepter { int control(int depth, bool get, unsigned int option, char *data, gensiods len, gensiods *rlen) { int rv = self->control(depth, get, option, data, &len); *rlen = len; return rv; } } // Handle auxdata %inline %{ #include void *gensio_alloc_ptr_array(unsigned int len) { return calloc(len, sizeof(void *)); } void gensio_set_ptr_array(void *ain, unsigned int pos, void *val) { void **a = (void **) ain; a[pos] = val; } void *gensio_get_ptr_array(void *ain, unsigned int pos) { void **a = (void **) ain; return a[pos]; } void gensio_free_ptr_array(void *ain) { void **a = (void **) ain; unsigned int i; if (!a) return; for (i = 0; a[i]; i++) { free(a[i]); } free(a); } char *gensio_uintptr_to_string(void *in) { return (char *) in; } void *gensio_string_to_uintptr(char *in) { return strdup(in); } %} %typemap(gotype) (const char * const *) "[]string"; %typemap(imtype) (const char * const *) "uintptr"; %typemap(goin) (const char * const *) { if $input == nil || len($input) == 0 { $result = 0 } else { $result = Gensio_alloc_ptr_array(uint(len($input) + 1)) defer func() { Gensio_free_ptr_array($result) }() var i uint for i = 0; i < uint(len($input)); i++ { Gensio_set_ptr_array($result, i, Gensio_string_to_uintptr($input[i])) } } } %typemap(in) (const char * const *) { $1 = (char **) $input; } %typemap(godirectorin) (const char * const *) { if ($input == 0) { $result = nil } else { var i uint for i = 0; ; i++ { var v uintptr = Gensio_get_ptr_array($input, i) if v == 0 { break } } if i == 0 { $result = nil } else { $result = make([]string, i) for i = 0; ; i++ { var v uintptr = Gensio_get_ptr_array($input, i) if v == 0 { break } $result[i] = Gensio_uintptr_to_string(v) } } } } // Make sure a nil gensio time is handled correctly %typemap(imtype) (gensio_time *) "uintptr" %typemap(goin) (gensio_time *) { if ! reflect.ValueOf($input).IsValid() { $result = 0 } else if reflect.ValueOf($input).IsNil() { $result = 0 } else { $result = $input.Swigcptr() } } %typemap(imtype) (gensios::Os_Funcs_Log_Handler *) "uintptr" %typemap(goin) (gensios::Os_Funcs_Log_Handler *) { if ! reflect.ValueOf($input).IsValid() { $result = 0 } else if reflect.ValueOf($input).IsNil() { $result = 0 } else { $result = $input.Swigcptr() } } %typemap(in) (const std::string *) (std::string temp) { if ($input) { temp.assign($input->p, $input->n); $1 = &temp; } else { $1 = NULL; } } %typemap(argout) (const std::string *) { if ($1) { *$input = Swig_AllocateString($1->data(), $1->length()); } } %typemap(goargout) (const std::string *) { } %extend gensios::Waiter { int service(gensio_time *timeout) { int err; Os_Funcs o = self->get_os_funcs(); do { err = gensio_os_funcs_service(o, timeout); if (err == GE_INTERRUPTED) continue; break; } while(true); return err; } } %extend gensios::Os_Funcs { void cleanup_mem() { gensio_cleanup_mem(*self); } } %rename("%s") gensios::MDNS::add_watch; %rename("%s") gensios::MDNS::add_service; // Take string * for the strings and do the proper translation on the // go side. %extend gensios::MDNS { MDNS_Service *add_service(int interfacenum, int ipdomain, const std::string *name, const std::string *mtype, const std::string *domain, const std::string *host, int port, const char * const *txt, struct MDNS_Service_Event *ev = NULL) { // string types from go are not nil terminated. std::string nname, nmtype, ndomain, nhost; if (name) { nname = *name; name = &nname; } if (mtype) { nmtype = *mtype; mtype = &nmtype; } if (domain) { ndomain = *domain; domain = &ndomain; } if (host) { nhost = *host; host = &nhost; } return self->add_service(interfacenum, ipdomain, name ? name->c_str() : NULL, mtype ? mtype->c_str() : NULL, domain ? domain->c_str() : NULL, host ? host->c_str() : NULL, port, txt, ev); } MDNS_Watch *add_watch(int interfacenum, int ipdomain, const std::string *name, const std::string *mtype, const std::string *domain, const std::string *host, MDNS_Watch_Event *event) { // string types from go are not nil terminated. std::string nname, nmtype, ndomain, nhost; if (name) { nname = *name; name = &nname; } if (mtype) { nmtype = *mtype; mtype = &nmtype; } if (domain) { ndomain = *domain; domain = &ndomain; } if (host) { nhost = *host; host = &nhost; } return self->add_watch(interfacenum, ipdomain, name ? name->c_str() : NULL, mtype ? mtype->c_str() : NULL, domain ? domain->c_str() : NULL, host ? host->c_str() : NULL, event); } } #define GENSIOOSH_DLL_PUBLIC // For some reason this doesn't get set in swig %include %include #define GENSIOOSHCPP_DLL_PUBLIC // For some reason this doesn't get set in swig %include %include %include int gensio_num_alloced(); gensio-3.0.0/c++/swig/go/gensio/Makefile.in0000664000175000017500000004223215061121657013747 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = c++/swig/go/gensio ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SCRIPTS = $(noinst_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ GOMOD = github.com/cminyard/go/gensio noinst_SCRIPTS = go.mod EXTRA_DIST = gensioapi.srcgo gensio.srcswigcxx go.srcmod all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/swig/go/gensio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/swig/go/gensio/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(SCRIPTS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile gensio_wrap.cxx gensio_wrap.h gensio.go: \ gensio.srcswigcxx $(top_srcdir)/c++/include/gensio \ $(top_srcdir)/c++/swig/include/gensio_base.i \ $(top_srcdir)/include/gensio/gensio_err.h \ $(top_srcdir)/include/gensio/gensio_control.h \ $(top_srcdir)/include/gensio/gensio_types.h $(SWIG) $(DEFS) -Wall -go -intgosize 64 $(GO_SWIG_FLAGS) \ -o gensio_wrap.cxx -c++ \ -I$(top_srcdir)/c++/swig/go -I$(top_srcdir)/c++/include \ -I$(top_srcdir)/include \ -I$(top_builddir)/include -I$(top_srcdir)/c++/swig/include \ $(srcdir)/gensio.srcswigcxx $(builddir)/go.mod: $(srcdir)/go.srcmod gensioapi.go gensio.go rm -f go.mod cp $(srcdir)/go.srcmod go.mod $(builddir)/gensioapi.go: $(srcdir)/gensioapi.srcgo cp $(srcdir)/gensioapi.srcgo gensioapi.go clean-local: rm -rf gensioapi.go go.mod rm -rf gensio_wrap.cxx gensio_wrap.h gensio.go # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/c++/swig/go/gensio/Makefile.am0000664000175000017500000000172614664224267013752 GOMOD = github.com/cminyard/go/gensio noinst_SCRIPTS = go.mod gensio_wrap.cxx gensio_wrap.h gensio.go: \ gensio.srcswigcxx $(top_srcdir)/c++/include/gensio \ $(top_srcdir)/c++/swig/include/gensio_base.i \ $(top_srcdir)/include/gensio/gensio_err.h \ $(top_srcdir)/include/gensio/gensio_control.h \ $(top_srcdir)/include/gensio/gensio_types.h $(SWIG) $(DEFS) -Wall -go -intgosize 64 $(GO_SWIG_FLAGS) \ -o gensio_wrap.cxx -c++ \ -I$(top_srcdir)/c++/swig/go -I$(top_srcdir)/c++/include \ -I$(top_srcdir)/include \ -I$(top_builddir)/include -I$(top_srcdir)/c++/swig/include \ $(srcdir)/gensio.srcswigcxx $(builddir)/go.mod: $(srcdir)/go.srcmod gensioapi.go gensio.go rm -f go.mod cp $(srcdir)/go.srcmod go.mod $(builddir)/gensioapi.go: $(srcdir)/gensioapi.srcgo cp $(srcdir)/gensioapi.srcgo gensioapi.go EXTRA_DIST = gensioapi.srcgo gensio.srcswigcxx go.srcmod clean-local: rm -rf gensioapi.go go.mod rm -rf gensio_wrap.cxx gensio_wrap.h gensio.go gensio-3.0.0/c++/swig/go/gensio/go.srcmod0000664000175000017500000000005614664224267013527 module github.com/cminyard/go/gensio go 1.17 gensio-3.0.0/c++/swig/go/gensio/gensioapi.srcgo0000664000175000017500000015731415045153771014733 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only // Creates a more go-friendly setup for the user. The raw interface // has issues dealing with naming, garbage collection, etc. This // wraps it all for a clean interface. package gensio import ( "fmt" "runtime" "reflect" "sync/atomic" "net" "time" ) // This is the interface used to receive logs from an OS handler. type Logger interface { // Callback to report a log to the user. level is one of LOG_xxx // defined below, log is a string. Log(level int, log string) // Internal getLoggerBase() *LoggerBase breakLinks() } // The base class for logging, this *must* be the first thing in your // structure. type LoggerBase struct { Logger rl *rawLoggerBase } // Errors are available as gensio.GE_xxx, normal error names. You can // use this function to convert the numbers to a human-readable // string. func ErrToStr(err int) string { return Err_to_string(err) } // Log levels. I couldn't find an easy way to make SWIG include these // directly. var LOG_FATAL int = int(GENSIO_LOG_FATAL) var LOG_ERR int = int(GENSIO_LOG_ERR) var LOG_WARNING int = int(GENSIO_LOG_WARNING) var LOG_INFO int = int(GENSIO_LOG_INFO) var LOG_DEBUG int = int(GENSIO_LOG_DEBUG) var LOG_MASK_ALL int = (1 << LOG_FATAL | 1 << LOG_ERR | 1 << LOG_WARNING | 1 << LOG_INFO | 1 << LOG_DEBUG) // The global log mask for the gensio library. By default only fatal // and error logs are reported. func SetLogMask(mask int) { Set_log_mask(mask) } func GetLogMask() int { return Get_log_mask() } // Convert a log level to a string. func LogLevelToStr(level int) string { return Log_level_to_str(Gensio_log_levels(level)) } // This is the OsFuncs structure you must pass around. type OsFuncs struct { RawOs_Funcs l Logger // Keep a ref around to avoid GC } // Allocate a new OsFuncs object. sig is the Unix signal to use for // inter-processor alerting in multi-threaded programs. It can be // zero for single-threaded programs, and must be zero for non-Unix // OSes. l is the function to receive log messages. It may be nil, // and no logs will be printed. func NewOsFuncs(l Logger) *OsFuncs { var o *OsFuncs if l == nil { o = &OsFuncs{NewRawOs_Funcs(-198234), l} } else { o = &OsFuncs{NewRawOs_Funcs(-198234, setupLogger(l)), l} } runtime.SetFinalizer(o, destroyer.destroy) return o } // Generate a log on the OsFuncs. func (o *OsFuncs) Log(level int, log string) { o.Rawlog(Gensio_log_levels(level), log) } // A structure used to represent time. It contains a seconds and // nanoseconds value that you may set and get with the appropriate // functions below. type Time struct { Gensio_time } func NewTime(secs int64, nsecs int) *Time { gt := &Time{NewGensio_time(secs, nsecs)} runtime.SetFinalizer(gt, destroyer.destroy) return gt } func (t *Time) SetTime(secs int64, nsecs int) { t.Gensio_time.SetSecs(secs) t.Gensio_time.SetNsecs(nsecs) } func (t *Time) GetTime() (int64, int) { return t.Gensio_time.GetSecs(), t.Gensio_time.GetNsecs() } // An interface to represent a Gensio object. type Gensio interface { // Open the given gensio and all of its children. If od is // not nil, call the OpenDone() method on that object when the // open completes. Open(od GensioOpenDone) // Open the given gensio like Open() but do not open its // children. This is useful if you are manually stacking // gensios on existing gensios with NewGensioChild(). OpenNochild(od GensioOpenDone) // Open and wait until the open completes before returning. OpenS() // Like OpenNochild, but wait until the open is complete // before returning. OpenNochildS() // For a channel-oriented gensio, allocate a new channel with // the given arguments and callback handler. It return a // Gensio object representing the new channel. AllocChannel(args []string, cb Event) Gensio // Enable the read callback for a Gensio. You must set this // to true get data from the gensio in asynchronous mode. If // you want to flow-control the read data, set it to false. SetReadCallbackEnable(val bool) // Enable the write ready callback for a Gensio. Normally you // would have this set to false. If you attempt to write to // the Gensio and it returns less than the amount you // requested to write, set this to true to know when you can // write again. SetWriteCallbackEnable(val bool) // Write the given data and auxdata to the gensio. The // meaning of auxdata is gensio-specific, see the gensio.5 man // for infor. Returns the number of bytes actually written. Write(data []byte, auxdata []string) uint64 // Close the given gensio and all of its children. If cd is // not nil, call the CloseDone() method on that object when // the close completes. Close(cd GensioCloseDone) // Like Close(), but waits until the close completes before // returning. CloseS() // Return a string type for a Gensio. depth is the number of // gensios to go down in the stack to fetch the type for. For // instance, if you have a gensio // "telnet,ssl,tcp,localhost,1234", depth 0 is "telnet", depth // 1 is "ssl", and depth 2 is "tcp". This will return an // empty string if the depth is larger than the gensio stack. GetType(depth uint) string // Returns if the gensio is a client or server IsClient() bool // Returns if the gensio is reliable (won't lose data) or not. IsReliable() bool // Returns if the gensio is a packet gensio. See the gensio.5 // man page for documentation on what this means. IsPacket() bool // Returns if the gensio is message packet gensio. See the gensio.5 // man page for documentation on what this means. IsMessage() bool // Returns if the gensio has been authenticated. IsAuthenticated() bool // Returns if the gensio's transferred data is encrypted. IsEncrypted() bool // Enable synchronous mode. See the gensio_sets_sync.3 man // page for details on what this means. SetSync() // Disable synchronous mode and set the Gensio to use normal // asynchronous mode. ClearSync() // Read data synchronously from the Gensio. This will wait // for data on the Gensio. See SetSync() for details; this is // somewhat dangerous to use if not done carefully. If // timeout is not nil, wait at most the given amount of time. // If intr is true, return immediately if the thread receives // a signal. The first return value is either 0 for data // being read, GE_TIMEDOUT if the operation timed out, and // GE_INTERRUPTED if a signal was received. The second return // value is the data. ReadS(data []byte, timeout *Time, intr bool) (int, []byte) // Write data to the gensio and wait for the write to // complete. See SetSync() for details; this is somewhat // dangerous to use if not done carefully. If timeout is not // nil, wait at most the given amount of time. If intr is // true, return immediately if the thread receives a signal. // The first return value is either 0 for data being written, // GE_TIMEDOUT if the operation timed out and no data was // written, and GE_INTERRUPTED if a signal was received and no // data was written. The second return value is the number of // bytes actually written; it may be less than the number of // bytes if the operation timed out or was signalled and only // a partial write occurred. WriteS(data []byte, timeout *Time, intr bool) (int, uint64) // Control operations. See the gensio_control.3 man page for // details. The depth, get, and option values are per the man // page. The data field is passed into the control and must // be large enough to hold the expected result that will be // returned. The first return value is an error, this will // not raise a gensio_error() when it gets an error return. // The second return value is the result data, using the same // data as passed in. The third return value is the full // amount of data that would be required to hold the data. It // may be larger than cap(data); you can use this to determine // if the data is truncated. Control(depth int, get bool, option uint, data []byte) (int, []byte, uint64) Acontrol(depth int, get bool, option uint, data []byte, cd GensioControlDone, timeout *Time) int AcontrolS(depth int, get bool, option uint, data []byte, timeout *Time) (int, []byte, uint64) // Set/change the event handler for a Gensio. Useful if you // receive a Gensio from a NewConnection or NewChannel // callback. SetEvent(e Event) // Internals getRawGensio() RawGensio } // Callback events for a Gensio. type Event interface { // Read data is ready on the Gensio. err will be non-zero if // an error has occurred, in this case the data and auxdata is // ignored an you should return 0. Otherwise data is passed // in. auxdata depends on the specific gensio, see the // gensio.5 main page for details. You should return the // number of bytes that you actually process. Note that if // you do not disable read event, if you are passed an error // or return less than the number of bytes you processed, this // will be called immedately. Read(err int, data []byte, auxdata []string) uint64 // Called when data can be written on the Gensio. WriteReady() // Called when a new channel is created by the remote end on a // channel-oriented Gensio. NewChannel(new_chan Gensio, auxdata []string) int // Called when a break is sent from the remote end on a telnet // connection. SendBreak() // Authorization has begun on the gensio, only called for // server-side gensios. See the gensio_event.3 for details. AuthBegin() int // Certificate verification is about to start on the gensio. // This is primarily to set any information required to verify // a certificate, like the CA. See the gensio_event.3 for // details. PrecertVerify() int // Certificate verification has finished on the gensio. If // the certificate was valid, error will be zero and string // will be empty. Otherwise an error is given. Note that // errstr is *not* a gensio error, it is information from the // validation process. See the gensio_event.3 for details. PostcertVerify(err int, errstr string) int // The gensio is requesting tha the given password be // verified. See the gensio_event.3 for details. PasswordVerify(val string) int // The other end of a connection has requested a password. // You should return the proper return value and a string with // the password, which may not exceed maxlen bytes. See the // gensio_event.3 for details. RequestPassword(maxlen uint64) (int, string) // The gensio is requesting tha the given 2-factor // authentication data be verified. See the gensio_event.3 // for details. Verify2fa(val []byte) int // The other end of a connection has requested a 2-factor // authentication. You should return the proper return value // and a data for the authentication token. See the // gensio_event.3 for details. Request2fa() (int, []byte) // An error occurred parsing parameters Parmlog(s string) // A window size event WinSize(height uint, width uint) // A general gensio log Log(level Gensio_log_levels, log string) int // An event in the user event range, this will only happen for // custom gensios. UserEvent(event int, err int, userdata *[]byte, auxdata []string) int Modemstate(state uint) ModemstateMask(state uint) Linestate(state uint) LinestateMask(state uint) Signature(data []byte) FlowState(state bool) Sync() Baud(baud uint) Datasize(size uint) Parity(par uint) Stopbits(bits uint) Flowcontrol(flow uint) Iflowcontrol(flow uint) Sbreak(sbreak uint) Dtr(dtr uint) Rts(rts uint) Flush(val uint) // Internal methods, don't mess with these. getEventBase() *EventBase } // This type must be the first entry in your event-handling callback // object; it allows the event handler to be passed NewGensio() or // whatnot. type EventBase struct { Event e *raweventBase } // Interface for handling an Open() operation completing. type GensioOpenDone interface { OpenDone(err int) // Internal, do not use getGensioOpenDoneBase() *GensioOpenDoneBase } // This type must be the first entry in your event-handling callback // for an Open() operation. type GensioOpenDoneBase struct { GensioOpenDone od *rawGensioOpenDoneBase } // Interface for handling a Close() operation completing. type GensioCloseDone interface { CloseDone() // Internal, do not use getGensioCloseDoneBase() *GensioCloseDoneBase } // This type must be the first entry in your event-handling callback // for a Close() operation. type GensioCloseDoneBase struct { GensioCloseDone cd *rawGensioCloseDoneBase } // Interface for handling a Control() operation completing. type GensioControlDone interface { ControlDone(err int, data []byte) // Internal, do not use getGensioControlDoneBase() *GensioControlDoneBase } // This type must be the first entry in your event-handling callback // for a Control() operation. type GensioControlDoneBase struct { GensioControlDone cd *rawGensioControlDoneBase } // Allocate a new Gensio. See the str_to_gensio.3 man page for // details. Note that you may pass in a nil cb, but the program will // crash if an event comes in. func NewGensio(str string, o *OsFuncs, cb Event) Gensio { if cb == nil { rawg := Rawgensio_alloc(str, o) return allocGensioObj(rawg, nil) } else { rawcb := setupEvent(cb) rawg := Rawgensio_alloc(str, o, rawcb) return allocGensioObj(rawg, rawcb) } } // Like NewGensio, but allocate the Gensio on top of the given child // Gensio in a stack. func NewGensioChild(child Gensio, str string, o *OsFuncs, cb Event) Gensio { var rawcb RawEvent if cb == nil { rawcb = nil } else { rawcb = setupEvent(cb) } rawg := Rawgensio_alloc(child.getRawGensio(), str, o, rawcb) return allocGensioObj(rawg, rawcb) } // An event handler for events from an Accepter type AccepterEvent interface { // A new connection has come in on the Accepter. NewConnection(g Gensio) // Something went wrong in the accepter processing that could // not be returned as an error. Log(level int, log string) // The following are just like the ones in the Event // interface, except they are passed a "dummy" gensio object. // You can use this object to fetch authentication information // that you need, but you *must not* keep it around or do // anything else but authentication Control() fetches to get // the data you need. AuthBegin(g Gensio) int PrecertVerify(g Gensio) int PostcertVerify(g Gensio, err int, errstr string) int PasswordVerify(g Gensio, val string) int RequestPassword(g Gensio, maxlen uint64) (int, string) Verify2fa(g Gensio, val []byte) int Request2fa(g Gensio) (int, []byte) Parmlog(s string) // Internal methods, don't mess with these. getAccepterEventBase() *AccepterEventBase } // This type must be the first entry in your event-handling callback // for an Accepter event handler. type AccepterEventBase struct { AccepterEvent e *rawAccepterEventBase } // Interface for handling a Shutdown() operation completing. type AccepterShutdownDone interface { AccShutdownDone() // Internal, do not use getAccepterShutdownDoneBase() *AccepterShutdownDoneBase } // This type must be the first entry in your event-handling callback // for a Shutdown() operation. type AccepterShutdownDoneBase struct { AccepterShutdownDone od *rawAccepterShutdownDoneBase } // Interface for handling an Enable() operation completing. type AccepterEnableDone interface { AccEnableDone() // Internal, do not use getAccepterEnableDoneBase() *AccepterEnableDoneBase } // This type must be the first entry in your event-handling callback // for an Enable() operation. type AccepterEnableDoneBase struct { AccepterEnableDone od *rawAccepterEnableDoneBase } // The Accepter object, used to receive connections. type Accepter interface { // Start receiving connections on an Accepter. Startup() // Shut down a connector's operation. If done is not nil, the // AccShutdownDone() method on the given object will be // called when the shutdown completes. Shutdown(done AccepterShutdownDone) // Like Shutdown(), but wait until the shutdown is complete // before returning. ShutdownS() // Enable/disable receiving new connections on the Accepter. // If done is not nil, the AccEnableDone() method on the given // object will be called when the enable/disable operation // completes SetCallbackEnable(val bool, done AccepterEnableDone) // Like SetCallbackEnable, but this will wait until the // operation completes before returning. SetCallbackEnableS(val bool) // Control operations. See the gensio_acc_control.3 man page // for details. See the Control() method on Gensio for // details on how this works. Control(depth int, get bool, option uint, data []byte) (int, []byte, uint64) // Turn on synchronous operation on the gensio. See the // gensio_acc_set_sync.3 man page for details. SetSync() // Do an asynchronous accept on a gensio. See the // gensio_acc_set_sync.3 man page for details. If timeout is // not nil, wait at most the given time for the operation to // complete. If intr is true, return if the thread receives a // signal. This returns 0 in the first return value if a // gensio is accepted and returned in the second return value. // Othersize the first return value will be GE_TIMEDOUT if the // operation timed out or GE_INTERRUPTED if a signal was // received. AcceptS(timeout *Time, intr bool) (int, Gensio) // Create a gensio. This is primarily for UDP; it will create // a connection to the remote end coming from the UDP socket. // See the gensio_acc_str_to_gensio.3 man page for details. StrToGensio(str string, cb Event) Gensio // Return a string type for an Accepter. depth is the number of // accepters to go down in the stack to fetch the type for. For // instance, if you have an accepter // "telnet,ssl,tcp,1234", depth 0 is "telnet", depth // 1 is "ssl", and depth 2 is "tcp". This will return an // empty string if the depth is larger than the gensio stack. GetType(depth uint) string // Returns if gensios from this accepter are reliable (won't // lose data) or not. IsReliable() bool // Returns if gensios from this accepter are packet. IsPacket() bool // Returns if gensios from this accepter are message-oriented. IsMessage() bool // Return the "port" for this Accepter. What this is depends // on the particular Accepter. For TCP one, it will be the // port number. See the gensio.5 man page for details. GetPort() string getRawAccepter() RawAccepter } // Allocate a new Accepter. See the str_to_gensio_accepter.3 man page // for details. Note that you may pass in a nil cb, but the program // will crash if an event comes in. func NewAccepter(str string, o *OsFuncs, cb AccepterEvent) Accepter { if cb == nil { Rawa := Rawgensio_acc_alloc(str, o.RawOs_Funcs) return allocaccepterObj(Rawa, nil) } else { Rawa := Rawgensio_acc_alloc(str, o.RawOs_Funcs, setupAccepterEvent(cb)) return allocaccepterObj(Rawa, cb) } } // Like NewAccepter, but allocate the Accepter on top of the given child // Accepter in a stack. func NewAccepterChild(child Accepter, str string, o *OsFuncs, cb AccepterEvent) Accepter { if cb == nil { rawg := Rawgensio_acc_alloc(child.getRawAccepter(), str, o.RawOs_Funcs, nil) return allocaccepterObj(rawg, nil) } else { rawg := Rawgensio_acc_alloc(child.getRawAccepter(), str, o.RawOs_Funcs, setupAccepterEvent(cb)) return allocaccepterObj(rawg, cb) } } // Type used for waiting for things to complete. Note that this has a // Wake() function to send a wakeup, and a // Wait(nrwakes uint, timeout *Time) to wait for the given number of // wakeups. type Waiter struct { o *OsFuncs RawWaiter } // Allocate a new Waiter object. func NewWaiter(o *OsFuncs) *Waiter { w := &Waiter{o, NewRawWaiter(o)} runtime.SetFinalizer(w, destroyer.destroy) return w } // Interface for handling an MDNS Free() operation completing. type MDNSFreeDone interface { MDNSFreeDone() // Internal, do not use getMDNSFreeDoneBase() *MDNSFreeDoneBase } // This type must be the first entry in your event-handling callback // for an MDNS Free() operation. type MDNSFreeDoneBase struct { MDNSFreeDone od *rawMDNSFreeDoneBase } // Interface for handling an MDNS Watch Free() operation completing. type MDNSWatchFreeDone interface { MDNSWatchFreeDone() // Internal, do not use getMDNSWatchFreeDoneBase() *MDNSWatchFreeDoneBase } // This type must be the first entry in your event-handling callback // for an MDNS Watch Free() operation. type MDNSWatchFreeDoneBase struct { MDNSWatchFreeDone od *rawMDNSWatchFreeDoneBase } // ev values for the Event callback below. I couldn't find an easy // way to make SWIG include these. var MDNS_SERVICE_ERROR = int(GENSIO_MDNS_SERVICE_ERROR) var MDNS_SERVICE_READY int = int(GENSIO_MDNS_SERVICE_READY) var MDNS_SERVICE_READY_NEW_NAME = int(GENSIO_MDNS_SERVICE_READY_NEW_NAME) var MDNS_SERVICE_REMOVED int = int(GENSIO_MDNS_SERVICE_REMOVED) // An event handler for MDNS Service events. See the gensio_mdns.3 man // page for details. type MDNSServiceEvent interface { Event(ev int, info string) // Internal, do not use getMDNSServiceEventBase() *MDNSServiceEventBase } // This type must be the first entry in your event-handling callback // for an MDNS event handler. type MDNSServiceEventBase struct { MDNSServiceEvent od *rawMDNSServiceEventBase } // state values for the Event callback below. I couldn't find an easy // way to make SWIG include these. var MDNS_WATCH_NEW_DATA int = int(GENSIO_MDNS_WATCH_NEW_DATA) var MDNS_WATCH_DATA_GONE int = int(GENSIO_MDNS_WATCH_DATA_GONE) var MDNS_WATCH_ALL_FOR_NOW int = int(GENSIO_MDNS_WATCH_ALL_FOR_NOW) // An event handler for MDNS Watch events. See the gensio_mdns.3 man // page for details. type MDNSWatchEvent interface { Event(state int, interfacenum int, ipdomain int, name string, mtype string, domain string, host string, addr Addr, txt []string) // Internal, do not use getMDNSWatchEventBase() *MDNSWatchEventBase } // This type must be the first entry in your event-handling callback // for an MDNS event handler. type MDNSWatchEventBase struct { MDNSWatchEvent od *rawMDNSWatchEventBase } // An MDNS object, see gensio_mdns.3 for details. type MDNS interface { // This is really: // AddService(interfacenum int, ipdomain int, name string, // mtype string, domain string, host string, port int, // txt []string[, evh MDNSServiceEvent]) AddService(interfacenum int, ipdomain int, a ...interface{}) MDNSService // This is really: // AddWatch(interfacenum int, ipdomain int, name string, // mtype string, domain string, host string, // txt []string, evh MDNSWatchEvent) MDNSWatch AddWatch(interfacenum int, ipdomain int, a ...interface{}) MDNSWatch // Free the MDNS. When the free completes (and all watches // and services associated with the MDNS are also freed), if // fh is not nil, call the MDNSFreeDone() method on fh. Free(fh MDNSFreeDone) } // Allocate a new MDNS object func NewMDNS(o *OsFuncs) MDNS { rawm := NewRawMDNS(o) m := &mDNSO{rawm} runtime.SetFinalizer(m, destroyer.destroy) return m } // An MDNS service object, allocated from AddService() in an MDNS // object. type MDNSService interface { // Free the service and stop advertising it. No free done // handler is needed. there are no callbacks associated with a // service. Free() } // An MDNS watch object, allocated from AddWatch() in an MDNS // object. type MDNSWatch interface { // Free the MDNS watch. When the free completes, if wfh is // not nil, call the MDNSWatchFreeDone() method on wfh. Free(wfh MDNSWatchFreeDone) } // Return network interface information for the system. type NetIfs interface { GetNumIfs() uint GetName(i uint) string IsUp(i uint) bool IsLoopback(i uint) bool IsMulticast(i uint) bool GetIfIndex(i uint) uint GetNumAddrs(i uint) uint GetAddrNetbits(i uint, j uint) uint GetAddrFamily(i uint, j uint) uint GetAddrStr(i uint, j uint) string } /////////////////////////////////////////////////////////////////////////// // Everything below here is internals // Log output whenever an object is GC-ed var Debug bool // A count of the number of objects GC-ed var GCCount uint32 = 0 type destroyer interface { destroy() } type rawLoggerBase struct { Os_Funcs_Log_Handler subl Logger } func (l *LoggerBase) breakLinks() { l.rl.subl = nil } func (l *LoggerBase) destroy() { if Debug { fmt.Println("Destroy Logger") } atomic.AddUint32(&GCCount, 1) DeleteOs_Funcs_Log_Handler(l.rl) } func (e *LoggerBase) getLoggerBase() *LoggerBase { return e } func setupLogger(l Logger) Os_Funcs_Log_Handler { lb := l.getLoggerBase() lb.rl = &rawLoggerBase{} lb.rl.subl = l lb.rl.Os_Funcs_Log_Handler = NewDirectorOs_Funcs_Log_Handler(lb.rl) runtime.SetFinalizer(lb, destroyer.destroy) return lb.rl } func (l *rawLoggerBase) Log(level Gensio_log_levels, log string) { l.subl.Log(int(level), log) } func (l *LoggerBase) Log(level int, log string) { } func (o *OsFuncs) destroy() { if Debug { fmt.Println("Destroy OsFuncs") } atomic.AddUint32(&GCCount, 1) if o.l != nil { o.l.breakLinks() o.l = nil } DeleteRawOs_Funcs(o) } func (gt *Time) destroy() { if Debug { fmt.Println("Destroy gensio time") } atomic.AddUint32(&GCCount, 1) DeleteGensio_time(gt) } type gensioO struct { g RawGensio e RawEvent } func (g *gensioO) destroy() { if g.g != nil { DeleteRawGensio(g.g) } if Debug { fmt.Println("Gensio destroy") } atomic.AddUint32(&GCCount, 1) } func (g *gensioO) getRawGensio() RawGensio { return g.g } type raweventBase struct { RawEvent sube Event } func (e *EventBase) getEventBase() *EventBase { return e } func (e *EventBase) NewChannel(new_channel Gensio, auxdata []string) int { return GE_NOTSUP } func (e *EventBase) SendBreak() { } func (e *EventBase) AuthBegin() int { return GE_NOTSUP } func (e *EventBase) PrecertVerify() int { return GE_NOTSUP } func (e *EventBase) PostcertVerify(err int, errstr string) int { return GE_NOTSUP } func (e *EventBase) PasswordVerify(val string) int { return GE_NOTSUP } func (e *EventBase) RequestPassword(maxsize uint64) (int, string) { return GE_NOTSUP, "" } func (e *EventBase) Verify2fa(val []byte) int { return GE_NOTSUP } func (e *EventBase) Request2fa() (int, []byte) { return GE_NOTSUP, nil } func (e *EventBase) Parmlog(s string) { } func (e *EventBase) WinSize(height uint, width uint) { } func (e *EventBase) Log(level Gensio_log_levels, log string) int { return GE_NOTSUP } func (e *EventBase) UserEvent(event int, err int, userdata *[]byte, auxdata []string) int { return GE_NOTSUP } func (e *EventBase) Modemstate(state uint) { } func (e *EventBase) ModemstateMask(state uint) { } func (e *EventBase) Linestate(state uint) { } func (e *EventBase) LinestateMask(state uint) { } func (e *EventBase) Signature(data []byte) { } func (e *EventBase) FlowState(state bool) { } func (e *EventBase) Sync() { } func (e *EventBase) Baud(baud uint) { } func (e *EventBase) Datasize(size uint) { } func (e *EventBase) Parity(par uint) { } func (e *EventBase) Stopbits(bits uint) { } func (e *EventBase) Flowcontrol(flow uint) { } func (e *EventBase) Iflowcontrol(flow uint) { } func (e *EventBase) Sbreak(sbreak uint) { } func (e *EventBase) Dtr(dtr uint) { } func (e *EventBase) Rts(rts uint) { } func (e *EventBase) Flush(val uint) { } func (e *EventBase) destroy() { if e.e != nil { DeleteRawEvent(e.e) } if Debug { fmt.Println("Event destroy") } atomic.AddUint32(&GCCount, 1) } func (e *raweventBase) Read(err int, data []byte, auxdata []string) uint64 { return e.sube.Read(err, data, auxdata) } func (e *raweventBase) Write_ready() { e.sube.WriteReady() } func (e *raweventBase) New_channel(new_channel RawGensio, auxdata []string) int { g := allocGensioObj(new_channel, nil) return e.sube.NewChannel(g, auxdata) } func (e *raweventBase) Send_break() { e.sube.SendBreak() } func (e *raweventBase) Auth_begin() int { return e.sube.AuthBegin() } func (e *raweventBase) Precert_verify() int { return e.sube.PrecertVerify() } func (e *raweventBase) Postcert_verify(err int, errstr string) int { return e.sube.PostcertVerify(err, errstr) } func (e *raweventBase) Password_verify(val string) int { return e.sube.PasswordVerify(val) } func (e *raweventBase) Request_password(maxsize uint64, val *string) int { rv, password := e.sube.RequestPassword(maxsize) *val = password return rv } func (e *raweventBase) Verify_2fa(val []byte) int { return e.sube.Verify2fa(val) } func (e *raweventBase) Request_2fa(val *[]byte) int { rv, ival := e.sube.Request2fa() *val = ival return rv } func (e *raweventBase) Parmlog(s string) { e.sube.Parmlog(s) } func (e *raweventBase) Win_size(height uint, width uint) { e.sube.WinSize(height, width) } func (e *raweventBase) Log(level Gensio_log_levels, s string) int { return e.sube.Log(level, s) } func (e *raweventBase) Modemstate(state uint) { e.sube.Modemstate(state) } func (e *raweventBase) Modemstate_mask(state uint) { e.sube.ModemstateMask(state) } func (e *raweventBase) Linestate(state uint) { e.sube.Linestate(state) } func (e *raweventBase) LinestateMask(state uint) { e.sube.LinestateMask(state) } func (e *raweventBase) Signature(data []byte) { e.sube.Signature(data) } func (e *raweventBase) FlowState(state bool) { e.sube.FlowState(state) } func (e *raweventBase) Sync() { e.sube.Sync() } func (e *raweventBase) Baud(baud uint) { e.sube.Baud(baud) } func (e *raweventBase) Datasize(size uint) { e.sube.Datasize(size) } func (e *raweventBase) Parity(par uint) { e.sube.Parity(par) } func (e *raweventBase) Stopbits(bits uint) { e.sube.Stopbits(bits) } func (e *raweventBase) Flowcontrol(flow uint) { e.sube.Flowcontrol(flow) } func (e *raweventBase) Iflowcontrol(flow uint) { e.sube.Iflowcontrol(flow) } func (e *raweventBase) Sbreak(sbreak uint) { e.sube.Sbreak(sbreak) } func (e *raweventBase) Dtr(dtr uint) { e.sube.Dtr(dtr) } func (e *raweventBase) Rts(rts uint) { e.sube.Rts(rts) } func (e *raweventBase) Flush(val uint) { e.sube.Flush(val) } func (e *raweventBase) User_event(event int, err int, userdata *[]byte, auxdata []string) int { return e.sube.UserEvent(event, err, userdata, auxdata) } func (e *raweventBase) Freed() { // The gensio associated with this is gone, break the loop so // the EventBase object will be GC-ed. e.sube = nil } func setupEvent(e Event) RawEvent { eb := e.getEventBase() eb.e = &raweventBase{} eb.e.sube = e eb.e.RawEvent = NewDirectorEvent(eb.e) runtime.SetFinalizer(eb, destroyer.destroy) return eb.e } type rawGensioOpenDoneBase struct { RawGensio_Open_Done subd GensioOpenDone } func (od *GensioOpenDoneBase) getGensioOpenDoneBase() *GensioOpenDoneBase { return od } func (od *rawGensioOpenDoneBase) Open_done(err int) { od.subd.OpenDone(err) od.subd = nil // Break the circular reference } func setupGensioOpenDone(od GensioOpenDone) RawGensio_Open_Done { odb := od.getGensioOpenDoneBase() odb.od = &rawGensioOpenDoneBase{} odb.od.subd = od odb.od.RawGensio_Open_Done = NewDirectorGensio_Open_Done(odb.od) runtime.SetFinalizer(odb, destroyer.destroy) return odb.od } func (od *GensioOpenDoneBase) destroy() { DeleteRawGensio_Open_Done(od.od) if Debug { fmt.Println("Open Done destroy") } atomic.AddUint32(&GCCount, 1) } type rawGensioCloseDoneBase struct { RawGensio_Close_Done subd GensioCloseDone } func (cd *GensioCloseDoneBase) getGensioCloseDoneBase() *GensioCloseDoneBase { return cd } func (cd *rawGensioCloseDoneBase) Close_done() { cd.subd.CloseDone() cd.subd = nil // Break the circular reference } func setupGensioCloseDone(cd GensioCloseDone) RawGensio_Close_Done { cdb := cd.getGensioCloseDoneBase() cdb.cd = &rawGensioCloseDoneBase{} cdb.cd.subd = cd cdb.cd.RawGensio_Close_Done = NewDirectorGensio_Close_Done(cdb.cd) runtime.SetFinalizer(cdb, destroyer.destroy) return cdb.cd } func (cd *GensioCloseDoneBase) destroy() { DeleteRawGensio_Close_Done(cd.cd) if Debug { fmt.Println("Close Done destroy") } atomic.AddUint32(&GCCount, 1) } type rawGensioControlDoneBase struct { RawGensio_Control_Done subd GensioControlDone } func (cd *GensioControlDoneBase) getGensioControlDoneBase() *GensioControlDoneBase { return cd } func (cd *rawGensioControlDoneBase) Control_done(err int, data []byte) { ndata := make([]byte, len(data)) copy(ndata, data) cd.subd.ControlDone(err, ndata) cd.subd = nil // Break the circular reference } func setupGensioControlDone(cd GensioControlDone) RawGensio_Control_Done { cdb := cd.getGensioControlDoneBase() cdb.cd = &rawGensioControlDoneBase{} cdb.cd.subd = cd cdb.cd.RawGensio_Control_Done = NewDirectorGensio_Control_Done(cdb.cd) runtime.SetFinalizer(cdb, destroyer.destroy) return cdb.cd } func (cd *GensioControlDoneBase) destroy() { DeleteRawGensio_Control_Done(cd.cd) if Debug { fmt.Println("Control Done destroy") } atomic.AddUint32(&GCCount, 1) } func allocGensioObj(rawg RawGensio, cb RawEvent) Gensio { var g Gensio g = &gensioO{rawg, cb} runtime.SetFinalizer(g, destroyer.destroy) return g } func (g *gensioO) Open(od GensioOpenDone) { g.g.Open(setupGensioOpenDone(od)) } func (g *gensioO) OpenNochild(od GensioOpenDone) { g.g.Open_nochild(setupGensioOpenDone(od)) } func (g *gensioO) OpenS() { g.g.Open_s() } func (g *gensioO) OpenNochildS() { g.g.Open_nochild_s() } func (g *gensioO) AllocChannel(args []string, cb Event) Gensio { var rawcb RawEvent if cb == nil { rawcb = nil } else { rawcb = setupEvent(cb) } rawg := g.g.Alloc_channel(args, rawcb) return allocGensioObj(rawg, rawcb) } func (g *gensioO) SetReadCallbackEnable(val bool) { g.g.Set_read_callback_enable(val) } func (g *gensioO) SetWriteCallbackEnable(val bool) { g.g.Set_write_callback_enable(val) } func (g *gensioO) Write(data []byte, auxdata []string) uint64 { return g.g.Write(data, auxdata) } func (g *gensioO) Close(cd GensioCloseDone) { if cd == nil { g.g.Close() } else { g.g.Close(setupGensioCloseDone(cd)) } } func (g *gensioO) CloseS() { g.g.Close_s() } func (g *gensioO) GetType(depth uint) string { return g.g.Get_type(depth) } func (g *gensioO) IsClient() bool { return g.g.Is_client() } func (g *gensioO) IsReliable() bool { return g.g.Is_reliable() } func (g *gensioO) IsPacket() bool { return g.g.Is_packet() } func (g *gensioO) IsAuthenticated() bool { return g.g.Is_authenticated() } func (g *gensioO) IsEncrypted() bool { return g.g.Is_encrypted() } func (g *gensioO) IsMessage() bool { return g.g.Is_message() } func (g *gensioO) SetSync() { g.g.Set_sync() } func (g *gensioO) ClearSync() { g.g.Clear_sync() } // Read_s has some special handling, see Rawi for details. func (g *gensioO) ReadS(data []byte, timeout *Time, intr bool) (int, []byte) { var len uint64 rv := g.g.Read_s(data, &len, timeout, intr) return rv, data[:len] } func (g *gensioO) WriteS(data []byte, timeout *Time, intr bool) (int, uint64) { count := uint64(0) rv := g.g.Write_s(&count, data, timeout, intr) return rv, count } func (g *gensioO) Control(depth int, get bool, option uint, data []byte) (int, []byte, uint64) { var len uint64 var actlen uint64 rv := g.g.Control(depth, get, option, data, &len) actlen = len if actlen > uint64(cap(data)) { actlen = uint64(cap(data)) } return rv, data[:actlen], len } func (g *gensioO) Acontrol(depth int, get bool, option uint, data []byte, cd GensioControlDone, timeout *Time) int { if cd == nil { return g.g.Acontrol_nodone(depth, get, option, data, timeout) } else { return g.g.Acontrol(depth, get, option, data, setupGensioControlDone(cd), timeout) } } func (g *gensioO) AcontrolS(depth int, get bool, option uint, data []byte, timeout *Time) (int, []byte, uint64) { var len uint64 var actlen uint64 rv := g.g.Acontrol_s(depth, get, option, data, &len, timeout) actlen = len if actlen > uint64(cap(data)) { actlen = uint64(cap(data)) } return rv, data[:actlen], len } func (g *gensioO) SetEvent(e Event) { // Break the link so it will GC if reflect.ValueOf(g.e).IsValid() { olde := g.e.(*raweventBase) olde.sube = nil } var rawcb RawEvent if e == nil { rawcb = nil } else { rawcb = setupEvent(e) } g.e = rawcb g.g.Set_event_handler(rawcb) } type rawAccepterEventBase struct { RawAccepter_Event sube AccepterEvent } func (e *AccepterEventBase) getAccepterEventBase() *AccepterEventBase { return e } // The user must implement NewConnection func (e *AccepterEventBase) Log(level int, log string) { } func (e *AccepterEventBase) AuthBegin(g Gensio) int { return GE_NOTSUP } func (e *AccepterEventBase) PrecertVerify(g Gensio) int { return GE_NOTSUP } func (e *AccepterEventBase) PostcertVerify(g Gensio, err int, errstr string) int { return GE_NOTSUP } func (e *AccepterEventBase) PasswordVerify(g Gensio, val string) int { return GE_NOTSUP } func (e *AccepterEventBase) RequestPassword(g Gensio, maxsize uint64) (int, string) { return GE_NOTSUP, "" } func (e *AccepterEventBase) Verify2fa(g Gensio, val []byte) int { return GE_NOTSUP } func (e *AccepterEventBase) Request2fa(g Gensio) (int, []byte) { return GE_NOTSUP, nil } func (e *AccepterEventBase) Parmlog(s string) { } func (e *AccepterEventBase) destroy() { DeleteRawAccepter_Event(e.e) if Debug { fmt.Println("Accepter Event destroy") } atomic.AddUint32(&GCCount, 1) } func (e *rawAccepterEventBase) New_connection(newg RawGensio) { g := allocGensioObj(newg, nil) e.sube.NewConnection(g) } func (e *rawAccepterEventBase) Log(level Gensio_log_levels, log string) { e.sube.Log(int(level), log) } func (e *rawAccepterEventBase) Auth_begin(rawg RawGensio) int { g := &gensioO{rawg, nil} rv := e.sube.AuthBegin(g) g.g = nil DeleteRawGensio(rawg) return rv } func (e *rawAccepterEventBase) Precert_verify(rawg RawGensio) int { g := &gensioO{rawg, nil} rv := e.sube.PrecertVerify(g) g.g = nil DeleteRawGensio(rawg) return rv } func (e *rawAccepterEventBase) Postcert_verify(rawg RawGensio, err int, errstr string) int { g := &gensioO{rawg, nil} rv := e.sube.PostcertVerify(g, err, errstr) g.g = nil DeleteRawGensio(rawg) return rv } func (e *rawAccepterEventBase) Password_verify(rawg RawGensio, val string) int { g := &gensioO{rawg, nil} rv := e.sube.PasswordVerify(g, val) g.g = nil DeleteRawGensio(rawg) return rv } func (e *rawAccepterEventBase) Request_password(rawg RawGensio, maxsize uint64, val *string) int { g := &gensioO{rawg, nil} rv, password := e.sube.RequestPassword(g, maxsize) *val = password g.g = nil DeleteRawGensio(rawg) return rv } func (e *rawAccepterEventBase) Verify_2fa(rawg RawGensio, val []byte) int { g := &gensioO{rawg, nil} rv := e.sube.Verify2fa(g, val) g.g = nil DeleteRawGensio(rawg) return rv } func (e *rawAccepterEventBase) Request_2fa(rawg RawGensio, val *[]byte) int { g := &gensioO{rawg, nil} rv, ival := e.sube.Request2fa(g) *val = ival g.g = nil DeleteRawGensio(rawg) return rv } func (e *rawAccepterEventBase) Parmlog(s string) { e.sube.Parmlog(s) } func (e *rawAccepterEventBase) Freed() { // The Accepter associated with this is gone, break the loop so // the rawAccepterEventBase object will be GC-ed. e.sube = nil } func setupAccepterEvent(e AccepterEvent) RawAccepter_Event { eb := e.getAccepterEventBase() eb.e = &rawAccepterEventBase{} eb.e.sube = e eb.e.RawAccepter_Event = NewDirectorAccepter_Event(eb.e) runtime.SetFinalizer(eb, destroyer.destroy) return eb.e } type rawAccepterShutdownDoneBase struct { RawAccepter_Shutdown_Done subd AccepterShutdownDone } func (od *AccepterShutdownDoneBase) getAccepterShutdownDoneBase() *AccepterShutdownDoneBase { return od } func (od *rawAccepterShutdownDoneBase) Shutdown_done() { od.subd.AccShutdownDone() od.subd = nil // Break the circular reference } func setupAccepterShutdownDone(od AccepterShutdownDone) RawAccepter_Shutdown_Done { odb := od.getAccepterShutdownDoneBase() odb.od = &rawAccepterShutdownDoneBase{} odb.od.subd = od odb.od.RawAccepter_Shutdown_Done = NewDirectorAccepter_Shutdown_Done(odb.od) runtime.SetFinalizer(odb, destroyer.destroy) return odb.od } func (od *AccepterShutdownDoneBase) destroy() { DeleteRawAccepter_Shutdown_Done(od.od) if Debug { fmt.Println("Accepter Shutdown Done destroy") } atomic.AddUint32(&GCCount, 1) } type rawAccepterEnableDoneBase struct { RawAccepter_Enable_Done subd AccepterEnableDone } func (od *AccepterEnableDoneBase) getAccepterEnableDoneBase() *AccepterEnableDoneBase { return od } func (od *rawAccepterEnableDoneBase) Enable_done() { od.subd.AccEnableDone() od.subd = nil // Break the circular reference } func setupAccepterEnableDone(od AccepterEnableDone) RawAccepter_Enable_Done { odb := od.getAccepterEnableDoneBase() odb.od = &rawAccepterEnableDoneBase{} odb.od.subd = od odb.od.RawAccepter_Enable_Done = NewDirectorAccepter_Enable_Done(odb.od) runtime.SetFinalizer(odb, destroyer.destroy) return odb.od } func (od *AccepterEnableDoneBase) destroy() { DeleteRawAccepter_Enable_Done(od.od) if Debug { fmt.Println("Accepter Enable Done destroy") } atomic.AddUint32(&GCCount, 1) } type accepterO struct { a RawAccepter e AccepterEvent } func (a *accepterO) destroy() { if a.a != nil { DeleteRawAccepter(a.a) } if Debug { fmt.Println("Accepter destroy") } atomic.AddUint32(&GCCount, 1) } func (a *accepterO) getRawAccepter() RawAccepter { return a.a } func allocaccepterObj(Rawa RawAccepter, cb AccepterEvent) Accepter { var a Accepter a = &accepterO{Rawa, cb} runtime.SetFinalizer(a, destroyer.destroy) return a } func (a *accepterO) Startup() { a.a.Startup() } func (a *accepterO) Shutdown(done AccepterShutdownDone) { if done == nil { a.a.Shutdown() } else { a.a.Shutdown(setupAccepterShutdownDone(done)) } } func (a *accepterO) ShutdownS() { a.a.Shutdown_s() } func (a *accepterO) SetCallbackEnable(val bool, done AccepterEnableDone) { if done == nil { a.a.Set_callback_enable(val) } else { a.a.Set_callback_enable(val, setupAccepterEnableDone(done)) } } func (a *accepterO) SetCallbackEnableS(val bool) { a.a.Set_callback_enable_s(val) } func (a *accepterO) Control(depth int, get bool, option uint, data []byte) (int, []byte, uint64) { var len uint64 var actlen uint64 rv := a.a.Control(depth, get, option, data, &len) actlen = len if actlen > uint64(cap(data)) { actlen = uint64(cap(data)) } return rv, data[:actlen], len } func (a *accepterO) SetSync() { a.a.Set_sync() } func (a *accepterO) AcceptS(timeout *Time, intr bool) (int, Gensio) { var rawg RawGensio var g Gensio rawg = nil g = nil rv := a.a.Accept_s(&rawg, timeout, intr) if rv == 0 { g = allocGensioObj(rawg, nil) } return rv, g } func (a *accepterO) StrToGensio(str string, cb Event) Gensio { var rawcb RawEvent if cb == nil { rawcb = nil } else { rawcb = setupEvent(cb) } rawg := a.a.Str_to_gensio(str, rawcb) return allocGensioObj(rawg, rawcb) } func (a *accepterO) GetType(depth uint) string { return a.a.Get_type(depth) } func (a *accepterO) IsReliable() bool { return a.a.Is_reliable() } func (a *accepterO) IsPacket() bool { return a.a.Is_packet() } func (a *accepterO) IsMessage() bool { return a.a.Is_message() } func (a *accepterO) GetPort() string { return a.a.Get_port() } func (w *Waiter) destroy() { if Debug { fmt.Println("Destroy Waiter") } atomic.AddUint32(&GCCount, 1) DeleteRawWaiter(w) } func (w *Waiter) Wait(count uint, timeout *Time) int { return w.RawWait(uint(count), timeout) } type rawMDNSFreeDoneBase struct { RawMDNS_Free_Done subd MDNSFreeDone } func (od *MDNSFreeDoneBase) getMDNSFreeDoneBase() *MDNSFreeDoneBase { return od } func (od *rawMDNSFreeDoneBase) Mdns_free_done() { od.subd.MDNSFreeDone() od.subd = nil // Break the circular reference } func setupMDNSFreeDone(od MDNSFreeDone) RawMDNS_Free_Done { odb := od.getMDNSFreeDoneBase() odb.od = &rawMDNSFreeDoneBase{} odb.od.subd = od odb.od.RawMDNS_Free_Done = NewDirectorMDNS_Free_Done(odb.od) runtime.SetFinalizer(odb, destroyer.destroy) return odb.od } func (od *MDNSFreeDoneBase) destroy() { DeleteRawMDNS_Free_Done(od.od) if Debug { fmt.Println("MDNS Free Done destroy") } atomic.AddUint32(&GCCount, 1) } type rawMDNSWatchFreeDoneBase struct { RawMDNS_Watch_Free_Done subd MDNSWatchFreeDone } func (od *MDNSWatchFreeDoneBase) getMDNSWatchFreeDoneBase() *MDNSWatchFreeDoneBase { return od } func (od *rawMDNSWatchFreeDoneBase) Mdns_watch_free_done() { od.subd.MDNSWatchFreeDone() od.subd = nil // Break the circular reference } func setupMDNSWatchFreeDone(od MDNSWatchFreeDone) RawMDNS_Watch_Free_Done { odb := od.getMDNSWatchFreeDoneBase() odb.od = &rawMDNSWatchFreeDoneBase{} odb.od.subd = od odb.od.RawMDNS_Watch_Free_Done = NewDirectorMDNS_Watch_Free_Done(odb.od) runtime.SetFinalizer(odb, destroyer.destroy) return odb.od } func (od *MDNSWatchFreeDoneBase) destroy() { DeleteRawMDNS_Watch_Free_Done(od.od) if Debug { fmt.Println("Watch Free Done destroy") } atomic.AddUint32(&GCCount, 1) } type rawMDNSWatchEventBase struct { RawMDNS_Watch_Event subd MDNSWatchEvent } func (od *MDNSWatchEventBase) getMDNSWatchEventBase() *MDNSWatchEventBase { return od } func (od *rawMDNSWatchEventBase) Event(state Gensio_mdns_data_state, interfacenum int, ipdomain int, name string, mtype string, domain string, host string, addr Addr, txt []string) { if od.subd == nil { return } od.subd.Event(int(state), interfacenum, ipdomain, name, mtype, domain, host, addr, txt) } func setupMDNSWatchEvent(od MDNSWatchEvent) RawMDNS_Watch_Event { odb := od.getMDNSWatchEventBase() odb.od = &rawMDNSWatchEventBase{} odb.od.subd = od odb.od.RawMDNS_Watch_Event = NewDirectorMDNS_Watch_Event(odb.od) runtime.SetFinalizer(odb, destroyer.destroy) return odb.od } func (od *MDNSWatchEventBase) destroy() { DeleteRawMDNS_Watch_Event(od.od) if Debug { fmt.Println("MDNS Watch Event destroy") } atomic.AddUint32(&GCCount, 1) } type rawMDNSServiceEventBase struct { RawMDNS_Service_Event subd MDNSServiceEvent } func (od *MDNSServiceEventBase) getMDNSServiceEventBase() *MDNSServiceEventBase { return od } func (od *rawMDNSServiceEventBase) Event(ev Gensio_mdns_service_event, info string) { if od.subd == nil { return } od.subd.Event(int(ev), info) } func setupMDNSServiceEvent(od MDNSServiceEvent) RawMDNS_Service_Event { odb := od.getMDNSServiceEventBase() odb.od = &rawMDNSServiceEventBase{} odb.od.subd = od odb.od.RawMDNS_Service_Event = NewDirectorMDNS_Service_Event(odb.od) runtime.SetFinalizer(odb, destroyer.destroy) return odb.od } func (od *MDNSServiceEventBase) destroy() { DeleteRawMDNS_Service_Event(od.od) if Debug { fmt.Println("MDNS Service Event destroy") } atomic.AddUint32(&GCCount, 1) } type mDNSO struct { rm RawMDNS } func (m *mDNSO) AddService(interfacenum int, ipdomain int, a ...interface{}) MDNSService { argc := len(a) if argc < 6 || argc > 7 { panic("Warong number of parameters to AddService") } var vname string var vmtype string var vdomain string var vhost string var name *string; var mtype *string; var domain *string var host *string if a[0] == nil { name = nil } else { vname = a[0].(string) name = &vname } if a[1] == nil { mtype = nil } else { vmtype = a[1].(string) mtype = &vmtype } if a[2] == nil { domain = nil } else { vdomain = a[2].(string) domain = &vdomain } if a[3] == nil { host = nil } else { vhost = a[3].(string) host = &vhost } var s *mDNSServiceO = nil if (argc > 6) { rseh := setupMDNSServiceEvent(a[6].(MDNSServiceEvent)) rs := m.rm.Add_service(interfacenum, ipdomain, name, mtype, domain, host, a[4].(int), a[5].([]string), rseh) s = &mDNSServiceO{rs, rseh} } else { rs := m.rm.Add_service(interfacenum, ipdomain, name, mtype, domain, host, a[4].(int), a[5].([]string)) s = &mDNSServiceO{rs, nil} } runtime.SetFinalizer(s, destroyer.destroy) return s } func (m *mDNSO) AddWatch(interfacenum int, ipdomain int, a ...interface{}) MDNSWatch { argc := len(a) if argc != 5 { panic("Wrong number of parameters to AddWatch") } var vname string var vmtype string var vdomain string var vhost string var name *string var mtype *string var domain *string var host *string if a[0] == nil { name = nil } else { vname = a[0].(string) name = &vname } if a[1] == nil { mtype = nil } else { vmtype = a[1].(string) mtype = &vmtype } if a[2] == nil { domain = nil } else { vdomain = a[2].(string) domain = &vdomain } if a[3] == nil { host = nil } else { vhost = a[3].(string) host = &vhost } rweh := setupMDNSWatchEvent(a[4].(MDNSWatchEvent)) rw := m.rm.Add_watch(interfacenum, ipdomain, name, mtype, domain, host, rweh) w := &mDNSWatchO{rw, rweh} runtime.SetFinalizer(w, destroyer.destroy) return w } func (m *mDNSO) destroy() { if Debug { fmt.Println("MDNS destroy") } atomic.AddUint32(&GCCount, 1) if m.rm != nil { rm := m.rm m.rm = nil rm.Free(nil) } } func (m *mDNSO) Free(mfd MDNSFreeDone) { if m.rm == nil { return } rm := m.rm m.rm = nil if mfd != nil { rm.Free(setupMDNSFreeDone(mfd)) } else { rm.Free() } } type mDNSServiceO struct { rs RawMDNS_Service rse RawMDNS_Service_Event } func (ms *mDNSServiceO) destroy() { if Debug { fmt.Println("MDNS Service destroy") } atomic.AddUint32(&GCCount, 1) if ms.rs != nil { rs := ms.rs ms.rs = nil rs.Free() } if ms.rse != nil { r := ms.rse.(*rawMDNSServiceEventBase) r.subd = nil ms.rse = nil } } func (ms *mDNSServiceO) Free() { if ms.rs == nil { return } rs := ms.rs ms.rs = nil rs.Free() } type mDNSWatchO struct { rw RawMDNS_Watch rwe RawMDNS_Watch_Event } func (mw *mDNSWatchO) destroy() { if Debug { fmt.Println("MDNS Watch destroy") } atomic.AddUint32(&GCCount, 1) if mw.rw != nil { rw := mw.rw mw.rw = nil rw.Free(nil) } if mw.rwe != nil { r := mw.rwe.(*rawMDNSWatchEventBase) r.subd = nil mw.rwe = nil } } func (mw *mDNSWatchO) Free(mwfd MDNSWatchFreeDone) { if mw.rw == nil { return } rw := mw.rw mw.rw = nil if mwfd != nil { rw.Free(setupMDNSWatchFreeDone(mwfd)) } else { rw.Free() } } type netIfsO struct { n Net_Ifs } func NewNetIfs(o *OsFuncs) NetIfs { n := &netIfsO{NewNet_Ifs(o)} runtime.SetFinalizer(n, destroyer.destroy) return n; } func (n *netIfsO) destroy() { if Debug { fmt.Println("Destroy NetIfs") } atomic.AddUint32(&GCCount, 1) DeleteNet_Ifs(n.n) } func (n *netIfsO) GetNumIfs() uint { return n.n.Get_num_ifs() } func (n *netIfsO) GetName(i uint) string { return n.n.Get_name(i) } func (n *netIfsO) IsUp(i uint) bool { return n.n.Is_up(i) } func (n *netIfsO) IsLoopback(i uint) bool { return n.n.Is_loopback(i) } func (n *netIfsO) IsMulticast(i uint) bool { return n.n.Is_multicast(i) } func (n *netIfsO) GetIfIndex(i uint) uint { return n.n.Get_ifindex(i) } func (n *netIfsO) GetNumAddrs(i uint) uint { return n.n.Get_num_addrs(i) } func (n *netIfsO) GetAddrNetbits(i uint, j uint) uint { return n.n.Get_addr_netbits(i, j) } func (n *netIfsO) GetAddrFamily(i uint, j uint) uint { return n.n.Get_addr_family(i, j) } func (n *netIfsO) GetAddrStr(i uint, j uint) string { return n.n.Get_addrstr(i, j) } // A net.Conn interface for a gensio. Note that this does not support // any type of callback (all callbacks return GE_NOTSUP), and it puts // the gensio into synchronous mode so no read or write ready // callbacks are called. If you modify the gensio's synchronous // setting, it will mess things up. type Conn struct { g Gensio readTimeout time.Time writeTimeout time.Time } type ax25NetAddr struct { addrstr string } func (a *ax25NetAddr) Network() string { return "gensio-ax25" } func (a *ax25NetAddr) String() string { return a.addrstr } func NewAx25NetAddr(addr string) net.Addr { return &ax25NetAddr{addr} } // Create a gensio net.Conn func Dial(str string, o *OsFuncs) (rc *Conn, err error) { defer func() { if r := recover(); r != nil { rc = nil err = fmt.Errorf("%s", r) } }() c := &Conn{ } c.g = NewGensio(str, o, &EventBase{ }) c.g.SetSync() c.g.OpenS() return c, nil } // Convert a gensio into a net.Conn. The gensio is not opened, the caller // must do this. Synchronous mode is turned on. func DialGensio(g Gensio) (rc *Conn, err error) { c := &Conn{ } c.g = g c.g.SetSync() return c, nil } // Return the gensio for a gensio net.Conn func (c *Conn) GetGensio() Gensio { return c.g } // Allocate a channel for an existing connection and return it as a // new net.Conn. The underlying gensio must support channels. func (mc *Conn) DialChannel(args []string) (rc *Conn, err error) { defer func() { if r := recover(); r != nil { rc = nil err = fmt.Errorf("%s", r) } }() c := &Conn{ } c.g = mc.g.AllocChannel(args, &EventBase{ }) c.g.SetSync() c.g.OpenS() return c, nil } // Standard net.Conn read function. func (c *Conn) Read(b []byte) (n int, err error) { var timeout *Time = nil defer func() { if r := recover(); r != nil { n = 0 err = fmt.Errorf("%s", r) } }() if !c.readTimeout.IsZero() { diff := c.readTimeout.Sub(time.Now()) if diff <= 0 { return 0, fmt.Errorf("Timeout is in the past") } timeout = NewTime(int64(diff) / 1000000000, int(int64(diff) % 1000000000)) } errv, data := c.g.ReadS(b, timeout, false) if errv != 0 { return 0, fmt.Errorf("%s", ErrToStr(errv)) } return len(data), nil } // Standard net.Conn write function. func (c *Conn) Write(b []byte) (n int, err error) { var timeout *Time = nil defer func() { if r := recover(); r != nil { n = 0 err = fmt.Errorf("%s", r) } }() if !c.writeTimeout.IsZero() { diff := c.writeTimeout.Sub(time.Now()) if diff <= 0 { return 0, fmt.Errorf("Timeout is in the past") } timeout = NewTime(int64(diff) / 1000000000, int(int64(diff) % 1000000000)) } errv, count := c.g.WriteS(b, timeout, false) if errv != 0 { return 0, fmt.Errorf("%s", ErrToStr(errv)) } return int(count), nil } // Standard net.Conn close function. func (c *Conn) Close() (err error) { defer func() { if r := recover(); r != nil { err = fmt.Errorf("%s", r) } }() c.g.CloseS() return nil } // Return the local address for the gensio. func (c *Conn) LocalAddr() net.Addr { addrdata := make([]byte, 1024) errv, data, count := c.g.Control(GENSIO_CONTROL_DEPTH_FIRST, true, GENSIO_CONTROL_LADDR, addrdata) if errv != 0 || count == 0 || count > 1024 { return nil } return &ax25NetAddr { string(data) } } // Return the remote address for the gensio. func (c *Conn) RemoteAddr() net.Addr { addrdata := make([]byte, 1024) errv, data, count := c.g.Control(GENSIO_CONTROL_DEPTH_FIRST, true, GENSIO_CONTROL_RADDR, addrdata) if errv != 0 || count == 0 || count > 1024 { return nil } return &ax25NetAddr { string(data) } } func (c *Conn) SetDeadline(t time.Time) error { c.readTimeout = t c.writeTimeout = t return nil } func (c *Conn) SetReadDeadline(t time.Time) error { c.readTimeout = t return nil } func (c *Conn) SetWriteDeadline(t time.Time) error { c.writeTimeout = t return nil } // A net.Listener implementation for gensio type Listener struct { a Accepter } // Allocate a gensio and a net.Listener under it func Listen(str string, o *OsFuncs) (rl *Listener, err error) { defer func() { if r := recover(); r != nil { rl = nil err = fmt.Errorf("%s", r) } }() l := &Listener{ } l.a = NewAccepter(str, o, &AccepterEventBase{ }) l.a.SetSync() l.a.Startup() return l, nil } // Create a listener from an existing accepter. The accepter should be // shut down, this will start it up. func ListenAccepter(a Accepter) (rl *Listener, err error) { l := &Listener{ } l.a = a l.a.SetSync() l.a.Startup() return l, nil } // Return the accepter associated with the listener func (l *Listener) GetAccepter() Accepter { return l.a } func (l *Listener) Accept() (rc net.Conn, err error) { defer func() { if r := recover(); r != nil { rc = nil err = fmt.Errorf("%s", r) } }() errv, g := l.a.AcceptS(nil, false) if errv != 0 { return nil, fmt.Errorf("%s", ErrToStr(errv)) } c := &Conn{ } c.g = g; return c, nil } func (l *Listener) Close() (err error) { defer func() { if r := recover(); r != nil { err = fmt.Errorf("%s", r) } }() l.a.ShutdownS() return nil } func (l *Listener) Addr() net.Addr { addrdata := make([]byte, 1024) errv, data, count := l.a.Control(GENSIO_CONTROL_DEPTH_FIRST, true, GENSIO_ACC_CONTROL_LADDR, addrdata) if errv != 0 || count == 0 || count > 1024 { return nil } return &ax25NetAddr { string(data) } } gensio-3.0.0/c++/swig/Makefile.in0000664000175000017500000005457515061121657012073 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = c++/swig ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = . include $(PYGENSIO_DIR) $(GO_DIR) DIST_SUBDIRS = include pygensio go all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/swig/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/swig/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/c++/swig/Makefile.am0000664000175000017500000000012214664224267012046 SUBDIRS = . include $(PYGENSIO_DIR) $(GO_DIR) DIST_SUBDIRS = include pygensio go gensio-3.0.0/c++/swig/pygensio/0000775000175000017500000000000015061121734011717 5gensio-3.0.0/c++/swig/pygensio/Makefile.in0000664000175000017500000007526315061121657013725 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = c++/swig/pygensio ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pythonlibdir)" LTLIBRARIES = $(pythonlib_LTLIBRARIES) am__DEPENDENCIES_1 = _pygensio_la_DEPENDENCIES = \ $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/c++/lib/libgensiomdnscpp.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensiomdns.la $(am__DEPENDENCIES_1) nodist__pygensio_la_OBJECTS = pygensio_wrap.lo _pygensio_la_OBJECTS = $(nodist__pygensio_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = _pygensio_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(_pygensio_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/pygensio_wrap.Plo am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(nodist__pygensio_la_SOURCES) DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = include tests AM_CPPFLAGS = $(PYTHON_CPPFLAGS) -I$(top_srcdir)/c++/swig/pygensio/include pythonlibdir = $(PYTHON_INSTALL_LIB_DIR) pythonlib_LTLIBRARIES = _pygensio.la EXTRA_DIST = pygensio.i nodist__pygensio_la_SOURCES = pygensio_wrap.cc _pygensio_la_LIBADD = $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/c++/lib/libgensiomdnscpp.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensiomdns.la \ $(PYTHON_UNDEF_LIBS) _pygensio_la_LDFLAGS = -module -avoid-version $(OPENSSL_LDFLAGS) \ $(PYTHON_UNDEF_FLAG) $(PYTHON_EXT_EXT_SET) all: all-recursive .SUFFIXES: .SUFFIXES: .cc .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/swig/pygensio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/swig/pygensio/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pythonlibLTLIBRARIES: $(pythonlib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pythonlib_LTLIBRARIES)'; test -n "$(pythonlibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pythonlibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pythonlibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pythonlibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pythonlibdir)"; \ } uninstall-pythonlibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pythonlib_LTLIBRARIES)'; test -n "$(pythonlibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pythonlibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pythonlibdir)/$$f"; \ done clean-pythonlibLTLIBRARIES: -test -z "$(pythonlib_LTLIBRARIES)" || rm -f $(pythonlib_LTLIBRARIES) @list='$(pythonlib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } _pygensio.la: $(_pygensio_la_OBJECTS) $(_pygensio_la_DEPENDENCIES) $(EXTRA__pygensio_la_DEPENDENCIES) $(AM_V_CXXLD)$(_pygensio_la_LINK) -rpath $(pythonlibdir) $(_pygensio_la_OBJECTS) $(_pygensio_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pygensio_wrap.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LTLIBRARIES) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(pythonlibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local \ clean-pythonlibLTLIBRARIES mostlyclean-am distclean: distclean-recursive -rm -f ./$(DEPDIR)/pygensio_wrap.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-pythonlibLTLIBRARIES install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-exec-local install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f ./$(DEPDIR)/pygensio_wrap.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-local uninstall-pythonlibLTLIBRARIES .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--depfiles check check-am clean clean-generic clean-libtool \ clean-local clean-pythonlibLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-exec-local install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-pythonlibLTLIBRARIES install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-local \ uninstall-pythonlibLTLIBRARIES .PRECIOUS: Makefile pygensio_wrap.cc pygensio.py: pygensio.i $(top_srcdir)/c++/include/gensio \ $(top_srcdir)/c++/swig/include/gensio_base.i \ $(top_srcdir)/include/gensio/gensio_err.h \ $(top_srcdir)/include/gensio/gensio_control.h \ $(top_srcdir)/include/gensio/gensio_types.h $(SWIG) $(DEFS) -Wall -python $(PYTHON_SWIG_FLAGS) \ -o pygensio_wrap.cc -c++ \ -I$(top_srcdir)/c++/swig/pygensio -I$(top_srcdir)/c++/include \ -I$(top_srcdir)/include \ -I$(top_builddir)/include -I$(top_srcdir)/c++/swig/include \ $(top_srcdir)/c++/swig/pygensio/pygensio.i clean-local: rm -rf __pycache__ pygensio_wrap.cc pygensio_wrap.h pygensio.py install-exec-local: _pygensio.la pygensio.py $(INSTALL) -d $(DESTDIR)$(PYTHON_INSTALL_DIR) $(INSTALL_DATA) pygensio.py "$(DESTDIR)$(PYTHON_INSTALL_DIR)" uninstall-local: $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(PYTHON_INSTALL_LIB_DIR)/_pygensio.$(PYTHON_EXT_EXT)" rm -f "$(DESTDIR)$(PYTHON_INSTALL_DIR)/pygensio.py" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/c++/swig/pygensio/tests/0000775000175000017500000000000015061121734013061 5gensio-3.0.0/c++/swig/pygensio/tests/Makefile.in0000664000175000017500000007650715061121657015071 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = c++/swig/pygensio/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = runtest CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/runtest.in \ $(top_srcdir)/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_TESTS_ENVIRONMENT = SKIP_TESTS="$(SKIP_TESTS)" LOG_COMPILER = $(SHELL) $(builddir)/runtest TESTS = test_basic.py test_ax25.py test_crypto.py test_mdns.py \ test_serial.py EXTRA_DIST = testbase.py $(TESTS) all: all-am .SUFFIXES: .SUFFIXES: .log .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/swig/pygensio/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/swig/pygensio/tests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): runtest: $(top_builddir)/config.status $(srcdir)/runtest.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? test_basic.py.log: test_basic.py @p='test_basic.py'; \ b='test_basic.py'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_ax25.py.log: test_ax25.py @p='test_ax25.py'; \ b='test_ax25.py'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_crypto.py.log: test_crypto.py @p='test_crypto.py'; \ b='test_crypto.py'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_mdns.py.log: test_mdns.py @p='test_mdns.py'; \ b='test_mdns.py'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_serial.py.log: test_serial.py @p='test_serial.py'; \ b='test_serial.py'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am check check-TESTS check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am recheck tags-am \ uninstall uninstall-am .PRECIOUS: Makefile export VERBOSE = 1 test_crypto.py: ca/CA.key ca/CA.key: $(top_srcdir)/tests/make_keys clean-local: rm -rf ca __pycache__ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/c++/swig/pygensio/tests/runtest.in0000664000175000017500000000556214752425772015064 #!/bin/sh SRCDIR="@top_srcdir@" TEST_SRCDIR="${SRCDIR}/c++/swig/pygensio/tests" BUILDDIR="@top_builddir@" TEST_BUILDDIR="${BUILDDIR}/c++/swig/pygensio/tests" PYTHON="@PYTHON_EXECUTABLE@" PYTHON_SET=false PRINT_MODE=false while echo $1 | grep '^-' >/dev/null; do if [ "X$1" = "X--python" ]; then PYTHON_SET=true elif [ "X$1" = "X--print" ]; then PRINT_MODE=true elif [ "X$1" = "X--" ]; then break else echo "Unknown option: $1" 1>&2 exit 1 fi shift done if [ -z "$1" ]; then echo "No test given" 1>&2 exit 1 fi # See if we are skipping this test T1=`basename $1` if echo "$SKIP_TESTS" | grep -q "$T1"; then exit 77 fi TEST=$1 shift if [ -e "${TEST_BUILDDIR}/${TEST}" ]; then TEST="${TEST_BUILDDIR}/${TEST}" elif [ -e "${TEST_SRCDIR}/${TEST}" ]; then TEST="${TEST_SRCDIR}/${TEST}" else echo "Test ${TEST} not found" 1>&2 exit 1 fi if ${PYTHON_SET}; then PYTHON_MODE=true elif echo "${TEST}" | grep '\.py$' >/dev/null; then PYTHON_MODE=true else PYTHON_MODE=false fi if ${PYTHON_MODE}; then export PYTHONPATH="${BUILDDIR}/tests:${BUILDDIR}/c++/swig/pygensio:${BUILDDIR}/c++/swig/pygensio/.libs:${SRCDIR}/c++/swig/pygensio/test:${BUILDDIR}/glib/c++/swig/pygensio:${BUILDDIR}/glib/c++/swig/pygensio/.libs:${BUILDDIR}/tcl/c++/swig/pygensio:${BUILDDIR}/tcl/c++/swig/pygensio/.libs:${TEST_BUILDDIR}" if [ ! -z "$MSYSTEM" -a "$MSYSTEM" != "MSYS" ]; then # PYTHONPATH is separated by ; on windows export PYTHONPATH=`echo ${PYTHONPATH} | tr ':' ';'` fi TEST="${PYTHON} ${TEST}" export GENSIO_MEMTRACK=abort else if [ ! -x ${TEST} ]; then echo "Test ${TEST} is not executable" 1>&2 exit 1 fi fi # We need to put the DLL in PATH for MSYS on Windows if [ ! -z "$MSYSTEM" -a "$MSYSTEM" != "MSYS" ]; then export PATH="${BUILDDIR}/lib:${BUILDDIR}/lib/.libs:${BUILDDIR}/c++/lib/.libs:${BUILDDIR}/c++/swig/pygensio/.libs:${BUILDDIR}/glib/.libs:${BUILDDIR}/glib/c++/swig/pygensio/.libs:${BUILDDIR}/tcl/.libs:${BUILDDIR}/tcl/c++/swig/pygensio/.libs:$PATH" else export LD_LIBRARY_PATH=${BUILDDIR}/lib:${BUILDDIR}/lib/.libs:${BUILDDIR}/c++/swig/pygensio/.libs:${BUILDDIR}/glib/.libs:${BUILDDIR}/glib/c++/pygensio/.libs:${BUILDDIR}/tcl/.libs:${BUILDDIR}/tcl/c++/pygensio/.libs:${BUILDDIR}/c++/lib/.libs fi if test `uname` = Darwin; then TEST="DYLD_LIBRARY_PATH=${LD_LIBRARY_PATH} ${TEST}" fi if ${PRINT_MODE}; then echo export PYTHONPATH="${PYTHONPATH}" if [ ! -z "$MSYSTEM" -a "$MSYSTEM" != "MSYS" ]; then echo export PATH=${PATH} elif test `uname` != Darwin; then echo export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" fi echo ${TEST} $* else # Run the test with each available OS handler for i in default @TCL_DIR@ @GLIB_DIR@; do echo "Testing with '$i'" export GENSIO_TEST_OS_HANDLER=$i eval "${TEST} $*" rv=$? if test $rv != 0; then # A test failed, exit exit $rv fi done fi gensio-3.0.0/c++/swig/pygensio/tests/testbase.py0000664000175000017500000002371215011013022015153 # # gensio - A library for abstracting stream I/O # Copyright (C) 2018 Corey Minyard # # SPDX-License-Identifier: GPL-2.0-only # import os # Since Python 3.8 non-system paths are not loaded to the DLL load order # in python. Work around that by adding all PATH directories to the DLL # search path. def fix_dll_path(): if os.name != "nt": return path = os.getenv("PATH") if not path: return paths = path.split(";") # The patches added below are search last added first. So preserved # the DLL order by putting them in backwards. for folder in reversed(paths): if os.path.exists(folder): os.add_dll_directory(folder) fix_dll_path() import sys import pygensio # Allocate an OS handler class Logger(pygensio.Os_Funcs_Log_Handler): def __init__(self): pygensio.Os_Funcs_Log_Handler.__init__(self) return def log(self, level, s): print("Log") try: print(pygensio.log_level_to_str(level).upper() + " LOG: " + s.encode('utf-8', 'surrogateescape').decode('ISO-8859-1')) except: print("Log error") return l = Logger() oshndname = os.getenv("GENSIO_TEST_OS_HANDLER") if oshndname is None or oshndname == "default": o = pygensio.Os_Funcs(0, l); elif oshndname == "glib": import pygensioglib o = pygensioglib.Glib_Os_Funcs(l); elif oshndname == "tcl": import pygensiotcl o = pygensiotcl.Tcl_Os_Funcs(l); else: print("Unknown OS handler name: " + oshndname) sys.exit(1) del l class Refl_EvHnd(pygensio.Event): def __init__(self, w): pygensio.Event.__init__(self) self.data = None self.g = None self.w = w return def set_gensio(self, g): self.g = g return def read(self, err, data, auxdata): self.g.set_read_callback_enable(False) if err != 0: if err != pygensio.GE_REMCLOSE: raise Exception("Error from reflector event read: " + pygensio.err_to_string(err)) self.g = None self.w.wake() return 0 self.data = data self.g.set_write_callback_enable(True) return len(data) def write_ready(self): if self.data is None: self.g.set_write_callback_enable(False) return count = self.g.write(self.data, None) if count == len(self.data): self.data = None self.g.set_write_callback_enable(False) self.g.set_read_callback_enable(True) else: self.data = self.data[count:] return class Refl_Acc_EvHnd(pygensio.Accepter_Event): def __init__(self): pygensio.Accepter_Event.__init__(self) return def set_reflector(self, r): self.r = r return def new_connection(self, g): self.r.new_connection(g) return; class Refl_Acc_Shutdown(pygensio.Accepter_Shutdown_Done): def __init__(self, r): pygensio.Accepter_Shutdown_Done.__init__(self) self.r = r return def shutdown_done(self): self.r.shutdown_done() return class Refl_Acc_Enable(pygensio.Accepter_Enable_Done): def __init__(self, r): pygensio.Accepter_Enable_Done.__init__(self) self.r = r return def enable_done(self): self.r.enable_done() return class Reflector: def __init__(self, o, accstr, evh = None, w = None, acc_evh = None): self.o = o if acc_evh is None: self.e = Refl_Acc_EvHnd() else: self.e = acc_evh self.e.set_reflector(self) self.acc = pygensio.gensio_acc_alloc(accstr, o, self.e) if w is None: self.w = pygensio.Waiter(o) else: self.w = w self.g = None if evh is None: self.h = Refl_EvHnd(self.w) else: self.h = evh return def startup(self): self.acc.startup() return def new_connection(self, g): if self.g is not None: raise Exception("New connection while connected") self.g = g self.h.set_gensio(g) self.g.set_event_handler(self.h) self.g.set_read_callback_enable(True) return def set_enable(self, val, do_cb = True): if do_cb: h = Refl_Acc_Enable(self) self.acc.set_callback_enable(val, h) else: self.acc.set_callback_enable(val, None) return def set_enable_s(self, val): self.acc.set_callback_enable_s(val) return def enable_done(self): self.w.wake() return def shutdown(self): h = Refl_Acc_Shutdown(self) self.acc.shutdown(h) return def shutdown_done(self): self.w.wake() self.del_links() return def shutdown_s(self): self.acc.shutdown_s() self.del_links() return def del_links(self): self.g = None self.acc = None self.h = None self.e = None return def wait(self, timeout = None): return self.w.wait(2, timeout) def wait1(self, timeout = None): return self.w.wait(1, timeout) def get_port(self): return self.acc.get_port() class Open_Done(pygensio.Gensio_Open_Done): def __init__(self, w): pygensio.Gensio_Open_Done.__init__(self) self.err = None self.w = w return def open_done(self, err): self.err = err self.w.wake() class Close_Done(pygensio.Gensio_Close_Done): def __init__(self, w): pygensio.Gensio_Close_Done.__init__(self) self.w = w return def close_done(self): self.w.wake() class EvHnd(pygensio.Event): def __init__(self, o): pygensio.Event.__init__(self) self.data = None self.g = None self.w = pygensio.Waiter(o) return def set_gensio(self, g): self.g = g return def read(self, err, data, auxdata): readlen = len(data) if readlen + self.readpos > len(self.data): raise Exception("Read too much data") if data != self.data[self.readpos:self.readpos + readlen]: raise Exception("Data mismatch") self.readpos = self.readpos + readlen if self.readpos == len(self.data): self.w.wake() self.g = None return len(data) def write_ready(self): if self.data is None or self.writepos >= len(self.data): self.g.set_write_callback_enable(False) return count = self.g.write(self.data[self.writepos:], None) self.writepos = self.writepos + count if self.writepos == len(self.data): self.g.set_write_callback_enable(False) return def set_data(self, d): self.data = d self.readpos = 0 self.writepos = 0 self.g.set_read_callback_enable(True) self.g.set_write_callback_enable(True) return def wait(self, count = 1, timeout = None): return self.w.wait(count, timeout) def conv_to_bytes(s): if (isinstance(s, str)): return bytes(s, "utf-8") else: return s def conv_from_bytes(b): return str(b, "utf-8") def verify_acc(acc, acctype, is_reliable, is_packet, is_message): if acc.get_type(0) != acctype: raise Exception("Accepter type incorrect, expected %s, got %s" % (acctype, r.acc.get_type(0))) if acc.is_reliable() != is_reliable: raise Exception("Accepter is_reliable incorrect, expect %s, got %s" % (is_reliable, acc.is_reliable())) if acc.is_packet() != is_packet: raise Exception("Accepter is_packet incorrect, expect %s, got %s" % (is_packet, acc.is_packet())) if acc.is_message(): raise Exception("Accepter is_message incorrect, expect %s, got %s" % (is_message, acc.is_message())) def verify_gen(g, gtype, is_client, is_reliable, is_packet, is_authenticated, is_encrypted, is_message): if g.get_type(0) != gtype: raise Exception("Gensio type incorrect, expected %s, got %s" % (gentype, g.get_type(0))) if g.is_client() != is_client: raise Exception("Gensio is_client incorrect, expect %s, got %s" % (is_client, g.is_client())) if g.is_reliable() != is_reliable: raise Exception("Gensio is_reliable incorrect, expect %s, got %s" % (is_reliable, g.is_reliable())) if g.is_packet() != is_packet: raise Exception("Gensio is_packet incorrect, expect %s, got %s" % (is_packet, g.is_packet())) if g.is_authenticated() != is_authenticated: raise Exception("Gensio is_authenticated incorrect, expect %s, got %s" % (is_authenticated, g.is_authenticated())) if g.is_encrypted() != is_encrypted: raise Exception("Gensio is_encrypted incorrect, expect %s, got %s" % (is_encrypted, g.is_encrypted())) if g.is_message(): raise Exception("Gensio is_message incorrect, expect %s, got %s" % (is_message, g.is_message())) def test_shutdown(): global o w = pygensio.Waiter(o) count = 0 while pygensio.gensio_num_alloced() > 0: count += 1 if (count > 100): raise Exception("All gensios were not freed in time, %d left" % pygensio.gensio_num_alloced()) w.service(pygensio.gensio_time(0, 1000000)) while w.service(pygensio.gensio_time(0, 0)) == 0: # Give some time for everyting to clear out. pass del w o.set_log_handler(None) c = sys.getrefcount(o) if c != 2: raise Exception("OS object refcount was %d, not 2" % c) c = o.get_refcount() if c != 1: raise Exception("OS funcs refcount was %d, not 1" % c) o.cleanup_mem() del o gensio-3.0.0/c++/swig/pygensio/tests/test_serial.py0000664000175000017500000003135215045153771015705 # # gensio - A library for abstracting stream I/O # Copyright (C) 2018 Corey Minyard # # SPDX-License-Identifier: GPL-2.0-only # # Test basic operation, both synchronous and asynchronous open, close, # and data passing. Also shutdown, enable, and new connections for # Accepters. from testbase import * import pygensio import sys # Note that serial_event must be first. class STelnet_Refl_EvHnd(Refl_EvHnd): def __init__(self, w): Refl_EvHnd.__init__(self, w) self.got_break = False self.baud_v = 9600 self.sig_v = bytes("mysig", "utf8") self.datasize_v = 8 self.parity_v = pygensio.GENSIO_SER_PARITY_NONE self.stopbits_v = 1 self.flowcontrol_v = pygensio.GENSIO_SER_FLOWCONTROL_NONE self.iflowcontrol_v = pygensio.GENSIO_SER_FLOWCONTROL_DCD self.break_v = pygensio.GENSIO_SER_OFF self.rts_v = pygensio.GENSIO_SER_OFF return def set_gensio(self, g): self.g = g return def signature(self, sig): if sig is not None and len(sig) > 0: self.sig_v = sig self.g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_SIGNATURE, self.sig_v, None, None) return def flush(self, val): # FIXME - how to detect? return def sync(self): return def baud(self, speed): if speed != 0: self.baud_v = speed self.g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_BAUD, str(self.baud_v), None, None) return def datasize(self, size): if size != 0: self.datasize_v = size self.g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_DATASIZE, str(self.datasize_v), None, None) return def parity(self, par): if par != 0: self.parity_v = par par = pygensio.gensio_parity_to_str(self.parity_v) rv = self.g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_PARITY, par, None, None) return def stopbits(self, bits): if bits != 0: self.stopbits_v = bits self.g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_STOPBITS, str(self.stopbits_v), None, None) return def flowcontrol(self, flow): if flow != 0: self.flowcontrol_v = flow flow = pygensio.gensio_flowcontrol_to_str(self.flowcontrol_v) self.g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_FLOWCONTROL, flow, None, None) return def iflowcontrol(self, flow): if flow != 0: self.iflowcontrol_v = flow flow = pygensio.gensio_flowcontrol_to_str(self.iflowcontrol_v) self.g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_IFLOWCONTROL, flow, None, None) return def sbreak(self, val): if val != 0: self.break_v = val val = pygensio.gensio_onoff_to_str(self.break_v) self.g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_SBREAK, val, None, None) return def dtr(self, val): if val != 0: self.dtr_v = val val = pygensio.gensio_onoff_to_str(self.dtr_v) self.g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_DTR, val, None, None) return def rts(self, val): if val != 0: self.rts_v = val val = pygensio.gensio_onoff_to_str(self.rts_v) self.g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_RTS, val, None, None) return def send_break(self): self.got_break = True self.w.wake() return class STelnet_EvHnd(EvHnd): def __init__(self, w): EvHnd.__init__(self, w) self.got_break = False self.baud_v = None return def modemstate(self, state): return def linestate(self, state): return def flow_state(self, state): return def send_break(self): self.got_break = True self.w.wake() return class Gen_Control_Done(pygensio.Gensio_Control_Done): def __init__(self, w): pygensio.Gensio_Control_Done.__init__(self) self.w = w def control_done(self, err, val): self.err = err self.val = val self.w.wake() w = pygensio.Waiter(o) treh = STelnet_Refl_EvHnd(w) r = Reflector(o, "telnet(rfc2217),tcp,localhost,0", w = w, evh = treh) r.startup() port = r.get_port() h = STelnet_EvHnd(o) g = pygensio.gensio_alloc("telnet(rfc2217),tcp,localhost," + port, o, h) h.set_gensio(g) g.open_s() h.set_data(conv_to_bytes("Test string")) rv = h.wait(timeout=pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for I/O: " + pygensio.err_to_string(rv)) g.set_read_callback_enable(True) od = Gen_Control_Done(w) g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_SIGNATURE, "", od, None) rv = w.wait(1, pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for sig: " + pygensio.err_to_string(rv)) if od.err != 0: raise Exception("Error fetching sig: " + pygensio.err_to_string(od.err)) if str(od.val, "utf8") != "mysig": raise Exception("Invalid sig: '%s'" % str(od.val, "utf8")) del od g.control(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_CONTROL_SER_FLUSH, "recv") (rv, baud) = g.acontrol_s(0, pygensio.GENSIO_CONTROL_GET, pygensio.GENSIO_ACONTROL_SER_BAUD, "0", pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error getting baud: " + pygensio.err_to_string(rv)) if baud != b"9600": raise Exception("Invalid baud: %s" % str(baud)) od = Gen_Control_Done(w) g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_BAUD, "19200", od, None) rv = w.wait(1, pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for baud: " + pygensio.err_to_string(rv)) if od.err != 0: raise Exception("Error fetching baud: " + pygensio.err_to_string(od.err)) if od.val != b"19200": raise Exception("Invalid baud(2): %s" % str(od.val)) del od (rv, datasize) = g.acontrol_s(0, pygensio.GENSIO_CONTROL_GET, pygensio.GENSIO_ACONTROL_SER_DATASIZE, "0", pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error getting datasize: " + pygensio.err_to_string(rv)) if datasize != b"8": raise Exception("Invalid datasize: %d" % datasize) od = Gen_Control_Done(w) g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_DATASIZE, "7", od, None) rv = w.wait(1, pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for datasize: " + pygensio.err_to_string(rv)) if od.err != 0: raise Exception("Error fetching datasize: " + pygensio.err_to_string(od.err)) if od.val != b"7": raise Exception("Invalid datasize(2): %s" % str(od.val)) del od (rv, parity) = g.acontrol_s(0, pygensio.GENSIO_CONTROL_GET, pygensio.GENSIO_ACONTROL_SER_PARITY, "0", pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error getting parity: " + pygensio.err_to_string(rv)) if parity != b"none": raise Exception("Invalid parity: %d" % parity) od = Gen_Control_Done(w) g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_PARITY, "odd", od, None) rv = w.wait(1, pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for parity: " + pygensio.err_to_string(rv)) if od.err != 0: raise Exception("Error fetching parity: " + pygensio.err_to_string(od.err)) if od.val != b"odd": raise Exception("Invalid parity(2): %s" % str(od.val)) del od (rv, stopbits) = g.acontrol_s(0, pygensio.GENSIO_CONTROL_GET, pygensio.GENSIO_ACONTROL_SER_STOPBITS, "0", pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error getting stopbits: " + pygensio.err_to_string(rv)) if stopbits != b"1": raise Exception("Invalid stopbits: %d" % stopbits) od = Gen_Control_Done(w) g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_STOPBITS, "2", od, None) rv = w.wait(1, pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for stopbits: " + pygensio.err_to_string(rv)) if od.err != 0: raise Exception("Error fetching stopbits: " + pygensio.err_to_string(od.err)) if od.val != b"2": raise Exception("Invalid stopbits(2): %s" % str(od.val)) del od (rv, flowcontrol) = g.acontrol_s(0, pygensio.GENSIO_CONTROL_GET, pygensio.GENSIO_ACONTROL_SER_FLOWCONTROL, "0", pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error getting flowcontrol: " + pygensio.err_to_string(rv)) if flowcontrol != b"none": raise Exception("Invalid flowcontrol: %d" % flowcontrol) od = Gen_Control_Done(w) g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_FLOWCONTROL, "xonxoff", od, None) rv = w.wait(1, pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for flowcontrol: " + pygensio.err_to_string(rv)) if od.err != 0: raise Exception("Error fetching flowcontrol: " + pygensio.err_to_string(od.err)) if od.val != b"xonxoff": raise Exception("Invalid flowcontrol(2): %s" % str(od.val)) del od (rv, iflowcontrol) = g.acontrol_s(0, pygensio.GENSIO_CONTROL_GET, pygensio.GENSIO_ACONTROL_SER_IFLOWCONTROL, "0", pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error getting iflowcontrol: " + pygensio.err_to_string(rv)) if iflowcontrol != b"dcd": raise Exception("Invalid iflowcontrol: %d" % iflowcontrol) od = Gen_Control_Done(w) g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_IFLOWCONTROL, "dsr", od, None) rv = w.wait(1, pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for iflowcontrol: " + pygensio.err_to_string(rv)) if od.err != 0: raise Exception("Error fetching iflowcontrol: " + pygensio.err_to_string(od.err)) if od.val != b"dsr": raise Exception("Invalid iflowcontrol(2): %s" % str(od.val)) del od (rv, breakv) = g.acontrol_s(0, pygensio.GENSIO_CONTROL_GET, pygensio.GENSIO_ACONTROL_SER_SBREAK, "0", pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error getting break: " + pygensio.err_to_string(rv)) if breakv != b"off": raise Exception("Invalid break: %d" % breakv) od = Gen_Control_Done(w) g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_SBREAK, "on", od, None) rv = w.wait(1, pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for break: " + pygensio.err_to_string(rv)) if od.err != 0: raise Exception("Error fetching break: " + pygensio.err_to_string(od.err)) if od.val != b"on": raise Exception("Invalid break(2): %s" % str(od.val)) del od (rv, rts) = g.acontrol_s(0, pygensio.GENSIO_CONTROL_GET, pygensio.GENSIO_ACONTROL_SER_RTS, "0", pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error getting rts: " + pygensio.err_to_string(rv)) if rts != b"off": raise Exception("Invalid rts: %d" % rts) od = Gen_Control_Done(w) g.acontrol(0, pygensio.GENSIO_CONTROL_SET, pygensio.GENSIO_ACONTROL_SER_RTS, "on", od, None) rv = w.wait(1, pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for rts: " + pygensio.err_to_string(rv)) if od.err != 0: raise Exception("Error fetching rts: " + pygensio.err_to_string(od.err)) if od.val != b"on": raise Exception("Invalid rts(2): %s" % str(od.val)) del od # No tests for cts, dcd_dsr, ri. Those require ipmisol ch = Close_Done(w) g.close(ch) rv = w.wait(1, pygensio.gensio_time(1, 0)) del ch h.g = None if rv != 0: raise Exception("Error waiting for close: " + pygensio.err_to_string(rv)) r.shutdown() rv = r.wait(pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for acc shutdown: " + pygensio.err_to_string(rv)) del g del r del h del treh del w del o test_shutdown() print("Pass") sys.exit(0) gensio-3.0.0/c++/swig/pygensio/tests/test_ax25.py0000664000175000017500000000465614664224267015221 # # gensio - A library for abstracting stream I/O # Copyright (C) 2018 Corey Minyard # # SPDX-License-Identifier: GPL-2.0-only # # Use AX25 to test passing of auxdata. from testbase import * import pygensio import sys # Basic test with blocking I/O r = Reflector(o, "tcp,localhost,0") r.startup() port = r.get_port() class Auxdata_EvHnd(EvHnd): def __init__(self, o): EvHnd.__init__(self, o) self.wrauxdata = None self.rdauxdata = None return def set_wrauxdata(self, auxdata): self.wrauxdata = auxdata return def set_rdauxdata(self, auxdata): self.rdauxdata = auxdata return def read(self, err, data, auxdata): if err == 0: if len(auxdata) != len(self.rdauxdata): raise Exception("auxdata length mismatch, expected %s, got %s" % (str(self.rdauxdata), str(auxdata))) for i in range(0, len(auxdata)): if auxdata[i] != self.rdauxdata[i]: raise Exception("auxdata parameter mismatch, expecte %s, got %s" % (str(self.rdauxdata), str(auxdata))) return EvHnd.read(self, err, data, auxdata) def write_ready(self): if self.data is None or self.writepos >= len(self.data): return count = self.g.write(self.data[self.writepos:], self.wrauxdata) self.writepos = self.writepos + count if self.writepos == len(self.data): self.g.set_write_callback_enable(False) return h = Auxdata_EvHnd(o) g = pygensio.gensio_alloc("ax25(laddr=AE5KM-1,uiaddr=AE5KM-1),kiss(server=yes),tcp,localhost," + port, o, h) h.set_gensio(g) (rv, rsp) = g.control(0, False, pygensio.GENSIO_CONTROL_ENABLE_OOB, "1") if rv != 0: raise Exception("Error enabling oob: " + pygensio.err_to_string(rv)) g.open_s() h.set_wrauxdata(("pid:33", "addr:0,AE5KM-1,AE5KM-1", "oob")) h.set_rdauxdata(("oob", "addr:ax25:0,AE5KM-1,AE5KM-1", "pid:33")) h.set_data(conv_to_bytes("AX25 Test string")) rv = h.wait(timeout=pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for I/O: " + pygensio.err_to_string(rv)) g.close_s() r.shutdown() rv = r.wait(pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for acc shutdown: " + pygensio.err_to_string(rv)) del g del r del h del o test_shutdown() print("Pass") sys.exit(0) gensio-3.0.0/c++/swig/pygensio/tests/Makefile.am0000664000175000017500000000052414664224267015053 export VERBOSE = 1 AM_TESTS_ENVIRONMENT = SKIP_TESTS="$(SKIP_TESTS)" LOG_COMPILER = $(SHELL) $(builddir)/runtest TESTS = test_basic.py test_ax25.py test_crypto.py test_mdns.py \ test_serial.py EXTRA_DIST = testbase.py $(TESTS) test_crypto.py: ca/CA.key ca/CA.key: $(top_srcdir)/tests/make_keys clean-local: rm -rf ca __pycache__ gensio-3.0.0/c++/swig/pygensio/tests/test_crypto.py0000664000175000017500000001061214664224267015747 # # gensio - A library for abstracting stream I/O # Copyright (C) 2018 Corey Minyard # # SPDX-License-Identifier: GPL-2.0-only # # Use certauth to verify crypto interfaces from testbase import * import pygensio import sys class Crypto_Refl_Acc_EvHnd(Refl_Acc_EvHnd): def __init__(self): Refl_Acc_EvHnd.__init__(self) return def auth_begin(self, g): (rv, name) = g.control(pygensio.GENSIO_CONTROL_DEPTH_FIRST, True, pygensio.GENSIO_CONTROL_USERNAME, "0") if str(name, "utf8") != "asdf": raise Exception("Name mismatch in auth_begin") return pygensio.GE_NOTSUP def precert_verify(self, g): return pygensio.GE_NOTSUP def postcert_verify(self, g, err, errstr): return pygensio.GE_NOTSUP def password_verify(self, g, password): if password != "jkl": raise Exception("password mismatch in password_verify") return pygensio.GE_NOTSUP def request_password(self, g, maxsize): return (0, "jkl") def verify_2fa(self, g, val): if str(val, "utf8") != "1234": raise Exception("2fa mismatch in verify_2fa") return 0 def request_2fa(self, g): return (0, bytes("1234", "utf8")) class Crypto_EvHnd(EvHnd): def __init__(self, o): EvHnd.__init__(self, o) self.wrauxdata = None self.rdauxdata = None return def auth_begin(self): (rv, name) = self.g.control(pygensio.GENSIO_CONTROL_DEPTH_FIRST, True, pygensio.GENSIO_CONTROL_USERNAME, "0") if str(name, "utf8") != "asdf": raise Exception("Name mismatch in auth_begin") return pygensio.GE_NOTSUP def precert_verify(self): return pygensio.GE_NOTSUP def postcert_verify(self, err, errstr): return pygensio.GE_NOTSUP def password_verify(self, password): if password != "jkl": raise Exception("password mismatch in password_verify") return pygensio.GE_NOTSUP def request_password(self, maxsize): return (0, "jkl") def verify_2fa(self, val): if str(val, "utf8") != "1234": raise Exception("2fa mismatch in verify_2fa") return 0 def request_2fa(self): return (0, bytes("1234", "utf8")) print("Verify crypto interfaces") acch = Crypto_Refl_Acc_EvHnd() r = Reflector(o, "certauth(enable-password,enable-2fa)," + "ssl(key=ca/key.pem,cert=ca/cert.pem),tcp,localhost,0", acc_evh = acch) r.startup() port = r.get_port() h = Crypto_EvHnd(o) g = pygensio.gensio_alloc("certauth(username=asdf,enable-password)," + "ssl(ca=ca/CA.pem),tcp,localhost," + port, o, h) h.set_gensio(g) g.open_s() h.set_data(conv_to_bytes("Crypto Test string")) rv = h.wait(timeout=pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for I/O: " + pygensio.err_to_string(rv)) g.close_s() h.g = None r.shutdown() rv = r.wait(pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for acc shutdown: " + pygensio.err_to_string(rv)) del g del r del h del acch print("Verify backwards crypto interfaces") acch = Crypto_Refl_Acc_EvHnd() r = Reflector(o, "certauth(username=asdf,enable-password,mode=client)," + "ssl(ca=ca/CA.pem,mode=client),tcp,localhost,0", acc_evh = acch) r.startup() port = r.get_port() verify_acc(r.acc, "certauth", True, True, False) h = Crypto_EvHnd(o) g = pygensio.gensio_alloc("certauth(enable-password,enable-2fa,mode=server)," + "ssl(key=ca/key.pem,cert=ca/cert.pem,mode=server)," + "tcp,localhost," + port, o, h) h.set_gensio(g) g.open_s() verify_gen(g, "certauth", False, True, True, True, True, False) h.set_data(conv_to_bytes("Crypto Test string")) rv = h.wait(timeout=pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for I/O: " + pygensio.err_to_string(rv)) verify_gen(r.g, "certauth", True, True, True, True, True, False) g.close_s() h.g = None r.shutdown() rv = r.wait(pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for acc shutdown: " + pygensio.err_to_string(rv)) del g del r del h del acch del o test_shutdown() print("Pass") sys.exit(0) gensio-3.0.0/c++/swig/pygensio/tests/test_mdns.py0000664000175000017500000000637214664224267015400 # # gensio - A library for abstracting stream I/O # Copyright (C) 2018 Corey Minyard # # SPDX-License-Identifier: GPL-2.0-only # # Test mdns interfaces import sys import gensios_enabled if not gensios_enabled.check_gensio_enabled("mdns"): sys.exit(77) from testbase import * import pygensio class Free_Done(pygensio.MDNS_Free_Done): def __init__(self, waiter): pygensio.MDNS_Free_Done.__init__(self) self.waiter = waiter return def mdns_free_done(self): self.waiter.wake() return class Watch_Free_Done(pygensio.MDNS_Watch_Free_Done): def __init__(self, waiter): pygensio.MDNS_Watch_Free_Done.__init__(self) self.waiter = waiter return def mdns_watch_free_done(self): self.waiter.wake() return class Watch_EvHnd(pygensio.MDNS_Watch_Event): def __init__(self, waiter): pygensio.MDNS_Watch_Event.__init__(self) self.waiter = waiter self.watch_count = 0 self.found = False return def event(self, state, interfacenum, ipdomain, name, mtype, domain, host, addr, txt): self.watch_count += 1 if state == pygensio.GENSIO_MDNS_WATCH_ALL_FOR_NOW: # Don't use this for anything, it's unreliable return if self.found: return if state == pygensio.GENSIO_MDNS_WATCH_NEW_DATA: self.found = True self.waiter.wake() return class Service_EvHnd(pygensio.MDNS_Service_Event): def __init__(self, waiter): pygensio.MDNS_Service_Event.__init__(self) self.waiter = waiter return def event(self, ev, info): if ev == pygensio.GENSIO_MDNS_SERVICE_REMOVED: self.waiter.wake() elif ev == pygensio.GENSIO_MDNS_SERVICE_ERROR: print("Error: " + info) else: print("Service name: " + info); self.waiter.wake() return waiter = pygensio.Waiter(o) waiter2 = pygensio.Waiter(o) m = pygensio.MDNS(o) e = Watch_EvHnd(waiter) w = m.add_watch(-1, pygensio.GENSIO_NETTYPE_UNSPEC, None, "=_gensio_pytest._tcp", None, None, e) se = Service_EvHnd(waiter2) s = m.add_service(-1, pygensio.GENSIO_NETTYPE_UNSPEC, "gensio1", "_gensio_pytest._tcp", None, None, 5001, ("A=1", "B=2"), se) rv = waiter.wait(1, pygensio.gensio_time(5,0)) if rv != 0: raise Exception("Error waiting for mdns service: " + pygensio.err_to_string(rv)) if not e.found: raise Exception("mdns watch not found") wfh = Watch_Free_Done(waiter) w.free(wfh) rv = waiter.wait(1, pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for mdns watch free: " + pygensio.err_to_string(rv)) del wfh s.free() rv = waiter2.wait(1, pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for mdns service free: " + pygensio.err_to_string(rv)) del s mfh = Free_Done(waiter) m.free(mfh) rv = waiter.wait(1, pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for mdns free: " + pygensio.err_to_string(rv)) del mfh del se del e del waiter del waiter2 del o test_shutdown() print("Pass") sys.exit(0) gensio-3.0.0/c++/swig/pygensio/tests/test_basic.py0000664000175000017500000001056014664224267015512 # # gensio - A library for abstracting stream I/O # Copyright (C) 2018 Corey Minyard # # SPDX-License-Identifier: GPL-2.0-only # # Test basic operation, both synchronous and asynchronous open, close, # and data passing. Also shutdown, enable, and new connections for # Accepters. from testbase import * import pygensio import sys class ParseHandler(pygensio.Event): def __init__(self): pygensio.Event.__init__(self) self.log = None return def parmlog(self, log): self.log = log return None p = ParseHandler() try: g = pygensio.gensio_alloc("tcp(asdf=x),localhost,1234", o, p) except Exception as E: if str(E) != "Invalid data to parameter": raise Exception("Didn't get proper error from gensio_alloc: " + str(E)) if p.log is None: raise Exception("Log handler didn't get called ") if p.log != "gensio tcp: unknown parameter asdf=x": raise Exception("Did't get proper log from gensio_alloc: " + p.log) class AccParseHandler(pygensio.Accepter_Event): def __init__(self): pygensio.Accepter_Event.__init__(self) self.log = None return def parmlog(self, log): self.log = log return None p = AccParseHandler() try: g = pygensio.gensio_acc_alloc("tcp(asdf=x),localhost,0", o, p) except Exception as E: if str(E) != "Invalid data to parameter": raise Exception("Didn't get proper error from gensio_alloc: " + str(E)) if p.log is None: raise Exception("Log handler didn't get called ") if p.log != "accepter tcp: unknown parameter asdf=x": raise Exception("Did't get proper log from gensio_acc_alloc: " + p.log) # Basic test with blocking I/O r = Reflector(o, "tcp,localhost,0") r.startup() port = r.get_port() g = pygensio.gensio_alloc("tcp,localhost," + port, o, None) g.open_s() g.set_sync() mydata = conv_to_bytes("Test sync string") (rv, count) = g.write_s(mydata) if rv != 0: raise Exception("Error writing: " + pygensio.err_to_string(rv)) if count != len(mydata): raise Exception("Write length mismatch") (rv, data) = g.read_s(pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for read: " + pygensio.err_to_string(rv)) if data != mydata: raise Exception("Data mismatch: expected '" + str(mydata) + "' but got '" + str(data) + "'") g.clear_sync() g.close_s() r.shutdown_s() del r del g class Telnet_Refl_EvHnd(Refl_EvHnd): def __init__(self, w): Refl_EvHnd.__init__(self, w) self.got_break = False return def send_break(self): self.got_break = True self.w.wake() return # Basic test with non-blocking I/O w = pygensio.Waiter(o) treh = Telnet_Refl_EvHnd(w) r = Reflector(o, "telnet,tcp,localhost,0", w = w, evh = treh) r.startup() port = r.get_port() r.set_enable(False) rv = r.wait1(pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for acc disable: " + pygensio.err_to_string(rv)) r.set_enable_s(False) rv = r.set_enable(True, do_cb = False) h = EvHnd(o) g = pygensio.gensio_alloc("telnet,tcp,localhost," + port, o, h) h.set_gensio(g) w = pygensio.Waiter(o) oh = Open_Done(w) g.open(oh) rv = w.wait(1, pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for open: " + pygensio.err_to_string(rv)) if oh.err != 0: raise Exception("Error in open: " + pygensio.err_to_string(oh.err)) del oh h.set_data(conv_to_bytes("Test string")) rv = h.wait(timeout=pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for I/O: " + pygensio.err_to_string(rv)) g.set_read_callback_enable(True) (rv, rsp) = g.control(0, False, pygensio.GENSIO_CONTROL_SEND_BREAK, None) if rv != 0: raise Exception("Error sending break: " + pygensio.err_to_string(rv)) rv = treh.w.wait(1, pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for break: " + pygensio.err_to_string(rv)) if not treh.got_break: raise Exception("Didn't receive break: " + pygensio.err_to_string(rv)) ch = Close_Done(w) g.close(ch) rv = w.wait(1, pygensio.gensio_time(1, 0)) del ch h.g = None if rv != 0: raise Exception("Error waiting for close: " + pygensio.err_to_string(rv)) r.shutdown() rv = r.wait(pygensio.gensio_time(1, 0)) if rv != 0: raise Exception("Error waiting for acc shutdown: " + pygensio.err_to_string(rv)) del g del r del h del treh del w del o test_shutdown() print("Pass") sys.exit(0) gensio-3.0.0/c++/swig/pygensio/Makefile.am0000664000175000017500000000313314724200353013673 SUBDIRS = include tests AM_CPPFLAGS = $(PYTHON_CPPFLAGS) -I$(top_srcdir)/c++/swig/pygensio/include pythonlibdir=$(PYTHON_INSTALL_LIB_DIR) pythonlib_LTLIBRARIES = _pygensio.la pygensio_wrap.cc pygensio.py: pygensio.i $(top_srcdir)/c++/include/gensio \ $(top_srcdir)/c++/swig/include/gensio_base.i \ $(top_srcdir)/include/gensio/gensio_err.h \ $(top_srcdir)/include/gensio/gensio_control.h \ $(top_srcdir)/include/gensio/gensio_types.h $(SWIG) $(DEFS) -Wall -python $(PYTHON_SWIG_FLAGS) \ -o pygensio_wrap.cc -c++ \ -I$(top_srcdir)/c++/swig/pygensio -I$(top_srcdir)/c++/include \ -I$(top_srcdir)/include \ -I$(top_builddir)/include -I$(top_srcdir)/c++/swig/include \ $(top_srcdir)/c++/swig/pygensio/pygensio.i EXTRA_DIST = pygensio.i nodist__pygensio_la_SOURCES = pygensio_wrap.cc _pygensio_la_LIBADD = $(top_builddir)/c++/lib/libgensiooshcpp.la \ $(top_builddir)/c++/lib/libgensiocpp.la \ $(top_builddir)/c++/lib/libgensiomdnscpp.la \ $(top_builddir)/lib/libgensioosh.la \ $(top_builddir)/lib/libgensio.la \ $(top_builddir)/lib/libgensiomdns.la \ $(PYTHON_UNDEF_LIBS) _pygensio_la_LDFLAGS = -module -avoid-version $(OPENSSL_LDFLAGS) \ $(PYTHON_UNDEF_FLAG) $(PYTHON_EXT_EXT_SET) clean-local: rm -rf __pycache__ pygensio_wrap.cc pygensio_wrap.h pygensio.py install-exec-local: _pygensio.la pygensio.py $(INSTALL) -d $(DESTDIR)$(PYTHON_INSTALL_DIR) $(INSTALL_DATA) pygensio.py "$(DESTDIR)$(PYTHON_INSTALL_DIR)" uninstall-local: $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(PYTHON_INSTALL_LIB_DIR)/_pygensio.$(PYTHON_EXT_EXT)" rm -f "$(DESTDIR)$(PYTHON_INSTALL_DIR)/pygensio.py" gensio-3.0.0/c++/swig/pygensio/pygensio.i0000664000175000017500000010312415045153771013657 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only // This is the python-specific gensio wrapper %module(directors="1") pygensio /* * The gensio library can dynamically load other modules that need access * to the original library. So we need to set RTLD_GLOBAL while loading. */ %pythonbegin %{ import sys import os if os.name != 'nt': origdlopenflags = sys.getdlopenflags() sys.setdlopenflags(os.RTLD_GLOBAL | os.RTLD_LAZY) %} %pythoncode %{ if os.name != 'nt': sys.setdlopenflags(origdlopenflags) %} %include %typemap(throws) gensios::gensio_error %{ PyErr_SetString(PyExc_RuntimeError, $1.what()); SWIG_fail; %} %{ static PyObject * PI_add_result(PyObject *result, PyObject *val) { PyObject *seq, *o; if (result == Py_None) { result = val; Py_DECREF(Py_None); return result; } if (!PyTuple_Check(result)) { PyObject *tmpr = result; result = PyTuple_New(1); PyTuple_SetItem(result, 0, tmpr); } seq = PyTuple_New(1); PyTuple_SetItem(seq, 0, val); o = result; result = PySequence_Concat(o, seq); Py_DECREF(o); Py_DECREF(seq); return result; } static int PI_BytesCheck(PyObject *o) { if (PyUnicode_Check(o)) return 1; if (PyBytes_Check(o)) return 1; return 0; } static int PI_AsBytesAndSize(PyObject *o, void **buf, gensiods *ilen) { Py_ssize_t len = *ilen; int rv = 0; if (PyUnicode_Check(o)) { *buf = (char *) PyUnicode_AsUTF8AndSize(o, &len); } else { rv = PyBytes_AsStringAndSize(o, (char **) buf, &len); } if (!rv) *ilen = len; return rv; } /* Not a function because it's not always used, avoid the unused warning. */ #define PI_CanBeBytes(o) \ (o == Py_None || PI_BytesCheck(o) || PyByteArray_Check(o)) static int PI_ToUCharVector(std::vector &v, PyObject *o) { void *tdata = NULL; gensiods len = 0; if (o == Py_None) { // Nothing to do, vector is empty return 0; } if (PI_BytesCheck(o)) { if (PI_AsBytesAndSize(o, &tdata, &len) == -1) PyErr_SetString(PyExc_TypeError, "byte string conversion failed"); } else if (PyByteArray_Check(o)) { tdata = PyByteArray_AsString(o); len = PyByteArray_Size(o); } else { PyErr_SetString(PyExc_TypeError, "Must be a byte string or array"); return -1; } v.assign((unsigned char *) tdata, ((unsigned char *) tdata) + len); return 0; } #define PI_StringCheck PyUnicode_Check #define PI_AsString PyUnicode_AsUTF8 #define PI_FromStringAndSize PyBytes_FromStringAndSize static PyObject * PI_StringArrayToTuple(const char *const *val) { PyObject *o; if (val == NULL) { Py_INCREF(Py_None); return Py_None; } else { gensiods len, i; for (len = 0; val[len]; len++) ; o = PyTuple_New(len); for (i = 0; i < len; i++) PyTuple_SetItem(o, i, PyString_FromString(val[i])); return o; } } static int PI_TupleToStringArray(char ***out, PyObject *so) { unsigned int i; unsigned int len; char **temp = NULL; if (so == Py_None) goto null_auxdata; if (!PySequence_Check(so)) { PyErr_SetString(PyExc_TypeError, "Expecting a sequence"); return -1; } len = PyObject_Length(so); if (len == 0) goto null_auxdata; temp = (char **) malloc(sizeof(char *) * (len + 1)); if (!temp) { PyErr_SetString(PyExc_ValueError, "Out of memory"); return -1; } memset(temp, 0, sizeof(char *) * (len + 1)); for (i = 0; i < len; i++) { PyObject *o = PySequence_GetItem(so, i); if (!PI_StringCheck(o)) { Py_XDECREF(o); PyErr_SetString(PyExc_ValueError, "Expecting a sequence of strings"); for (; i > 0; i--) Py_XDECREF(temp[i - 1]); free(temp); return -1; } temp[i] = (char *) PI_AsString(o); Py_DECREF(o); } null_auxdata: *out = temp; return 0; } #define GENSIO_SWIG_C_BLOCK_ENTRY Py_BEGIN_ALLOW_THREADS #define GENSIO_SWIG_C_BLOCK_EXIT Py_END_ALLOW_THREADS static bool check_for_err(int err) { bool rv; if (err == GE_INTERRUPTED) PyErr_CheckSignals(); rv = (bool) PyErr_Occurred(); return rv; }; %} // We use the pure vector versions for python %ignore gensios::Gensio::write(const SimpleUCharVector data, const char *const *auxdata); %ignore gensios::Gensio::read_s(const SimpleUCharVector data, gensio_time *timeout = NULL, bool intr = false); %ignore gensios::Addr::getaddr(void *oaddr, gensiods *len); %ignore gensios::Addr::get_data(void *oaddr, gensiods *len); //////////////////////////////////////////////////// // Typemaps // // For returning a gensiods in addition to the current return items. %typemap(in, numinputs=0) gensiods *count (gensiods temp = 0) { $1 = &temp; } %typemap(argout) (gensiods *count) { $result = PI_add_result($result, SWIG_From_int(*$1)); } // For strings returned from directors. %typemap(directorin, numinputs=0) std::string &retval { } %typemap(directorargout) std::string &retval { char *buf = NULL; gensiods size = 0; if (PI_AsBytesAndSize($result, (void **) &buf, &size) == -1) { Swig::DirectorTypeMismatchException::raise( SWIG_ErrorType(SWIG_ArgError(swig_res)), "in output value of type '""std::string""'"); } else { $1.assign(buf, size); } } %typemap(argout) std::string &retval { PyObject *o; o = PyUnicode_FromStringAndSize((const char *) $1->data(), $1->size()); $result = PI_add_result($result, o); } // For vectors passed from target lang to C++, and passed in directors // to target lang, and returned vectors from directors. %typemap(typecheck, precedence=SWIG_TYPECHECK_VECTOR) std::vector { $1 = PI_CanBeBytes($input); } %typemap(typecheck, precedence=SWIG_TYPECHECK_VECTOR) const std::vector { $1 = PI_CanBeBytes($input); } // For values for write, write_s %typemap(in) const std::vector { if (PI_ToUCharVector($1, $input) == -1) SWIG_fail; } // Return value for get_addr %typemap(out) std::vector { $result = PI_FromStringAndSize((const char *) $1.data(), $1.size()); } // Used for verify_2fa %typemap(directorin) const std::vector data { $input = PI_FromStringAndSize((const char *) $1.data(), $1.size()); } // Used for request_2fa %typemap(directorin, numinputs=0) std::vector &retval { } %typemap(directorargout) std::vector &retval { char *buf = NULL; gensiods size = 0; if (PI_AsBytesAndSize($result, (void **) &buf, &size) == -1) { Swig::DirectorTypeMismatchException::raise( SWIG_ErrorType(SWIG_ArgError(swig_res)), "in output value of type '""std::vector""'"); } else { $1.assign((unsigned char *) buf, ((unsigned char *) buf) + size); } } // Used for user_event %typemap(directorin) std::vector &userdata { $input = PI_FromStringAndSize((const char *) $1.data(), $1.size()); } %typemap(directorargout) std::vector &userdata { char *buf = NULL; gensiods size = 0; if (PI_AsBytesAndSize($result, (void **) &buf, &size) == -1) { Swig::DirectorTypeMismatchException::raise( "in output value of type '""std::vector""'"); } else { $1.assign((unsigned char *) buf, ((unsigned char *) buf) + size); } } // Return for read_s, Addr::get_data, Addr:getaddr %typemap(in, numinputs=0) std::vector &rvec (std::vector temp) { temp.reserve(128); // FIXME - how to do this better? $1 = &temp; } %typemap(argout) std::vector &rvec { PyObject *o; o = PI_FromStringAndSize((const char *) $1->data(), $1->size()); $result = PI_add_result($result, o); } // For control I/O %typemap(in) std::vector &controldata (std::vector temp) { $1 = &temp; if (PI_ToUCharVector(*$1, $input) == -1) SWIG_fail; } %typemap(argout) std::vector &controldata { PyObject *o; if ($1->size() == 0) { o = Py_None; Py_INCREF(o); } else { o = PI_FromStringAndSize((const char *) $1->data(), $1->size()); } $result = PI_add_result($result, o); } // For non-allocating vectors passed from c++ to a direcotry target lang %typemap(typecheck, precedence=SWIG_TYPECHECK_VECTOR) gensios::SimpleUCharVector { $1 = PI_CanBeBytes($input); } %typemap(directorin) const gensios::SimpleUCharVector { $input = PI_FromStringAndSize((const char *) data.data(), data.size()); } // auxdata and MDNS text fields %typemap(in) const char *const * { if (PI_TupleToStringArray(&$1, $input) == -1) SWIG_fail; } %typemap(freearg) const char *const * { if ($1) { free($1); } }; %typemap(directorin) const char *const * { $input = PI_StringArrayToTuple($1_name); } %typemap(directorin) gensios::Gensio *newg { // This is for reporting new gensios $input = SWIG_NewPointerObj(SWIG_as_voidptr($1), SWIGTYPE_p_gensios__Gensio, SWIG_POINTER_OWN); } %typemap(directorin) gensios::Gensio *tmpg { // Don't set SWIG_POINTER_OWN on this, we don't want python refcounts // managing it. $input = SWIG_NewPointerObj(SWIG_as_voidptr($1), SWIGTYPE_p_gensios__Gensio, 0); } %typemap(in, numinputs=0) gensios::Gensio **gret (Gensio *temp = NULL) { $1 = &temp; } %typemap(argout) gensios::Gensio **gret { PyObject *val; if (*$1) { val = SWIG_NewPointerObj(SWIG_as_voidptr(*$1), SWIGTYPE_p_gensios__Gensio, SWIG_POINTER_OWN | 0 ); } else { val = Py_None; Py_INCREF(Py_None); } $result = PI_add_result($result, val); } %typemap(in, numinputs=0) unsigned int *outval (unsigned int temp) { temp = 0; $1 = &temp; } %typemap(argout) unsigned int *outval { $result = PI_add_result($result, PyInt_FromLong(*$1)); } // Handling of nested waiters and python callback. %{ #include static thread_local Waiter *curr_waiter; static Waiter * save_waiter(Waiter *waiter) { Waiter *prev_waiter = curr_waiter; curr_waiter = waiter; return prev_waiter; } static void restore_waiter(Waiter *prev_waiter) { curr_waiter = prev_waiter; } class Py_Open_Done: public Gensio_Open_Done { public: Py_Open_Done(Gensio_Open_Done *iparent) : parent(iparent) { Swig::Director *d = dynamic_cast(parent); if (d) pydirobj_incref(d); } void open_done(int err) override { PyGILState_STATE gstate; gstate = PyGILState_Ensure(); parent->open_done(err); Swig::Director *d = dynamic_cast(parent); if (d) pydirobj_decref(d); PyGILState_Release(gstate); delete this; } private: // The one to call after we have done our python stuff. Gensio_Open_Done *parent; }; class Py_Gensio_Close_Done: public Gensio_Close_Done { public: Py_Gensio_Close_Done(Gensio_Close_Done *iparent) : parent(iparent) { Swig::Director *d = dynamic_cast(parent); if (d) pydirobj_incref(d); } void close_done() override { PyGILState_STATE gstate; gstate = PyGILState_Ensure(); parent->close_done(); Swig::Director *d = dynamic_cast(parent); if (d) pydirobj_decref(d); PyGILState_Release(gstate); delete this; } private: // The one to call after we have done our python stuff. Gensio_Close_Done *parent; }; class Py_Gensio_Control_Done: public Gensio_Control_Done { public: Py_Gensio_Control_Done(Gensio_Control_Done *iparent) : parent(iparent) { Swig::Director *d = dynamic_cast(parent); if (d) pydirobj_incref(d); } void control_done(int err, const std::vector data) override { PyGILState_STATE gstate; gstate = PyGILState_Ensure(); parent->control_done(err, data); Swig::Director *d = dynamic_cast(parent); if (d) pydirobj_decref(d); PyGILState_Release(gstate); delete this; } private: // The one to call after we have done our python stuff. Gensio_Control_Done *parent; }; class Py_Raw_Event_Handler: public Raw_Event_Handler { public: Py_Raw_Event_Handler(Raw_Event_Handler *iparent): parent(iparent) { } ~Py_Raw_Event_Handler() { delete parent; } int handle(Gensio *g, struct gensio *io, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) override { PyGILState_STATE gstate; int rv; gstate = PyGILState_Ensure(); rv = parent->handle(g, io, event, err, buf, buflen, auxdata); PyGILState_Release(gstate); return rv; } int new_channel(Event *e, Gensio *newg, const char *const *auxdata) override { int rv; newg->raw_event_handler = new Py_Raw_Event_Handler(newg->raw_event_handler); rv = parent->new_channel(e, newg, auxdata); if (rv) { delete newg->raw_event_handler; newg->raw_event_handler = NULL; } return rv; } void freed(Event *e) override { // Don't pass the event handler. The python object is // gone, we don't want this trying to report a deleted // object to the freed event handler. parent->freed(NULL); if (e) { PyGILState_STATE gstate; gstate = PyGILState_Ensure(); Swig::Director *d = dynamic_cast(e); if (d) pydirobj_decref(d); PyGILState_Release(gstate); } } private: Raw_Event_Handler *parent; }; class Py_Accepter_Shutdown_Done: public Accepter_Shutdown_Done { public: Py_Accepter_Shutdown_Done(Accepter_Shutdown_Done *iparent) : parent(iparent) { Swig::Director *d = dynamic_cast(parent); if (d) pydirobj_incref(d); } void shutdown_done() override { PyGILState_STATE gstate; gstate = PyGILState_Ensure(); parent->shutdown_done(); Swig::Director *d = dynamic_cast(parent); if (d) pydirobj_decref(d); PyGILState_Release(gstate); delete this; } private: // The one to call after we have done our python stuff. Accepter_Shutdown_Done *parent; }; class Py_Accepter_Enable_Done: public Accepter_Enable_Done { public: Py_Accepter_Enable_Done(Accepter_Enable_Done *iparent) : parent(iparent) { Swig::Director *d = dynamic_cast(parent); if (d) pydirobj_incref(d); } void enable_done() override { PyGILState_STATE gstate; gstate = PyGILState_Ensure(); parent->enable_done(); Swig::Director *d = dynamic_cast(parent); if (d) pydirobj_decref(d); PyGILState_Release(gstate); delete this; } private: // The one to call after we have done our python stuff. Accepter_Enable_Done *parent; }; class Py_Raw_Acc_Event_Handler: public Raw_Accepter_Event_Handler { public: Py_Raw_Acc_Event_Handler(Raw_Accepter_Event_Handler *iparent): parent(iparent) { } ~Py_Raw_Acc_Event_Handler() { delete parent; } int handle(Accepter *a, int event, void *data) override { PyGILState_STATE gstate; int rv; gstate = PyGILState_Ensure(); rv = parent->handle(a, event, data); PyGILState_Release(gstate); return rv; } void new_connection(Accepter_Event *e, Gensio *newg) override { newg->raw_event_handler = new Py_Raw_Event_Handler(newg->raw_event_handler); parent->new_connection(e, newg); } void freed(Accepter_Event *e) override { // Don't pass the event handler. The python object is // gone, we don't want this trying to report a deleted // object to the freed event handler. parent->freed(NULL); if (e) { PyGILState_STATE gstate; gstate = PyGILState_Ensure(); Swig::Director *d = dynamic_cast(e); if (d) pydirobj_decref(d); PyGILState_Release(gstate); } } private: Raw_Accepter_Event_Handler *parent; }; class Py_MDNS_Free_Done: public MDNS_Free_Done { public: Py_MDNS_Free_Done(MDNS_Free_Done *iparent) : parent(iparent) { Swig::Director *d = dynamic_cast(parent); if (d) pydirobj_incref(d); } void mdns_free_done() override { PyGILState_STATE gstate; gstate = PyGILState_Ensure(); parent->mdns_free_done(); Swig::Director *d = dynamic_cast(parent); if (d) pydirobj_decref(d); PyGILState_Release(gstate); delete this; } private: // The one to call after we have done our python stuff. MDNS_Free_Done *parent; }; class Py_MDNS_Watch_Free_Done: public MDNS_Watch_Free_Done { public: Py_MDNS_Watch_Free_Done(MDNS_Watch_Free_Done *iparent) : parent(iparent) { Swig::Director *d = dynamic_cast(parent); if (d) pydirobj_incref(d); } void mdns_watch_free_done() override { PyGILState_STATE gstate; gstate = PyGILState_Ensure(); parent->mdns_watch_free_done(); Swig::Director *d = dynamic_cast(parent); if (d) pydirobj_decref(d); PyGILState_Release(gstate); delete this; } private: // The one to call after we have done our python stuff. MDNS_Watch_Free_Done *parent; }; class Py_Raw_MDNS_Event_Handler: public Raw_MDNS_Event_Handler { public: Py_Raw_MDNS_Event_Handler() { } ~Py_Raw_MDNS_Event_Handler() { if (parent) delete parent; } void handle(MDNS_Watch_Event *e, enum gensio_mdns_data_state state, int interfacenum, int ipdomain, const char *name, const char *type, const char *domain, const char *host, const struct gensio_addr *addr, const char * const *txt) override { PyGILState_STATE gstate; gstate = PyGILState_Ensure(); parent->handle(e, state, interfacenum, ipdomain, name, type, domain, host, addr, txt); PyGILState_Release(gstate); } void set_parent(Raw_MDNS_Event_Handler *parent) override { this->parent = parent; } private: Raw_MDNS_Event_Handler *parent = NULL; }; class Py_Raw_MDNS_Service_Event_Handler: public Raw_MDNS_Service_Event_Handler { public: Py_Raw_MDNS_Service_Event_Handler() { } ~Py_Raw_MDNS_Service_Event_Handler() { if (parent) delete parent; } void handle(MDNS_Service_Event *e, enum gensio_mdns_service_event ev, const char *info) override { PyGILState_STATE gstate; gstate = PyGILState_Ensure(); parent->handle(e, ev, info); PyGILState_Release(gstate); } void set_parent(Raw_MDNS_Service_Event_Handler *parent) override { this->parent = parent; } private: Raw_MDNS_Service_Event_Handler *parent = NULL; }; %} // In Python there's no way to call the free handle as the python // object has been destroyed by then. %ignore gensios::Event::freed; // We intercept all functions with callbacks to insert our own code. // Python has special requirements when you block and when you call // into python code from C/C++, we have to handle all those. %ignore gensios::Os_Funcs::Os_Funcs; %ignore gensios::Os_Funcs::~Os_Funcs; %ignore gensios::Os_Funcs::set_log_handler; %ignore gensios::Gensio::open; %ignore gensios::Gensio::open_nochild; %ignore gensios::Gensio::close; %ignore gensios::Gensio::write_s; %ignore gensios::Gensio::set_event_handler; %ignore gensios::Gensio::alloc_channel; %ignore gensios::Gensio::control; %ignore gensios::Gensio::acontrol; %ignore gensios::Gensio::acontrol_s; %ignore gensios::gensio_alloc; %ignore gensios::gensio_acc_alloc; %ignore gensios::Accepter::set_event_handler; %ignore gensios::Accepter::shutdown; %ignore gensios::Accepter::set_callback_enable(bool enabled, Accepter_Enable_Done *done); %ignore gensios::Accepter::str_to_gensio; %ignore gensios::Accepter::control; %ignore gensios::Waiter::wait; %ignore gensios::MDNS::free; %ignore gensios::MDNS::add_watch; %ignore gensios::MDNS::add_service; %ignore gensios::MDNS_Service::MDNS_Service; %ignore gensios::MDNS_Watch::free; %ignore gensios::MDNS_Watch::MDNS_Watch; #define GENSIOOSH_DLL_PUBLIC // For some reason this doesn't get set in swig %include %include #define GENSIOOSHCPP_DLL_PUBLIC // For some reason this doesn't get set in swig %include %include %include //////////////////////////////////////////////////// // Define our own Os_Funcs functions. %rename("") gensios::Os_Funcs::Os_Funcs; %rename("") gensios::Os_Funcs::~Os_Funcs; %rename("") gensios::Os_Funcs::set_log_handler; %extend gensios::Os_Funcs { Os_Funcs(int wait_sig, Os_Funcs_Log_Handler *logger = NULL) { Os_Funcs_Log_Handler *int_handler = NULL; Os_Funcs *rv; if (logger) int_handler = new Internal_Log_Handler(logger); try { rv = new Os_Funcs(wait_sig, int_handler); } catch (...) { if (int_handler) delete int_handler; throw; } return rv; } ~Os_Funcs() { delete self; } void set_log_handler(Os_Funcs_Log_Handler *logger) { Internal_Log_Handler *ilogger = dynamic_cast(self->get_log_handler()); if (ilogger) ilogger->set_handler(logger); } void cleanup_mem() { gensio_cleanup_mem(*self); } } //////////////////////////////////////////////////// // Define our own Gensio functins. %rename("") gensios::Gensio::open; %rename("") gensios::Gensio::open_nochild; %rename("") gensios::Gensio::close; %rename("") gensios::Gensio::write_s; %rename("") gensios::Gensio::write_s(gensiods *count, const std::vector data, gensio_time *timeout = NULL, bool intr = false); %rename("") gensios::Gensio::set_event_handler; %rename("") gensios::Gensio::alloc_channel; %rename("") gensios::Gensio::control; %rename("") gensios::Gensio::acontrol; %rename("") gensios::Gensio::acontrol_s; %catches(gensios::gensio_error) gensios::Gensio::write_s; %extend gensios::Gensio { void open(Gensio_Open_Done *done) { Py_Open_Done *pydone = NULL; if (done) pydone = new Py_Open_Done(done); try { self->open((Gensio_Open_Done *) pydone); } catch (...) { if (pydone) delete pydone; throw; } } void open_nochild(Gensio_Open_Done *done) { Py_Open_Done *pydone = NULL; if (done) pydone = new Py_Open_Done(done); try { self->open_nochild((Gensio_Open_Done *) pydone); } catch (...) { if (pydone) delete pydone; throw; } } void close(Gensio_Close_Done *done) { Py_Gensio_Close_Done *pydone = NULL; if (done) pydone = new Py_Gensio_Close_Done(done); try { self->close((Gensio_Close_Done *) pydone); } catch (...) { if (pydone) delete pydone; throw; } } int write_s(gensiods *count, const std::vector data) { int rv; GENSIO_SWIG_C_BLOCK_ENTRY rv = self->write_s(count, data); GENSIO_SWIG_C_BLOCK_EXIT return rv; } Gensio *alloc_channel(const char *const *args, Event *cb) { Gensio *g = self->alloc_channel(args, cb); if (cb) { Swig::Director *d = dynamic_cast(cb); if (d) pydirobj_incref(d); } if (g) g->raw_event_handler = new Py_Raw_Event_Handler(g->raw_event_handler); return g; } void set_event_handler(Event *cb) { Event *old_cb = self->get_cb(); if (cb) { Swig::Director *d = dynamic_cast(cb); if (d) pydirobj_incref(d); } self->set_event_handler(cb); if (old_cb) { Swig::Director *d = dynamic_cast(old_cb); if (d) pydirobj_decref(d); } } %rename(control) controlt; int control(int depth, bool get, unsigned int option, std::vector &controldata) { int rv; char *rdata = NULL; gensiods glen = 0, slen = 0; slen = controldata.size(); if (get) { rdata = (char *) malloc(slen + 1); if (!rdata) { rv = GE_NOMEM; goto out; } memcpy(rdata, controldata.data(), slen); rdata[slen] = '\0'; glen = slen; /* Pass in a zero length to get the actual length. */ rv = self->control(depth, get, option, rdata, &glen); free(rdata); rdata = NULL; if (rv) goto out; /* Allocate the larger of controldata.size() and glen) */ if (slen > glen) { rdata = (char *) malloc(slen + 1); glen = slen; } else { rdata = (char *) malloc(glen + 1); } if (!rdata) { rv = GE_NOMEM; goto out; } rdata[glen] = '\0'; rdata[slen] = '\0'; glen += 1; memcpy(rdata, controldata.data(), slen); rv = self->control(depth, get, option, rdata, &glen); if (rv) { free(rdata); rdata = NULL; glen = 0; } out: if (!rv) controldata.assign(rdata, rdata + glen); free(rdata); } else { rv = self->control(depth, get, option, (char *) controldata.data(), &slen); controldata.resize(0); } return rv; } %rename(acontrol) acontrolt; int acontrolt(int depth, bool get, unsigned int option, const std::vector &controldata, Gensio_Control_Done *done, gensio_time *timeout) { int rv; Py_Gensio_Control_Done *pydone = NULL; char *str = (char *) malloc(controldata.size() + 1); if (!str) return GE_NOMEM; if (done) pydone = new Py_Gensio_Control_Done(done); memcpy(str, controldata.data(), controldata.size()); str[controldata.size()] = '\0'; rv = self->acontrol(depth, get, option, str, controldata.size(), (Gensio_Control_Done *) pydone, timeout); free(str); if (rv && pydone) delete(pydone); return rv; } %rename(acontrol_s) acontrol_st; int acontrol_st(int depth, bool get, unsigned int option, std::vector &controldata, gensio_time *timeout) { int rv; char *rdata = NULL; gensiods glen = 0, slen = 0; slen = controldata.size(); if (get) { rdata = (char *) malloc(slen + 1); if (!rdata) { rv = GE_NOMEM; goto out; } memcpy(rdata, controldata.data(), slen); rdata[slen] = '\0'; glen = slen; /* Pass in a zero length to get the actual length. */ rv = self->acontrol_s(depth, get, option, rdata, &glen, timeout); free(rdata); rdata = NULL; if (rv) goto out; /* Allocate the larger of controldata.size() and glen) */ if (slen > glen) { rdata = (char *) malloc(slen + 1); glen = slen; } else { rdata = (char *) malloc(glen + 1); } if (!rdata) { rv = GE_NOMEM; goto out; } rdata[glen] = '\0'; rdata[slen] = '\0'; glen += 1; memcpy(rdata, controldata.data(), slen); rv = self->acontrol_s(depth, get, option, rdata, &glen, timeout); if (rv) { free(rdata); rdata = NULL; glen = 0; } out: if (!rv) controldata.assign(rdata, rdata + glen); if (rdata) free(rdata); } else { rv = self->acontrol_s(depth, get, option, (char *) controldata.data(), &slen, timeout); controldata.resize(0); } return rv; } } %catches(gensios::gensio_error) gensio_alloct; %rename("") gensios::gensio_alloc; %rename(gensio_alloc) gensio_alloct; %newobject gensio_alloct; %newobject cast_to_serial_gensio; %inline %{ gensios::Gensio *gensio_alloct(std::string str, gensios::Os_Funcs &o, gensios::Event *cb) { Gensio *g = gensio_alloc(std::move(str), o, cb); if (cb) { Swig::Director *d = dynamic_cast(cb); if (d) pydirobj_incref(d); } if (g) g->raw_event_handler = new Py_Raw_Event_Handler(g->raw_event_handler); return g; } gensios::Gensio *gensio_alloct(gensios::Gensio *child, std::string str, gensios::Os_Funcs &o, gensios::Event *cb) { Gensio *g = gensio_alloc(child, std::move(str), o, cb); if (cb) { Swig::Director *d = dynamic_cast(cb); if (d) pydirobj_incref(d); } if (g) g->raw_event_handler = new Py_Raw_Event_Handler(g->raw_event_handler); return g; } %} %catches(gensios::gensio_error) gensio_acc_alloct; %rename("") gensios::gensio_acc_alloc; %rename(gensio_acc_alloc) gensio_acc_alloct; %newobject gensio_acc_alloct; %inline %{ gensios::Accepter * gensio_acc_alloct(std::string str, gensios::Os_Funcs &o, gensios::Accepter_Event *cb) { Accepter *a = gensio_acc_alloc(std::move(str), o, cb); if (cb) { Swig::Director *d = dynamic_cast(cb); if (d) pydirobj_incref(d); } if (a) a->raw_event_handler = new Py_Raw_Acc_Event_Handler(a->raw_event_handler); return a; } gensios::Accepter * gensio_acc_alloct(gensios::Accepter *child, std::string str, gensios::Os_Funcs &o, gensios::Accepter_Event *cb) { Accepter *a = gensio_acc_alloc(child, std::move(str), o, cb); if (cb) { Swig::Director *d = dynamic_cast(cb); if (d) pydirobj_incref(d); } if (a) a->raw_event_handler = new Py_Raw_Acc_Event_Handler(a->raw_event_handler); return a; } %} %rename("") gensios::Accepter::set_event_handler; %rename("") gensios::Accepter::shutdown; %rename("") gensios::Accepter::set_callback_enable(bool enabled, Accepter_Enable_Done *done); %rename("") gensios::Accepter::str_to_gensio; %rename("") gensios::Accepter::control; %extend gensios::Accepter { ~Accepter() { self->free() } void shutdown(Accepter_Shutdown_Done *done) { Py_Accepter_Shutdown_Done *pydone = NULL; if (done) pydone = new Py_Accepter_Shutdown_Done(done); try { self->shutdown((Accepter_Shutdown_Done *) pydone); } catch (...) { if (pydone) delete pydone; throw; } } void set_callback_enable(bool enabled, Accepter_Enable_Done *done) { Py_Accepter_Enable_Done *pydone = NULL; if (done) pydone = new Py_Accepter_Enable_Done(done); try { self->set_callback_enable(enabled, (Accepter_Enable_Done *) pydone); } catch (...) { if (pydone) delete pydone; throw; } } void set_event_handler(Accepter_Event *cb) { Accepter_Event *old_cb = self->get_cb(); if (cb) { Swig::Director *d = dynamic_cast(cb); if (d) pydirobj_incref(d); } self->set_event_handler(cb); if (old_cb) { Swig::Director *d = dynamic_cast(old_cb); if (d) pydirobj_decref(d); } } %newobject str_to_gensio; Gensio *str_to_gensio(std::string str, Event *cb) { Gensio *g = self->str_to_gensio(std::move(str), cb); if (cb) { Swig::Director *d = dynamic_cast(cb); if (d) pydirobj_incref(d); } if (g) g->raw_event_handler = new Py_Raw_Event_Handler(g->raw_event_handler); return g; } %rename(control) controlt; int control(int depth, bool get, unsigned int option, std::vector &controldata) { int rv; char *rdata = NULL; gensiods glen = 0, slen = 0; slen = controldata.size(); if (get) { /* Pass in a zero length to get the actual length. */ rv = self->control(depth, get, option, (char *) controldata.data(), &glen); if (rv) goto out; /* Allocate the larger of constroldata.size() and glen) */ if (slen > glen) { rdata = (char *) malloc(slen + 1); glen = slen; } else { rdata = (char *) malloc(glen + 1); } if (!rdata) { rv = GE_NOMEM; goto out; } rdata[glen] = '\0'; rdata[slen] = '\0'; glen += 1; memcpy(rdata, controldata.data(), slen); rv = self->control(depth, get, option, rdata, &glen); if (rv) { free(rdata); rdata = NULL; glen = 0; } out: if (!rv) controldata.assign(rdata, rdata + glen); free(rdata); } else { rv = self->control(depth, get, option, (char *) controldata.data(), &slen); controldata.resize(0); } return rv; } } //////////////////////////////////////////////////// // MDNS handling %rename("") gensios::MDNS::free; %rename("") gensios::MDNS::add_watch; %rename("") gensios::MDNS::add_service; %extend gensios::MDNS { void free(MDNS_Free_Done *done) { Py_MDNS_Free_Done *pydone = new Py_MDNS_Free_Done(done); self->free((Py_MDNS_Free_Done *) pydone); } %newobject add_watch; MDNS_Watch *add_watch(int interfacenum, int ipdomain, char *name, char *type, char *domain, char *host, MDNS_Watch_Event *event) { Raw_MDNS_Event_Handler *evh = new Py_Raw_MDNS_Event_Handler; MDNS_Watch *w = self->add_watch(interfacenum, ipdomain, name, type, domain, host, event, evh); if (!w) delete evh; return w; } %newobject add_service; MDNS_Service *add_service(int interfacenum, int ipdomain, char *name, char *type, char *domain, char *host, int port, const char *const *txt, MDNS_Service_Event *event) { Raw_MDNS_Service_Event_Handler *evh = new Py_Raw_MDNS_Service_Event_Handler; MDNS_Service *s = self->add_service(interfacenum, ipdomain, name, type, domain, host, port, txt, event, evh); if (!s) delete evh; return s; } } %rename("") gensios::MDNS_Watch::free; %extend gensios::MDNS_Watch { void free(MDNS_Watch_Free_Done *done) { Py_MDNS_Watch_Free_Done *pydone = new Py_MDNS_Watch_Free_Done(done); self->free((Py_MDNS_Watch_Free_Done *) pydone); } } //////////////////////////////////////////////////// // Define our own Waiter function. %rename("") gensios::Waiter::wait; %extend gensios::Waiter { int wait(unsigned int count, gensio_time *timeout) { int rv; Waiter *prev_waiter = save_waiter(self); do { GENSIO_SWIG_C_BLOCK_ENTRY rv = self->wait(count, timeout, true); GENSIO_SWIG_C_BLOCK_EXIT if (rv == GE_TIMEDOUT) break; if (check_for_err(rv)) { if (prev_waiter) prev_waiter->wake(); break; } if (rv == GE_INTERRUPTED) continue; break; } while(true); restore_waiter(prev_waiter); return rv; } int service(gensio_time *timeout) { int err; Waiter *prev_waiter = save_waiter(self); Os_Funcs o = self->get_os_funcs(); do { GENSIO_SWIG_C_BLOCK_ENTRY err = gensio_os_funcs_service(o, timeout); GENSIO_SWIG_C_BLOCK_EXIT if (check_for_err(err)) { if (prev_waiter) prev_waiter->wake(); break; } if (err == GE_INTERRUPTED) continue; break; } while(true); restore_waiter(prev_waiter); return err; } } int gensio_num_alloced(); gensio-3.0.0/c++/swig/pygensio/include/0000775000175000017500000000000015061121734013342 5gensio-3.0.0/c++/swig/pygensio/include/Makefile.in0000664000175000017500000005461215061121657015343 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = c++/swig/pygensio/include ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = gensio all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/swig/pygensio/include/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/swig/pygensio/include/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/c++/swig/pygensio/include/Makefile.am0000664000175000017500000000002214664224267015325 SUBDIRS = gensio gensio-3.0.0/c++/swig/pygensio/include/gensio/0000775000175000017500000000000015061121734014626 5gensio-3.0.0/c++/swig/pygensio/include/gensio/Makefile.in0000664000175000017500000005076715061121657016636 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = c++/swig/pygensio/include/gensio ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(pkginclude_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkgincludedir)" HEADERS = $(pkginclude_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkginclude_HEADERS = pygensio.h all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/swig/pygensio/include/gensio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/swig/pygensio/include/gensio/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkgincludeHEADERS: $(pkginclude_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ done uninstall-pkgincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pkgincludeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkgincludeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool cscopelist-am ctags ctags-am distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkgincludeHEADERS install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-pkgincludeHEADERS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/c++/swig/pygensio/include/gensio/pygensio.h0000664000175000017500000000336214664224267016575 #ifndef __PYGENSIO_H__ #define __PYGENSIO_H__ // Increment/decrement refcount for object contained in directors. // If the python code passed a reference in then loses all it's // reference to it, we want to make sure it still hangs around. void pydirobj_incref(Swig::Director *dir) { PyObject *po = dir->swig_get_self(); /* Make sure it's not deleted if python loses all references. */ Py_INCREF(po); } void pydirobj_decref(Swig::Director *dir) { PyObject *po = dir->swig_get_self(); /* Make sure it's not deleted if python loses all references. */ Py_DECREF(po); } class Internal_Log_Handler : public gensios::Os_Funcs_Log_Handler { public: Internal_Log_Handler(gensios::Os_Funcs_Log_Handler *pyhandler) : handler(pyhandler) { incref(); } virtual ~Internal_Log_Handler() { decref(); } void set_handler(gensios::Os_Funcs_Log_Handler *pyhandler) { decref(); handler = pyhandler; incref(); } void log(enum gensios::gensio_log_levels level, const std::string log) override { // Hack. If there is a python error, the call to the log // function will always fail because this error is not // cleared and SWIG will think the log call failed. This // will print some useful information and clear the error // log. PyErr_Print(); if (handler) handler->log(level, log); } private: void decref() { if (handler) { Swig::Director *pydir_obj = dynamic_cast(handler); if (pydir_obj) pydirobj_decref(pydir_obj); } } void incref() { if (handler) { Swig::Director *pydir_obj = dynamic_cast(handler); if (pydir_obj) pydirobj_incref(pydir_obj); } } gensios::Os_Funcs_Log_Handler *handler; }; #endif /* __PYGENSIO_H__ */ gensio-3.0.0/c++/swig/pygensio/include/gensio/Makefile.am0000664000175000017500000000004114664224267016612 pkginclude_HEADERS = pygensio.h gensio-3.0.0/c++/swig/include/0000775000175000017500000000000015061121734011505 5gensio-3.0.0/c++/swig/include/Makefile.in0000664000175000017500000004023515061121657013502 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = c++/swig/include ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = gensio_base.i all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/swig/include/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/swig/include/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/c++/swig/include/gensio_base.i0000664000175000017500000002116215045153771014067 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only // This is base code that all target lagnages should need. %{ #include #include #include using namespace gensios; %} %include %include %feature("director") gensios::Os_Funcs_Log_Handler; %feature("director") gensios::Event; %feature("director") gensios::Gensio_Open_Done; %feature("director") gensios::Gensio_Close_Done; %feature("director") gensios::Gensio_Control_Done; %feature("director") gensios::Serial_Event; %feature("director") gensios::Serial_Op_Done; %feature("director") gensios::Serial_Op_Sig_Done; %feature("director") gensios::Accepter_Event; %feature("director") gensios::Accepter_Shutdown_Done; %feature("director") gensios::Accepter_Enable_Done; %feature("director") gensios::MDNS_Free_Done; %feature("director") gensios::MDNS_Service_Event; %feature("director") gensios::MDNS_Watch_Free_Done; %feature("director") gensios::MDNS_Watch_Event; %define GENSIOCPP_DLL_PUBLIC %enddef %define GENSIO_DLL_PUBLIC %enddef %define GENSIO_FUNC_DEPRECATED %enddef %ignore gensios::gensio_error; //////////////////////////////////////////////////// // Os_Funcs %catches(gensios::gensio_error) gensios::Os_Funcs::Os_Funcs; %catches(gensios::gensio_error) gensios::Os_Funcs::proc_setup; %ignore gensios::Os_Funcs::get_log_handler; %ignore gensios::Os_Funcs::init; %ignore gensios::Os_Funcs::operator=; %ignore gensios::Os_Funcs::operator struct gensio_os_funcs*; // FIXME - ignore proc_setup? %ignore gensios::Os_Funcs::get_proc_data; //////////////////////////////////////////////////// // Addr %catches(gensios::gensio_error) gensios::Addr::Addr; %catches(gensios::gensio_error) gensios::Addr::to_string; %catches(gensios::gensio_error) gensios::Addr::to_string_all; %ignore gensios::Addr::Addr(Os_Funcs &o, int nettype, const void *iaddr, gensiods len, unsigned int port); %ignore gensios::Addr::Addr(struct gensio_addr *iaddr); %ignore gensios::Addr::operator=; %ignore gensios::Addr::operator struct gensio_addr*; %ignore gensios::Addr::getaddr; //////////////////////////////////////////////////// // Event // Each language will have to provide a typemap for SimpleUCharVector %ignore gensios::SimpleUCharVector; %ignore gensios::SimpleUCharVector::operator[]; %ignore gensios::Raw_Event_Handler; //////////////////////////////////////////////////// // Allocators %catches(gensios::gensio_error) gensios::gensio_alloc; %ignore gensios::GensioW; //////////////////////////////////////////////////// // Gensio // Ignore the normal destructor, it's protected. %extend gensios::Gensio { ~Gensio() { self->free(); } } %ignore gensios::Gensio::~Gensio(); // We supply our own destructor %ignore gensios::Gensio::free; // Only allow the vector versions of write() %ignore gensios::Gensio::write(const void *data, gensiods datalen, const char *const *auxdata); %ignore gensios::Gensio::write(const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata); %ignore gensios::Gensio::write_s(gensiods *count, const void *data, gensiods datalen, gensio_time *timeout = NULL, bool intr = false); %ignore gensios::Gensio::write_s(gensiods *count, const std::vector data, gensio_time *timeout = NULL, bool intr = false); %ignore gensios::Gensio::get_os_funcs(); %ignore gensios::Gensio::get_cb(); %ignore gensios::Gensio::get_gensio(); %ignore gensios::Gensio::raw_event_handler; %ignore gensios::Gensio::user_data; %catches(gensios::gensio_error) gensios::Gensio::open; %catches(gensios::gensio_error) gensios::Gensio::open_s; %catches(gensios::gensio_error) gensios::Gensio::open_nochild; %catches(gensios::gensio_error) gensios::Gensio::open_nochild_s; %catches(gensios::gensio_error) gensios::Gensio::write; %catches(gensios::gensio_error) gensios::Gensio::write_s; %catches(gensios::gensio_error) gensios::Gensio::read_s; %catches(gensios::gensio_error) gensios::Gensio::alloc_channel; %catches(gensios::gensio_error) gensios::Gensio::close; %catches(gensios::gensio_error) gensios::Gensio::close_s; %catches(gensios::gensio_error) gensios::Gensio::read; %catches(gensios::gensio_error) gensios::Gensio::read_s; %catches(gensios::gensio_error) gensios::Gensio::control; %newobject gensios::Gensio::get_child; %newobject gensios::Gensio::alloc_channel; %newobject gensios::Gensio::gensio_alloc; %newobject gensios::Gensio::gensio_acc_alloc; //////////////////////////////////////////////////// // Accepter // Constructor is deleted. %extend gensios::Accepter { ~Accepter() { self->free(); } } %ignore gensios::Accepter::~Accepter; %ignore gensios::Accepter::get_os_funcs; %ignore gensios::Accepter::get_cb; %ignore gensios::Accepter::raw_event_handler; %ignore gensios::Accepter::user_data; %ignore gensios::AccepterW; %catches(gensios::gensio_error) gensios::Accepter::startup; %catches(gensios::gensio_error) gensios::Accepter::shutdown; %catches(gensios::gensio_error) gensios::Accepter::shutdown_s; %catches(gensios::gensio_error) gensios::Accepter::set_callback_enable; %catches(gensios::gensio_error) gensios::Accepter::set_callback_enable_s; %catches(gensios::gensio_error) gensios::Accepter::control; %catches(gensios::gensio_error) gensios::Accepter::accept_s; %catches(gensios::gensio_error) gensios::Accepter::str_to_gensio; %catches(gensios::gensio_error) gensios::Accepter::get_port; %catches(gensios::gensio_error) gensios::gensio_acc_alloc; %newobject gensios::Accepter::str_to_gensio; //////////////////////////////////////////////////// // MDNS %extend gensios::MDNS { ~MDNS() { self->free(NULL); } } %ignore gensios::MDNS::~MDNS; %extend gensios::MDNS_Watch { ~MDNS_Watch() { self->free(NULL); } } %extend gensios::MDNS_Service { ~MDNS_Service() { self->free(); } } %ignore gensios::MDNS::~MDNS; %ignore gensios::MDNS_Watch::~MDNS_Watch; %ignore gensios::MDNS_Service::~MDNS_Service; %delobject gensios::MDNS::free; %delobject gensios::MDNS_Watch::free; %delobject gensios::MDNS_Service::free; %ignore gensios::MDNS_Watch::raw_event_handler; %ignore gensios::MDNS_Service::raw_event_handler; %ignore gensios::Raw_MDNS_Event_Handler; %newobject gensios::MDNS::alloc_watch; %newobject gensios::MDNS::alloc_service; //////////////////////////////////////////////////// // gensio_err.h %ignore gensio_i_os_err_to_err; //////////////////////////////////////////////////// // A bunch of friend functions that we need to ignore. %ignore gensios::gensio_cpp_vlog_handler; %ignore gensios::gensio_alloc(struct gensio *io, Os_Funcs &o); %ignore gensios::gensio_acc_alloc(struct gensio_accepter *acc, Os_Funcs &o); %ignore gensios::gensio_add_class; %ignore gensios::gensio_cpp_freed; %ignore gensios::gensio_acc_cpp_freed; %ignore gensios::mdns_free_done; %ignore gensios::mdns_service_event; %ignore gensios::mdns_watch_done; %ignore gensios::mdns_watch_event; %ignore gensios::mdns_watch_free_done; //////////////////////////////////////////////////// // We need gensio_time and gensiods from here. %ignore ""; %rename("%s") gensio_time; %rename("%s") gensio_time::secs; %rename("%s") gensio_time::nsecs; %rename("%s") gensio_log_levels; %rename("%s", regextarget=1) "GENSIO_LOG_.*"; %rename("%s") gensiods; %include %rename("%s") ""; //////////////////////////////////////////////////// // gensio_time %extend gensio_time { gensio_time(long secs, int nsecs) { struct gensio_time *t = new gensio_time; t->secs = secs; t->nsecs = nsecs; return t; } } //////////////////////////////////////////////////// // Pull some constants from gensio_addr.h %ignore ""; %rename("%s", regextarget=1) "GENSIO_NETTYPE_.*"; #define GENSIOOSH_DLL_PUBLIC // swig is not getting these defined right %include %rename("%s") ""; //////////////////////////////////////////////////// // Pull some constants from gensio_mdns.h %ignore ""; %rename("%s") gensio_mdns_data_state; %rename("%s", regextarget=1) "GENSIO_MDNS_WATCH_.*"; %rename("%s") gensio_mdns_service_event; %rename("%s", regextarget=1) "GENSIO_MDNS_SERVICE_.*"; %include %rename("%s") ""; //////////////////////////////////////////////////// // Pull some constants from gensio.h %ignore ""; %rename("%s", regextarget=1) "GENSIO_SER_.*"; %include %rename("%s") ""; const char *gensio_parity_to_str(unsigned int ival); int gensio_str_to_parity(const char *sval); const char *gensio_flowcontrol_to_str(unsigned int ival); int gensio_str_to_flowcontrol(const char *sval); const char *gensio_onoff_to_str(unsigned int ival); int gensio_str_to_onoff(const char *sval); gensio-3.0.0/c++/swig/include/Makefile.am0000664000175000017500000000003314664224267013472 EXTRA_DIST = gensio_base.i gensio-3.0.0/c++/Makefile.am0000664000175000017500000000014614664224267011103 SUBDIRS = include lib $(SWIG_CPP_DIR) tests examples DIST_SUBDIRS = include lib swig tests examples gensio-3.0.0/c++/include/0000775000175000017500000000000015061121734010534 5gensio-3.0.0/c++/include/Makefile.in0000664000175000017500000005454015061121657012535 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = c++/include ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = gensio all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/include/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/include/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/c++/include/Makefile.am0000664000175000017500000000002214664224267012517 SUBDIRS = gensio gensio-3.0.0/c++/include/gensio/0000775000175000017500000000000015061121734012020 5gensio-3.0.0/c++/include/gensio/Makefile.in0000664000175000017500000005101715061121657014015 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = c++/include/gensio ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(pkginclude_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkgincludedir)" HEADERS = $(pkginclude_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkginclude_HEADERS = gensioosh gensio gensiomdns \ gensioosh_dllvisibility gensio_dllvisibility all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/include/gensio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/include/gensio/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkgincludeHEADERS: $(pkginclude_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ done uninstall-pkgincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pkgincludeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkgincludeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool cscopelist-am ctags ctags-am distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkgincludeHEADERS install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-pkgincludeHEADERS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/c++/include/gensio/gensio_dllvisibility0000664000175000017500000000223114664224267016125 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #ifndef GENSIOCPP_DLLVISIBILITY #define GENSIOCPP_DLLVISIBILITY #if defined GENSIO_LINK_STATIC #define GENSIOCPP_DLL_PUBLIC #define GENSIOCPP_DLL_LOCAL #elif defined _WIN32 || defined __CYGWIN__ #ifdef BUILDING_GENSIOCPP_DLL #ifdef __GNUC__ #define GENSIOCPP_DLL_PUBLIC __attribute__ ((dllexport)) #else #define GENSIOCPP_DLL_PUBLIC __declspec(dllexport) // Note: actually gcc seems to also supports this syntax. #endif #else #ifdef __GNUC__ #define GENSIOCPP_DLL_PUBLIC __attribute__ ((dllimport)) #else #define GENSIOCPP_DLL_PUBLIC __declspec(dllimport) // Note: actually gcc seems to also supports this syntax. #endif #endif #define GENSIOCPP_DLL_LOCAL #else #if __GNUC__ >= 4 #define GENSIOCPP_DLL_PUBLIC __attribute__ ((visibility ("default"))) #define GENSIOCPP_DLL_LOCAL __attribute__ ((visibility ("hidden"))) #else #define GENSIOCPP_DLL_PUBLIC #define GENSIOCPP_DLL_LOCAL #endif #endif #endif /* GENSIOCPP_DLLVISIBILITY */ gensio-3.0.0/c++/include/gensio/gensiomdns0000664000175000017500000002216414664224267014053 // // gensio - A library for abstracting stream I/O // Copyright (C) 2022 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only // This is a C++ wrapper for the gensio library MDNS interface. #ifndef GENSIOMDNS_CPP_INCLUDE #define GENSIOMDNS_CPP_INCLUDE #if defined GENSIO_LINK_STATIC #define GENSIOMDNSCPP_DLL_PUBLIC #define GENSIOMDNSCPP_DLL_LOCAL #elif defined _WIN32 || defined __CYGWIN__ #ifdef BUILDING_GENSIOMDNSCPP_DLL #ifdef __GNUC__ #define GENSIOMDNSCPP_DLL_PUBLIC __attribute__ ((dllexport)) #else #define GENSIOMDNSCPP_DLL_PUBLIC __declspec(dllexport) // Note: actually gcc seems to also supports this syntax. #endif #else #ifdef __GNUC__ #define GENSIOMDNSCPP_DLL_PUBLIC __attribute__ ((dllimport)) #else #define GENSIOMDNSCPP_DLL_PUBLIC __declspec(dllimport) // Note: actually gcc seems to also supports this syntax. #endif #endif #define GENSIOMDNSCPP_DLL_LOCAL #else #if __GNUC__ >= 4 #define GENSIOMDNSCPP_DLL_PUBLIC __attribute__ ((visibility ("default"))) #define GENSIOMDNSCPP_DLL_LOCAL __attribute__ ((visibility ("hidden"))) #else #define GENSIOMDNSCPP_DLL_PUBLIC #define GENSIOMDNSCPP_DLL_LOCAL #endif #endif namespace gensios { #include // Access to the MDNS code class MDNS; class MDNS_Service; class MDNS_Service_Event; class MDNS_Watch; class MDNS_Watch_Event; // This class is used to know when an MDNS object has finished the // shutdown operation and will not call any more callbacks. class GENSIOMDNSCPP_DLL_PUBLIC MDNS_Free_Done { public: // Called when the shutdown is complete. The mdns object may be // freed when this returns. virtual void mdns_free_done() = 0; virtual ~MDNS_Free_Done() = default; protected: MDNS *m; private: friend void mdns_free_done(struct gensio_mdns *m, void *userdata); friend class MDNS; }; class GENSIOMDNSCPP_DLL_PUBLIC Raw_MDNS_Event_Handler { public: virtual ~Raw_MDNS_Event_Handler() = default; virtual void handle(MDNS_Watch_Event *e, enum gensio_mdns_data_state state, int interfacenum, int ipdomain, const char *name, const char *mtype, const char *domain, const char *host, const struct gensio_addr *addr, const char * const *txt) = 0; virtual void set_parent(Raw_MDNS_Event_Handler *parent) { } }; class GENSIOMDNSCPP_DLL_PUBLIC Raw_MDNS_Service_Event_Handler { public: virtual ~Raw_MDNS_Service_Event_Handler() = default; virtual void handle(MDNS_Service_Event *e, enum gensio_mdns_service_event ev, const char *info) = 0; virtual void set_parent(Raw_MDNS_Service_Event_Handler *parent) { } }; class GENSIOMDNSCPP_DLL_PUBLIC MDNS { public: MDNS(Os_Funcs &o); inline Os_Funcs &get_os_funcs() { return go; } // Functions to allocate a service and a watch. This is the // only way for a user to allocate them. The event is not // required for services, but it makes no sense to have a // watch without an event handler, so it's required there. MDNS_Service *add_service(int interfacenum, int ipdomain, const char *name, const char *mtype, const char *domain, const char *host, int port, const char * const *txt, MDNS_Service_Event *event = NULL, Raw_MDNS_Service_Event_Handler *evh = NULL); MDNS_Watch *add_watch(int interfacenum, int ipdomain, const char *name, const char *mtype, const char *domain, const char *host, MDNS_Watch_Event *event, Raw_MDNS_Event_Handler *evh = NULL); // If you have a raw event handler, you must supply it above. // This avoids race conditions between creating the watch and // installing the new raw event handler. This is not a // problem for gensios because events aren't enabled at // startup, but they are for MDNS watches. // Like a gensio, you cannot directly delete an MDNS object. // It may be in callbacks. You have to go through a special // free operation. See the Gensio free() method for details. void free(MDNS_Free_Done *done = NULL); protected: virtual ~MDNS() { } Os_Funcs go; private: struct gensio_mdns *m; friend class MDNS_Service; friend class MDNS_Watch; friend void mdns_free_done(struct gensio_mdns *m, void *userdata); }; // This handles events from an mdns service informing you that it // has has finished registration, the name has changed, or that it // is removed. Analogous to gensio_mdns_service_cb, see the // gensio_mdns_add_service2() man page for details. class GENSIOMDNSCPP_DLL_PUBLIC MDNS_Service_Event { public: virtual void event(enum gensio_mdns_service_event ev, const char *info) = 0; virtual ~MDNS_Service_Event() = default; private: MDNS_Service *s = NULL; friend class MDNS_Service; friend void mdns_service_event(struct gensio_mdns_service *s, enum gensio_mdns_service_event ev, const char *info, void *userdata); }; // A class representing an MDNS service. A wrapper around // gensio_mdns_add/remove_service(), see man pages on those // functions for details. class GENSIOMDNSCPP_DLL_PUBLIC MDNS_Service { public: inline Os_Funcs &get_os_funcs() { return m->get_os_funcs(); } // Like a gensio, you cannot directly delete an MDNS_Service // object. It may be in callbacks. You have to go through a // special free operation. See the Gensio free() method for // details. Unlike a watch, the done callback goes through // the event handler registered in MDNS_Service, if you // registered one. That is unfortunate, but is that way due // to historical reasons. void free(); // This allows the user to intercept raw events, it is primarily // used to help other language bindings tie in things they need. Raw_MDNS_Service_Event_Handler *raw_event_handler = NULL; protected: friend class MDNS; MDNS_Service(MDNS *m, int interfacenum, int ipdomain, const char *name, const char *mtype, const char *domain, const char *host, int port, const char * const *txt, MDNS_Service_Event *event = NULL, Raw_MDNS_Service_Event_Handler *raw_event_handler = NULL); virtual ~MDNS_Service() { if (raw_event_handler) delete raw_event_handler; } private: MDNS *m; struct gensio_mdns_service *s; MDNS_Service_Event *event = NULL; friend void mdns_service_event(struct gensio_mdns_service *s, enum gensio_mdns_service_event ev, const char *info, void *userdata); }; // This class is used to know when an MDNS_Watch object has // finished the shutdown operation and will not call any more // callbacks. class GENSIOMDNSCPP_DLL_PUBLIC MDNS_Watch_Free_Done { public: // Called when the shutdown is complete. The mdns object may be // freed when this returns. virtual void mdns_watch_free_done() = 0; virtual ~MDNS_Watch_Free_Done() = default; private: MDNS_Watch *w = NULL; friend void mdns_watch_free_done(struct gensio_mdns_watch *w, void *userdata); friend class MDNS_Watch; }; // This handles events from an mdns watch informing you that it // has a new MDNS entry. Analogous to gensio_mdns_watch_cb, see // the gensio_mdns_add_watch() man page for details. class GENSIOMDNSCPP_DLL_PUBLIC MDNS_Watch_Event { public: virtual void event(enum gensio_mdns_data_state state, int interfacenum, int ipdomain, const char *name, const char *mtype, const char *domain, const char *host, const Addr *addr, const char * const *txt) = 0; virtual ~MDNS_Watch_Event() = default; private: MDNS_Watch *w; friend class MDNS_Watch; friend void mdns_watch_event(struct gensio_mdns_watch *w, enum gensio_mdns_data_state state, int interfacenum, int ipdomain, const char *name, const char *mtype, const char *domain, const char *host, const struct gensio_addr *addr, const char * const *txt, void *userdata); }; // A class representing an MDNS service. A wrapper around // gensio_mdns_add/remove_watch(), see man pages on those // functions for details. class GENSIOMDNSCPP_DLL_PUBLIC MDNS_Watch { public: inline Os_Funcs &get_os_funcs() { return m->get_os_funcs(); } // Like a gensio, you cannot directly delete an MDNS_Watch object. // It may be in callbacks. You have to go through a special // free operation. See the Gensio free() method for details. void free(MDNS_Watch_Free_Done *done = NULL); // This allows the user to intercept raw events, it is primarily // used to help other language bindings tie in things they need. Raw_MDNS_Event_Handler *raw_event_handler = NULL; protected: friend class MDNS; MDNS_Watch(MDNS *m, int interfacenum, int ipdomain, const char *name, const char *mtype, const char *domain, const char *host, MDNS_Watch_Event *event, Raw_MDNS_Event_Handler *raw_event_handler = NULL); virtual ~MDNS_Watch() { if (raw_event_handler) delete raw_event_handler; } private: MDNS *m; MDNS_Watch_Event *event; struct gensio_mdns_watch *w; friend void mdns_watch_free_done(struct gensio_mdns_watch *w, void *userdata); }; } #endif gensio-3.0.0/c++/include/gensio/Makefile.am0000664000175000017500000000014214664224267014006 pkginclude_HEADERS = gensioosh gensio gensiomdns \ gensioosh_dllvisibility gensio_dllvisibility gensio-3.0.0/c++/include/gensio/gensioosh0000664000175000017500000002610114666663072013701 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only // This is a C++ wrapper for the gensio library. #ifndef GENSIOOSH_CPP_INCLUDE #define GENSIOOSH_CPP_INCLUDE #include #include #include #include #include namespace gensios { #include #include GENSIOOSHCPP_DLL_PUBLIC std::string err_to_string(int err); // This is an exception that is raised by gensio operations that // get errors. Most operations raise exceptions, unless otherwise // noted. Note that the string is set, so what() will return the // string. You can get the number with get_error(). class gensio_error: public std::runtime_error { public: gensio_error(int ierr): std::runtime_error(gensio_err_to_str(ierr)) { err = ierr; }; int get_error() { return err; }; private: int err; }; // Handle log calls from the low-level gensio system, generally for // things that cannot be reported another way. class GENSIOOSHCPP_DLL_PUBLIC Os_Funcs_Log_Handler { public: virtual void log(enum gensio_log_levels level, const std::string log) = 0; virtual ~Os_Funcs_Log_Handler() = default; }; GENSIOOSHCPP_DLL_PUBLIC std::string log_level_to_str(enum gensio_log_levels level); GENSIOOSHCPP_DLL_PUBLIC void set_log_mask(int mask); GENSIOOSHCPP_DLL_PUBLIC int get_log_mask(); // Used as the startup function for a new thread. class GENSIOOSHCPP_DLL_PUBLIC Os_Funcs_Thread_Func { public: virtual void start() = 0; virtual ~Os_Funcs_Thread_Func() = default; }; // This is a wrapper for gensio_os_funcs that makes using it a lot // cleaner. The default constructor automatically allocates the // default os handler, destruction takes place automatically. // This is a smart pointer like object. class GENSIOOSHCPP_DLL_PUBLIC Os_Funcs { public: // Allocate an os function handlers for the platform. See // gensio_alloc_os_funcs.3 for details. Note that if you pass // in -1 for wait_sig, it will pick the default wait signal, // SIGUSR1 on Unix type systems. // // The logger you pass in here *must* be dynamically // allocated, the Os_Funcs takes over the task of freeing it // when done. This is a little strange, but that way if the // Os_Funcs here gets destroyed and another one outlives it, a // locally allocated logger won't be deleted while still in // use. Os_Funcs(int wait_sig, Os_Funcs_Log_Handler *logger = NULL); Os_Funcs(int wait_sig, Os_Funcs_Log_Handler *logger, unsigned int flags, ...); // This is for use by subclasses. Don't use one with an empty // parameter list, that can be used accidentally. Os_Funcs(bool dummy) { }; void set_log_handler(Os_Funcs_Log_Handler *ilogger) { logger = ilogger; }; Os_Funcs_Log_Handler *get_log_handler() { return logger; }; // Do the setup for the process. If you do this, this should be // the last os funcs to destruct, if you have more than one. See // gensio_os_funcs.3 for details on process setup. void proc_setup(); // Do the setup for the thread. See gensio_os_funcs.3 for details. void thread_setup(); // If you allocate your own subclass of this, you must call // this to set it up. Note that this takes over freeing the // OS handler and the logger. void init(struct gensio_os_funcs *o, Os_Funcs_Log_Handler *logger = NULL); Os_Funcs& operator=(const Os_Funcs &o); Os_Funcs(const Os_Funcs &o); struct gensio_os_proc_data *get_proc_data() { return proc_data; } // Instead of defining all our own functions, which would just // be direct wrapper, we just do this so we return the base os // funcs structure for a ->. struct gensio_os_funcs * operator->() { return osf; } // Automatically convert this object when a struct // gensio_os_funcs is asked for. operator struct gensio_os_funcs * () const { return osf; } virtual ~Os_Funcs(); void log(enum gensio_log_levels level, const std::string log) { gensio_log(osf, level, "%s", log.c_str()); } unsigned int get_refcount() { return *refcnt; } struct gensio_thread *new_thread(Os_Funcs_Thread_Func *start_func); void wait_thread(struct gensio_thread *thread_id); private: void refcount_from(const Os_Funcs *o); Os_Funcs_Log_Handler *logger = NULL; struct gensio_os_funcs *osf = NULL; struct gensio_os_proc_data *proc_data = NULL; std::atomic *refcnt = NULL; }; // A wrapper for the gensio_addr structure. class GENSIOOSHCPP_DLL_PUBLIC Addr { public: // Create a new address structure using the passed in string. // This is basically the same as gensio_scan_network_port() // in gensio.h, see that for details. Addr(Os_Funcs &o, std::string str, bool listen, int *protocol, int *argc, const char ***args); // Scan a string and create an address from it. If the address // is being allocated for an accepter, set listen to true, othersize // set it to false. Protocol must be one of GENSIO_NET_PROTOCOL_XXX. Addr(Os_Funcs &o, std::string str, bool listen, int protocol); // Allocate an address based upon the given passed in address and // port. See gensio_addr_create() in gensio.h for details. Addr(Os_Funcs &o, int nettype, const void *iaddr, gensiods len, unsigned int port); // Allocate an address based on the low-level address. // We assume the port is set in this case. Addr(struct gensio_addr *iaddr) { gaddr = iaddr; is_port_set = true; } // For copying and assignment, we duplicate the low-level // address. Addresses are immutable and refcounted. Addr(Addr &a) { this->gaddr = gensio_addr_dup(a); if (!this->gaddr) throw std::bad_alloc(); this->is_port_set = a.is_port_set; } // Allocate an empty address. You can use the = operator // below to assign it data. Addr() { } Addr & operator=(const Addr &a) { if (this->gaddr) // Address is already assigned. throw gensio_error(GE_INUSE); this->gaddr = gensio_addr_dup(a); if (!this->gaddr) throw std::bad_alloc(); this->is_port_set = a.is_port_set; return *this; } // Automatically convert to a low-level address operator struct gensio_addr * () const { return gaddr; } virtual ~Addr(); // See gensio_addr_xxx functions in gensio.h for details on these. void rewind() { gensio_addr_rewind(gaddr); } bool next() { return gensio_addr_next(gaddr); } void getaddr(void *oaddr, gensiods *len) const { gensio_addr_getaddr(gaddr, oaddr, len); } void getaddr(std::vector &rvec); void get_data(void *oaddr, gensiods *len) const { gensio_addr_get_data(gaddr, oaddr, len); } void get_data(std::vector &rvec); int get_nettype() const { return gensio_addr_get_nettype(gaddr); } int get_port() const { return gensio_addr_get_port(gaddr); } bool family_supports(int family, int flags) const { return gensio_addr_family_supports(gaddr, family, flags); } std::string to_string() const; std::string to_string_all() const; inline bool operator==(const Addr &a2) const { return gensio_addr_equal(*this, a2, true, false); } bool equal(const Addr &a2, bool compare_ports, bool compare_all) const { return gensio_addr_equal(*this, a2, compare_ports, compare_all); } bool addr_present(const void *addr, gensiods addrlen, bool compare_ports) const { return gensio_addr_addr_present(*this, addr, addrlen, compare_ports); } bool port_set() const { return is_port_set; } private: struct gensio_addr *gaddr = NULL; bool is_port_set = false; }; //***************************************************************** // This is a waiter class. You use one of these to wait for // things while running the event-driven code. class GENSIOOSHCPP_DLL_PUBLIC Waiter { public: Waiter(Os_Funcs &io); ~Waiter(); // Add one wakeup to the waiter. void wake(); // Wait for count wakeups to be delivered to the waiter, up to // timeout time. If the timeout occurs before count events // are delivered, none of the wakeups are used. If timeout is // NULL, wait forever. This will return either 0 if woken or // GE_TIMEDOUT if not woken before the timeout. If intr is // true it will return GE_INTERRUPTED if a signal comes in. // Any other error will result in a gensio_error being thrown. int wait(unsigned int count, gensio_time *timeout = NULL, bool intr = false); Os_Funcs get_os_funcs() { return o; } private: Os_Funcs o; struct gensio_waiter *waiter; }; // Retrieve and view network interfaces on the system. class GENSIOOSHCPP_DLL_PUBLIC Net_Ifs { public: Net_Ifs(Os_Funcs *ino): o(ino) { int rv = gensio_os_get_net_ifs(*o, &ifs, &nifs); if (rv) throw std::bad_alloc(); } ~Net_Ifs() { gensio_os_free_net_ifs(*o, ifs, nifs); } unsigned int get_num_ifs() { return this->nifs; } std::string get_name(unsigned int index) { if (index >= this->nifs) throw gensio_error(GE_OUTOFRANGE); return std::string(this->ifs[index]->name); } bool is_up(unsigned int index) { if (index >= this->nifs) throw gensio_error(GE_OUTOFRANGE); return !!(this->ifs[index]->flags & GENSIO_NET_IF_UP); } bool is_loopback(unsigned int index) { if (index >= this->nifs) throw gensio_error(GE_OUTOFRANGE); return !!(this->ifs[index]->flags & GENSIO_NET_IF_LOOPBACK); } bool is_multicast(unsigned int index) { if (index >= this->nifs) throw gensio_error(GE_OUTOFRANGE); return !!(this->ifs[index]->flags & GENSIO_NET_IF_MULTICAST); } unsigned int get_ifindex(unsigned int index) { if (index >= this->nifs) throw gensio_error(GE_OUTOFRANGE); return this->ifs[index]->ifindex; } unsigned int get_num_addrs(unsigned int index) { if (index >= this->nifs) throw gensio_error(GE_OUTOFRANGE); return this->ifs[index]->naddrs; } unsigned int get_addr_netbits(unsigned int index, unsigned int addridx) { if (index >= this->nifs || addridx > this->ifs[index]->naddrs) throw gensio_error(GE_OUTOFRANGE); return this->ifs[index]->addrs[addridx].netbits; } unsigned int get_addr_family(unsigned int index, unsigned int addridx) { if (index >= this->nifs || addridx > this->ifs[index]->naddrs) throw gensio_error(GE_OUTOFRANGE); return this->ifs[index]->addrs[addridx].family; } std::vector get_addr(unsigned int index, unsigned int addridx) { if (index >= this->nifs || addridx > this->ifs[index]->naddrs) throw gensio_error(GE_OUTOFRANGE); struct gensio_net_addr *a = &(this->ifs[index]->addrs[addridx]); return std::vector(a->addr, a->addr + sizeof(a->addr)); } std::string get_addrstr(unsigned int index, unsigned int addridx) { if (index >= this->nifs || addridx > this->ifs[index]->naddrs) throw gensio_error(GE_OUTOFRANGE); return std::string(this->ifs[index]->addrs[addridx].addrstr); } private: Os_Funcs *o; struct gensio_net_if **ifs; unsigned int nifs; }; } #endif /* GENSIOOSH_CPP_INCLUDE */ gensio-3.0.0/c++/include/gensio/gensioosh_dllvisibility0000664000175000017500000000230614664224267016642 /* * gensio - A library for abstracting stream I/O * Copyright (C) 2018 Corey Minyard * * SPDX-License-Identifier: LGPL-2.1-only */ #ifndef GENSIOOSHCPP_DLLVISIBILITY #define GENSIOOSHCPP_DLLVISIBILITY #if defined GENSIO_LINK_STATIC #define GENSIOOSHCPP_DLL_PUBLIC #define GENSIOOSHCPP_DLL_LOCAL #elif defined _WIN32 || defined __CYGWIN__ #ifdef BUILDING_GENSIOOSHCPP_DLL #ifdef __GNUC__ #define GENSIOOSHCPP_DLL_PUBLIC __attribute__ ((dllexport)) #else #define GENSIOOSHCPP_DLL_PUBLIC __declspec(dllexport) // Note: actually gcc seems to also supports this syntax. #endif #else #ifdef __GNUC__ #define GENSIOOSHCPP_DLL_PUBLIC __attribute__ ((dllimport)) #else #define GENSIOOSHCPP_DLL_PUBLIC __declspec(dllimport) // Note: actually gcc seems to also supports this syntax. #endif #endif #define GENSIOOSHCPP_DLL_LOCAL #else #if __GNUC__ >= 4 #define GENSIOOSHCPP_DLL_PUBLIC __attribute__ ((visibility ("default"))) #define GENSIOOSHCPP_DLL_LOCAL __attribute__ ((visibility ("hidden"))) #else #define GENSIOOSHCPP_DLL_PUBLIC #define GENSIOOSHCPP_DLL_LOCAL #endif #endif #endif /* GENSIOOSHCPP_DLLVISIBILITY */ gensio-3.0.0/c++/include/gensio/gensio0000664000175000017500000006276215045153771013174 // // gensio - A library for abstracting stream I/O // Copyright (C) 2021 Corey Minyard // // SPDX-License-Identifier: LGPL-2.1-only // This is a C++ wrapper for the gensio library. #ifndef GENSIO_CPP_INCLUDE #define GENSIO_CPP_INCLUDE #include #include #include #include //#include namespace gensios { // Incuding this in the gensio namespace to keep things neat. #include // This is a simple vector of unsigned chars, we use it to pass // data to the read() call to avoid copying the data. class GENSIOCPP_DLL_PUBLIC SimpleUCharVector { public: SimpleUCharVector() { } SimpleUCharVector(unsigned char *idata, gensiods ilen) { buffer = idata; len = ilen; datalen = ilen; } virtual ~SimpleUCharVector() { } gensiods size() const { return len; } void resize(gensiods ilen) { len = ilen; } gensiods capacity() const { return datalen; } unsigned char *data() const { return buffer; } unsigned char operator[](gensiods pos) const { return buffer[pos]; } void setbuf(unsigned char *ibuffer, gensiods ilen) { buffer = ibuffer; len = ilen; datalen = ilen; }; private: unsigned char *buffer = NULL; gensiods len = 0; gensiods datalen = 0; }; class Gensio; class Serial_Gensio; // This is an abstract class to be passed into a gensio class for // delivery of events from the gensio. class GENSIOCPP_DLL_PUBLIC Event { public: // Data from the gensio is delivered in this callback. You // must implement this. virtual gensiods read(int err, const SimpleUCharVector data, const char *const *auxdata) = 0; // Data can be written to the gensio. You must implement this. virtual void write_ready() = 0; // A new channel is available on the gensio. By default this // deletes the new channel. virtual int new_channel(Gensio *newg, const char *const *auxdata); // The remote end has requested that the receiver of this do a // break. This is primarily for a telnet server that is // hooked to a serial port, if it receives this it should send // a break on the serial port. By default this does nothing. virtual void send_break() { }; // Various authentication operations. See gensio_event.3 for // details on what these do. virtual int auth_begin() { return GE_NOTSUP; } virtual int precert_verify() { return GE_NOTSUP; } virtual int postcert_verify(int err, const char *errstr) { return GE_NOTSUP; } virtual int password_verify(const std::string val) { return GE_NOTSUP; } virtual int request_password(gensiods maxsize, std::string &retval) { return GE_NOTSUP; } virtual int verify_2fa(const std::vector data) { return GE_NOTSUP; } virtual int request_2fa(std::vector &retval) { return GE_NOTSUP; } // A gensio that is non-standard may generate events for its // own purposes; these events have event numbers that fall // into a range defined in gensio.h. These events will be // delivered here. virtual int user_event(int event, int err, std::vector &userdata, const char *const *auxdata) { return GE_NOTSUP; } // The free() operation for gensio this object is assigned to // has finished and the data will immediately be freed. This // is generally where you would free the event handler for a // gensio. Obviously, the Event object here must stay around // until the Gensio is freed. virtual void freed() { }; virtual ~Event() = default; // Errors from parameter parsing come in here. virtual void parmlog(const std::string log) { } // Window size events come in here. virtual void win_size(unsigned int height, unsigned int width) { } // General logs on running gensios come in here. virtual int log(enum gensio_log_levels level, const std::string log) { return GE_NOTSUP; } // See gensio_event.3 and gensio_acontrol.3 for details virtual void modemstate(unsigned int state) { } // See gensio_event.3 and gensio_acontrol.3 for details virtual void linestate(unsigned int state) { } virtual void flow_state(bool state) { } virtual void sync() { } // Server side calls, used when the client requests changes. // See GENSIO_ACONTROL_SER_xxx. virtual void signature(const std::vector data) { } virtual void flush(unsigned int val) { } virtual void baud(unsigned int speed) { } virtual void datasize(unsigned int size) { } virtual void parity(unsigned int par) { } virtual void stopbits(unsigned int bits) { } virtual void flowcontrol(unsigned int flow) { } virtual void iflowcontrol(unsigned int flow) { } virtual void sbreak(unsigned int sbreak) { } virtual void dtr(unsigned int dtr) { } virtual void rts(unsigned int rts) { } virtual void modemstate_mask(unsigned int state) { } virtual void linestate_mask(unsigned int state) { } }; // Used for done handlers for gensio operations that can fail, // failure is returned in the err field. class GENSIOCPP_DLL_PUBLIC Gensio_Open_Done { public: virtual void open_done(int err) = 0; virtual ~Gensio_Open_Done() = default; }; // Used for done handlers for gension operations that cannot fail. class GENSIOCPP_DLL_PUBLIC Gensio_Close_Done { public: virtual void close_done() = 0; virtual ~Gensio_Close_Done() = default; }; // Used for done handlers for acontrol callbacks class GENSIOCPP_DLL_PUBLIC Gensio_Control_Done { public: virtual void control_done(int err, const std::vector data) = 0; virtual ~Gensio_Control_Done() = default; }; // Allocate a gensio based upon the given string. The string // format is defiend in gensio.5. You must provided an os // function handler as described in gensio_os_funcs.3 and an event // handler defined above. // // Note that will return a subclass of Gensio depending on the // particular string provided. GENSIOCPP_DLL_PUBLIC Gensio *gensio_alloc(std::string str, Os_Funcs &o, Event *cb = NULL); // Like the above, but stacks the newly created gensio as defined // by str on top of the given gensio. This can be used to // dynamically add gensios to a gensio stack. GENSIOCPP_DLL_PUBLIC Gensio *gensio_alloc(Gensio *child, std::string str, Os_Funcs &o, Event *cb = NULL); // Allocate a terminal gensio GENSIOCPP_DLL_PUBLIC Gensio *gensio_alloc(const char *gensiotype, const void *gdata, const char * const args[], Os_Funcs &o, Event *cb = NULL); // For internal use only. Gensio *gensio_alloc(struct gensio *io, Os_Funcs &o); class GENSIOCPP_DLL_PUBLIC Raw_Event_Handler { public: virtual ~Raw_Event_Handler() = default; virtual int handle(Gensio *g, struct gensio *io, int event, int err, unsigned char *buf, gensiods *buflen, const char *const *auxdata) = 0; // New channels are routed through here so they can be set up properly. virtual int new_channel(Event *e, Gensio *new_chan, const char *const *auxdata) = 0; // Final free calls come through here. virtual void freed(Event *e) = 0; }; // This is a gensio, the central class in the gensio framework. // This is the thing that you use to send/receive data and control // various operations of the gensio. class GENSIOCPP_DLL_PUBLIC Gensio { public: Gensio(const Gensio&) = delete; Gensio &operator=(const Gensio&) = delete; // Unfortunately, you can't use the destructor with this class // because of race conditions. When you call this, there may // be other things pending in callbacks, and there's no way to // delay the free of the object in a destructor without // blocking. So you call free here, and when the freed // function in the event handler gets called, the free is // complete. void free(); // Change the event handler for a gensio. This is provided so // gensios delivered via new_channel() or in an accepter can // get their event handlers set. It's a bad idea to change // the event handler on a running gensio. inline void set_event_handler(Event *cb = NULL) { gcb = cb; } // Open a gensio. When the done handler is called it is ready // (unless it reports an error). void open(Gensio_Open_Done *done); // Open a gensio and wait for it's open peration to complete. void open_s(); // Open a gensio but assume that it's children are already // open. This is used if you stacked a new gensio on top of a // running stack. void open_nochild(Gensio_Open_Done *done); // Like the above, but synchronous. void open_nochild_s(); // Write datalen bytes of data to the given gensio. The // actual number of bytes written is returned. The // meaning of auxdata depends on the gensio, see gensio.5 for // detais. gensiods write(const void *data, gensiods datalen, const char *const *auxdata); gensiods write(const std::vector data, const char *const *auxdata); gensiods write(const SimpleUCharVector data, const char *const *auxdata); // Like the above, but use a scatter-gather structure to write // the data. gensiods write(const struct gensio_sg *sg, gensiods sglen, const char *const *auxdata); // Allocate a new channel for the gensio based upon the given // arguments, and use the given event handler for it. How // this works depends on the particular gensio, see gensio.5 // for details. Gensio *alloc_channel(const char *const *args, Event *cb = NULL); // Close the given gensio. When the close completely call the // done handler. void close(Gensio_Close_Done *done = NULL); // Like the above, but do it synchronosly. void close_s(); // This is used in specific circumstances to disable a gensio // that cannot function any more. See gensio_disable.3 for // details. inline void disable() { gensio_disable(io); } // A gensio won't deliver any data events until you enable it. // In general, you should run with read enabled unless you // can't handle any more data, and you should run with write // disabled until you write and get an incomplete write. When // you get an incomplete write, you can enable write callback // to know when you can transmit again. Note that if you // disable one of these, there may still be callbacks pending // on the gensio. Don't assume that when this returns there // are no callbacks pending. inline void set_read_callback_enable(bool enabled) { gensio_set_read_callback_enable(io, enabled); } inline void set_write_callback_enable(bool enabled) { gensio_set_write_callback_enable(io, enabled); } // Various control operations on a gensio, see // gensio_control.3 for details. int control(int depth, bool get, unsigned int option, char *data, gensiods *datalen); int acontrol(int depth, bool get, unsigned int option, const char *data, gensiods datalen, Gensio_Control_Done *done = NULL, gensio_time *timeout = NULL); int acontrol_s(int depth, bool get, unsigned int option, char *data, gensiods *datalen, gensio_time *timeout = NULL, bool intr = false); // Return the type of the gensio. If depth is larger than the // stack, returns NULL. inline const char *get_type(unsigned int depth) { return gensio_get_type(io, depth); } // Return various characterstics about a gensio. See the // gensio_is_xxx.3 man pages for details. inline bool is_client() const { return gensio_is_client(io); } inline bool is_reliable() const { return gensio_is_reliable(io); } inline bool is_packet() const { return gensio_is_packet(io); } inline bool is_authenticated() const { return gensio_is_authenticated(io); } inline bool is_encrypted() const { return gensio_is_encrypted(io); } inline bool is_message() const { return gensio_is_message(io); } inline bool is_mux() const { return gensio_is_mux(io); } inline bool is_serial() { return gensio_is_serial(io); } // Turn on/off synchronous mode for a gensio. In synchrohous // mode, the gensio will not deliver data via the read call. // You must call the read_s() functions below to read the data. // See the gensio_set_sync() man page for details. inline void set_sync() { gensio_set_sync(io); } inline void clear_sync() { gensio_clear_sync(io); } // Read data from the gensio in synchronous mode and wait up // to timeout time for the data. The vector's capacity should // be set to the max data to read, the length will be set to // the actual read length. If a timeout occurs, data may still // have been read. If timeout is NULL, wait forever. Note // that this returns if any data is available, even if it is // less than datalen. This will return GE_TIMEDOUT on a // timeout or 0 on success. If intr is true, it will return // GE_INTERRUPTED on a signal. All other errors throw // gensio_error. int read_s(std::vector &rvec, gensio_time *timeout = NULL, bool intr = false); int read_s(SimpleUCharVector &data, gensio_time *timeout = NULL, bool intr = false); // Write data and wait for the write to complete. If the // write does not complete in the time specified by timeout, // returns GE_TIMEDOUT. Note that some data may still have // been written, the amount written is returned in count. If // timeout is NULL, wait forever. If intr is true, a signal // will cause this to return GE_INTERRUPTED. int write_s(gensiods *count, const void *data, gensiods datalen, gensio_time *timeout = NULL, bool intr = false); int write_s(gensiods *count, const std::vector data, gensio_time *timeout = NULL, bool intr = false); int write_s(gensiods *count, const SimpleUCharVector data, gensio_time *timeout = NULL, bool intr = false); // Return the os funcs assigned to a gensio. inline Os_Funcs &get_os_funcs() { return go; } // Return the event handler assigned to a gensio. inline Event *get_cb() { return gcb; } // Return the raw gensio. Don't use this, it's for subclasses // to use. struct gensio *get_gensio() { return io; } // This allows the user to intercept raw events, it is primarily // used to help other language bindings tie in things they need. Raw_Event_Handler *raw_event_handler = NULL; protected: // Subclasses can use this to initialize the gensio object. virtual void set_gensio(struct gensio *io, bool set_cb); Gensio(Os_Funcs &o, Event *cb): go(o), gcb(cb) { } Gensio(struct gensio *iio, Os_Funcs &o): go(o), io(iio) { } virtual ~Gensio() { if (raw_event_handler) delete raw_event_handler; } private: Os_Funcs go; struct gensio *io = NULL; Event *gcb = NULL; friend Gensio *gensio_alloc(struct gensio *io, Os_Funcs &o); friend class Main_Raw_Accepter_Event_Handler; friend void gensio_cpp_freed(struct gensio *io, struct gensio_frdata *frdata); friend class Serial_Gensio; }; // A wrapper to allow RAII to be used on a Gensio. If you use // this, you should either make sure the gensio is closed before // the end of this object's lifetime, or you should not free it // and let this destructor close it. What you should *not* do is // an asynchronous free then call this, because the close here // will fail and then the free won't be done after the destructor // returns. class GENSIOCPP_DLL_PUBLIC GensioW { public: GensioW(std::string str, Os_Funcs &o, Event *cb = NULL) { io = gensio_alloc(std::move(str), o, cb); } GensioW(Gensio *child, std::string str, Os_Funcs &o, Event *cb = NULL) { io = gensio_alloc(child, std::move(str), o, cb); } // Take over an existing gensio. GensioW(Gensio *iio): io(iio) { } ~GensioW() { try { io->close_s(); } catch (gensio_error &) { // Ignore the error, already closed. } // Make sure the freed handler doesn't get called. io->set_event_handler(NULL); io->free(); } Gensio * operator->() { return io; } Gensio * operator&() { return io; } private: Gensio *io; }; //***************************************************************** class Accepter; // An object of this class is given to an Accepter to handle // events from that accepter. class GENSIOCPP_DLL_PUBLIC Accepter_Event { public: // A new connection has come in, the new gensio is in g. You // must provide this. virtual void new_connection(Gensio *newg) = 0; // An error has occurred in the accepter that cannot be // reported as a return value. virtual void log(enum gensio_log_levels level, const std::string log) { } // When authenticating a new incoming gensio, these are used // to deliver the certification events for the gensio. Note // that the delivered gensio is not operational, it can only // be used to fetch username, certificate info, etc. See // gensio_event.3 for details on these. virtual int auth_begin(Gensio *tmpg) { return GE_NOTSUP; } virtual int precert_verify(Gensio *tmpg) { return GE_NOTSUP; } virtual int postcert_verify(Gensio *tmpg, int err, const char *errstr) { return GE_NOTSUP; } virtual int password_verify(Gensio *tmpg, const std::string val) { return GE_NOTSUP; } virtual int request_password(Gensio *tmpg, gensiods maxsize, std::string &retval) { return GE_NOTSUP; } virtual int verify_2fa(Gensio *tmpg, const std::vector data) { return GE_NOTSUP; } virtual int request_2fa(Gensio *tmpg, std::vector &retval) { return GE_NOTSUP; } // The free() operation for accepter this object is assigned // to has finished and the data will immediately be freed. // Usually used to free the Accepter Event object. Like the // one for the Event class, see that for details. virtual void freed() { }; virtual ~Accepter_Event() = default; // Errors from parameter parsing come in here. virtual void parmlog(const std::string log) { } }; class GENSIOCPP_DLL_PUBLIC Accepter_Shutdown_Done { public: virtual void shutdown_done() = 0; virtual ~Accepter_Shutdown_Done() = default; }; class GENSIOCPP_DLL_PUBLIC Accepter_Enable_Done { public: virtual void enable_done() = 0; virtual ~Accepter_Enable_Done() = default; }; class GENSIOCPP_DLL_PUBLIC Raw_Accepter_Event_Handler { public: virtual ~Raw_Accepter_Event_Handler() = default; virtual int handle(Accepter *a, int event, void *data) = 0; // New connections are routed through here so they can be set // up properly. virtual void new_connection(Accepter_Event *e, Gensio *newg) = 0; // Freed accepters are routed through here so they can be shut // down properly. virtual void freed(Accepter_Event *e) = 0; }; // Allocate a new accepter object based on the given string. See // gensio.5 for details on the format of this string. Note that // the returned object will be a subclass of Accepter. GENSIOCPP_DLL_PUBLIC Accepter *gensio_acc_alloc(std::string str, Os_Funcs &o, Accepter_Event *cb = NULL); // Like above, but stack the accepter on top of an existing // accepter stack given in child. GENSIOCPP_DLL_PUBLIC Accepter *gensio_acc_alloc(Accepter *child, std::string str, Os_Funcs &o, Accepter_Event *cb = NULL); // Allocate a terminal gensio accepter by gensio type string. GENSIOCPP_DLL_PUBLIC Accepter *gensio_acc_alloc(const char *gensiotype, const void *gdata, const char * const args[], Os_Funcs &o, Accepter_Event *cb = NULL); // Allocate a filter gensio accepter by gensio type string. GENSIOCPP_DLL_PUBLIC Accepter *gensio_acc_alloc(const char *gensiotype, Accepter *child, const char * const args[], Os_Funcs &o, Accepter_Event *cb = NULL); class GENSIOCPP_DLL_PUBLIC Accepter { public: Accepter(const Accepter&) = delete; Accepter &operator=(const Accepter&) = delete; // Unfortunately, you can't use the destructor with this class // because of race conditions. When you call this, there may // be other things pending in callbacks, and there's no way to // delay the free of the object in a destructor without // blocking. So you call free here, and when the freed // function in the event handler gets called, the free is // complete. void free(); // Set the callback object. Not really very useful, and you // shouldn't do this while the accepter is started. inline void set_event_handler(Accepter_Event *cb = NULL) { gcb = cb; } // Start accepting connections. You still need to set the // enable to actual receive connections, this opens the // accepting sockets or whatever and gets things ready. void startup(); // Shutdown the accepter, closing the accept socket or // whatever is required for the gensio. The done will be // called when the shutdown is complete. void shutdown(Accepter_Shutdown_Done *done = NULL); // Shutdown and block until it completes. void shutdown_s(); // Disable the accepter, see gensio_acc_disable.3 for details. // This is not for normal use. void disable() { gensio_acc_disable(acc); } // Set the enable/disable, but call the done function when the // enable/disable completes, unless done is NULL. Using done // is not really useful for enable, but it can let you know // that no callbacks are pending on a disable. If you don't // have a done handler on a disable, you won't know when all // the callbacks are done. void set_callback_enable(bool enabled, Accepter_Enable_Done *done = NULL); // Synchronous enable/disable, won't return until the // enable/disable completes. void set_callback_enable_s(bool enabled); // Special control operations on the accepter, see // gensio_acc_control.3 for details. int control(int depth, bool get, unsigned int option, char *data, gensiods *datalen); // Put an accepter in synchronous mode. With this, all // accepts must be received with accept_s() inline void set_sync() { gensio_acc_set_sync(acc); } // Wait for an accept to come in. You must have called // set_sync() first. Wait for up to timeout time. If this // times out, it returns GE_TIMEDOUT, otherwise it returns // zero. Any other errors get thrown as a gensio_error. // The new gensio is returned in g. int accept_s(Gensio **gret, gensio_time *timeout = NULL, bool intr = false); // Create a new gensio as if it came from this accepter. This // doesn't have much meaning except for UDP. For UDP, it uses // the socket of the accepter to create the connection, so // packets will come from this accepter's socket and packets // received on this accepters's socket from the given remote // end will be sent to this gensio. Gensio *str_to_gensio(std::string str, Event *cb = NULL); // Return the type string for the accepter. inline const char *get_type(unsigned int depth) { return gensio_acc_get_type(acc, depth); } // Report capabilities of gensios from this accepter, see // gensio_acc_is_xxx.3 for details. inline bool is_reliable() const { return gensio_acc_is_reliable(acc); } inline bool is_packet() const { return gensio_acc_is_packet(acc); } inline bool is_message() const { return gensio_acc_is_message(acc); } inline bool is_mux() const { return gensio_acc_is_mux(acc); } inline bool is_serial() const { return gensio_acc_is_serial(acc); } // Return the local side port for the accepter. This is // useful if you create a gensio with the port set to zero, // letting the code choose a port. Then you can fetch the // actual port with this. Note that some accepter types will // return something besides a number here (ie unix). std::string get_port() const; // Get the os funcs for this accepter. inline Os_Funcs &get_os_funcs() { return go; } // Get the event handler for this accepter. inline class Accepter_Event *get_cb() const { return gcb; } // Return the raw accepter. Don't use this, it's for subclasses // to use. struct gensio_accepter *get_accepter() { return acc; } // This allows the user to intercept raw events, it is primarily // used to help other language bindings tie in things they need. Raw_Accepter_Event_Handler *raw_event_handler = NULL; protected: virtual void set_accepter(struct gensio_accepter *acc, bool set_cb); Accepter(Os_Funcs &o, Accepter_Event *cb) : go(o), gcb(cb) { } virtual ~Accepter() { if (raw_event_handler) delete raw_event_handler; } private: struct gensio_accepter *acc = NULL; Os_Funcs go; Accepter_Event *gcb; GENSIOCPP_DLL_PUBLIC friend Accepter *gensio_acc_alloc(struct gensio_accepter *acc, Os_Funcs &o); GENSIOCPP_DLL_PUBLIC friend void gensio_acc_cpp_freed(struct gensio_accepter *acc, struct gensio_acc_frdata *frdata); }; // A wrapper to allow RAII to be used on a Gensio. If you use // this, you should either make sure the gensio is closed before // the end of this object's lifetime, or you should not free it // and let this destructor close it. What you should *not* do is // an asynchronous free then call this, because the close here // will fail and then the free won't be done after the destructor // returns. class GENSIOCPP_DLL_PUBLIC AccepterW { public: AccepterW(std::string str, Os_Funcs &o, Accepter_Event *cb = NULL) { acc = gensio_acc_alloc(std::move(str), o, cb); } AccepterW(Accepter *child, std::string str, Os_Funcs &o, Accepter_Event *cb = NULL) { acc = gensio_acc_alloc(child, std::move(str), o, cb); } // Take over an existing accepter. AccepterW(Accepter *iacc): acc(iacc) { } ~AccepterW() { try { acc->shutdown_s(); } catch (gensio_error &) { // Ignore the error, already closed. } // Make sure the freed handler doesn't get called. acc->set_event_handler(NULL); acc->free(); } Accepter * operator->() { return acc; } Accepter * operator&() { return acc; } private: Accepter *acc; }; } #endif /* GENSIO_CPP_INCLUDE */ gensio-3.0.0/TODO0000664000175000017500000000303414664224267007166 This is a random-ish list of things that might be done. Add a way to stack multiple things on a mux. Idea, use ",;" to specify the start of a number of things to go onto a mux, ",," to separate things on top of a mux, and ",." to mark the end of the last thing on the mux. NOTE - The big problem with this is that there is nothing to connect to on the top. Implement RFC 1408 on telnet. Add a "stream" option that tells the gensio to act as a stream, even if it's a packet oriented gensio. This will allow the gensio to add data to existing untranmsmitted packets and do other optimizations. Report an error if a mux or relpkt client tries to connect to a client. serialdev devices cannot be used in a forked process because the UUCP lock will not be correct. However, flock locking solves this problem. Port selector changes to openipmi. Add 300 baud support to afskmdm. Add 9600 baud Add an AGWPE client. Add AGWPE server heard list, UI and raw data handling. Add a sound mux to support multiple modems on the same radio. * mux would control the key. * mux can use the carrier indication from the radio if available. * mux can get indications from the modem if they are receiving data (if carrier indication isn't available). * Used write ready callbacks to allow writing to sound device. Add an aux data/ oob data for sent messages that is sent back to the user of afskmdm. This way, ax.25 can know when a packet was transmitted and properly set the timers. Add controls into afsk for controlling tx delay, tail, etc. and use them from kiss. gensio-3.0.0/man/0000775000175000017500000000000015061121735007315 5gensio-3.0.0/man/gensio_acc_accept_s.30000664000175000017500000000374614664224267013302 .TH gensio_acc_accept_s 3 "27 Jan 2020" .SH NAME gensio_acc_set_sync, gensio_acc_accept_s, gensio_acc_accept_s_intr \- Synchronous I/O operations on a gensio accepter .SH SYNOPSIS .B #include .TP 20 .B int gensio_acc_set_sync(struct gensio_accepter *acc); .TP 20 .B int gensio_acc_accept_s(struct gensio_accepter *acc, .br .B struct gensio_time *timeout, .br .B struct gensio **new_io); .TP 20 .B int gensio_acc_accept_s_intr(struct gensio_accepter *acc, .br .B struct gensio_time *timeout, .br .B struct gensio **new_io); .SH "DESCRIPTION" Normal gensio accepter operation is asynchronous callback based. This serves most programs fairly well, especially if they need to handle multiple accepts on the same or different accepters. But occasionally you need to do something synchronous with the program execution, especially if you have a simple program that just accepts one connection and then does something. .B gensio_acc set_sync sets up the gensio accepter for synchronous accepts. If you do this, the event callback that is currently registered will no longer receive new connection events. It *will* receive other callbacks. You must call this before starting up the gensio accepter, and once you call it the gensio accepter is in sync mode until you shut it down. .B gensio_accept_s Waits for an incoming connection on the gensio accepter. This function waits for the amount of time in .I timeout. .I timeout is updated to the amount of time left to wait. If .I timeout is NULL, wait forever. If no error is returned, the new incoming connection is returned in .I new_io. .B gensio_accept_s_intr is like .B gensio_accept_s, but it return immediately if an signal interrupt occurs. On systems without signals, this is the same as .B gensio_accept_s. .SH "RETURN VALUES" Zero is returned on success, or a gensio error on failure. .SH "SEE ALSO" gensio_err(3), gensio_set_sync(3), gensio(5) gensio-3.0.0/man/gensio_write.30000644000175000017500000000373713626222160012026 .TH gensio_write 3 "24 Feb 2019" .SH NAME gensio_write \- Write data to a gensio .SH SYNOPSIS .B #include .TP 20 .B int gensio_write(struct gensio *io, gensiods *count, .br .B const void *buf, gensiods buflen, .br .B const char *const *auxdata); .PP .B struct gensio_sg { .RS 4 .B const void *buf; .br .B gensiods buflen; .RE .B }; .TP 20 .B int gensio_write_sg(struct gensio *io, gensiods *count, .br .B const struct gensio_sg *sg, gensiods sglen, .br .B const char *const *auxdata); .SH "DESCRIPTION" Write data to the given gensio. The data is in .I buf and the length of the data is in .I buflen. Note that .B gensio_write may not write all of the data given, depending on the gensio type and the internal buffer space. It will return the number of bytes actually written in .B count which may be NULL if you don't care. (Hint: you should almost always care.) If .B gensio_write is unable to write the full amount of data, you should generally buffer the unwritten data and call .B gensio_set_write_callback_enable(3) to know when you can write the rest of the data. Many applications always buffer the data and enable the write callback to do the write and then disable the write callback when all data is written, for consistency. .B gensio_write will never block, if it cannot write all the data it will write what it can and return. .B auxdata is used to pass in gensio specific auxiliary data, such as the stream number for SCTP or whether the data is out of band data for SCTP or TCP. .B gensio_write_sg is like .B gensio_write, but it takes a scatter-gather structure to allow you to combine multiple chunks of data without copying. Note that if you get a partial write, you must figure out where the write ended in your scatter-gather list and start the next write from there. .SH "RETURN VALUES" Zero is returned on success, or a gensio error on failure. .SH "SEE ALSO" gensio_err(3), gensio(5) gensio-3.0.0/man/gensio_set_sync.30000664000175000017500000000735414664224267012541 .TH gensio_set_sync 3 "27 Feb 2019" .SH NAME gensio_set_sync, gensio_clear_sync, gensio_read_s, gensio_write_s \- Synchronous I/O operations on a gensio .SH SYNOPSIS .B #include .TP 20 .B int gensio_set_sync(struct gensio *io); .TP 20 .B int gensio_clear_sync(struct gensio *io); .TP 20 .B int gensio_read_s(struct gensio *io, gensiods *count, .br .B void *data, gensiods datalen, .br .B struct gensio_time *timeout); .TP 20 .B int gensio_read_s_intr(struct gensio *io, gensiods *count, .br .B void *data, gensiods datalen, .br .B struct gensio_time *timeout); .TP 20 .B int gensio_write_s(struct gensio *io, gensiods *count, .br .B const void *data, gensiods datalen, .br .B struct gensio_time *timeout); .TP 20 .B int gensio_write_s_intr(struct gensio *io, gensiods *count, .br .B const void *data, gensiods datalen, .br .B struct gensio_time *timeout); .SH "DESCRIPTION" Normal gensio operation is asynchronous callback based. This serves most programs fairly well, especially if they are listening to multiple connections at the same time. You wouldn't want to write a compiler this way, but if you are writing something that is driven by external events, this event-driven type of programming works well. If you think about it, if you are using something like poll, select, etc., you almost always end up with something like: .IP poll(fds...) .br if (fd1 read is set) .br call fd1_read_handler() .br if (fd1 write is set) .br call fd1_write_handler() .br if (fd2 read is set) ... .PP The gensio handling does all this for you. Just register a handler with the gensio to get the read and write calls. It's more efficient, neater, and you end up with less code. But occasionally you need to do something synchronous with the program execution. For instance, in gtlsshd, if the initial certificate and password verification fails, it uses PAM to handle reading the password from the remote gensio. This requires synchronous I/O, and it uses this capability. .B gensio_set_sync sets up the gensio for synchronous I/O. If you do this, the event callback that is currently registered will no longer receive read and write callbacks. It *will* receive other callbacks. You must call this before doing any of the synchronous read and write operations. This function will block (while handling normal gensio events) until no callbacks are active. .B gensio_clear_sync returns the gensio to asynchronous I/O. The callback will be restored to the one that was set when gensio_set_sync() was called. .B gensio_read_s Waits for data from the gensio, up to .I datalen bytes. .I count (if not NULL) will be updated to the actual number of bytes read. This will wait for any read and will return whatever that read was, even if it is less than .I datalen. This function waits for the amount of time in .I timeout. .I timeout is updated to the amount of time left to wait. If .I timeout is NULL, wait forever. .B gensio_write_s writes data to the gensio. .I count (if not NULL) will be updated to the actual number of bytes written. This function will wait until either the timeout occurs or all the data is written. This function waits for the amount of time in .I timeout. .I timeout is updated to the amount of time left to wait. If .I timeout is NULL, wait forever. .B gensio_read_s_intr and .B gensio_write_s_intr are like .B gensio_read_s and .B gensio_write_s, but they return immediately if an signal interrupt occurs. On systems without signals, these are the same as .B gensio_read_s and .B gensio_write_s. .SH "RETURN VALUES" Zero is returned on success, or a gensio error on failure. .SH "SEE ALSO" gensio_err(3), gensio(5) gensio-3.0.0/man/gensio_acc_set_callback.30000644000175000017500000000223013626222160014074 .TH gensio_accepter_set_callback 3 "27 Feb 2019" .SH NAME gensio_accepter_set_callback, gensio_accepter_get_user_data, gensio_accepter_set_user_data \- Set the event callback and user data for a gensio accepter .SH SYNOPSIS .B #include .TP 20 .B void gensio_accepter_set_callback(struct gensio *io, .br .B gensio_accepter_event cb, void *user_data) .PP .TP 20 .B void gensio_accepter_set_user_data(struct gensio *io, void *user_data); .PP .TP 20 .B void *gensio_accepter_get_user_data(struct gensio *io) .SH "DESCRIPTION" .B gensio_accepter_set_callback sets the event handler and data for the gensio accepter. This function may be called again if the gensio accepter cannot generate any callbacks, generally after it has been shutdown. Otherwise race conditions may occur. .B gensio_accepter_set_user_data Just sets the user_data field in the gensio accepter. If this is called when the gensio is running, race conditions may occur. .B gensio_accepter_get_user_data Return the user data passed in with the gensio accepter was created or set by one of the above two functions. .SH "SEE ALSO" gensio(5), gensio_accepter_event(3) gensio-3.0.0/man/Makefile.in0000664000175000017500000010643515061121660011310 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = man ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_config_feature.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/m4/ax_have_epoll.m4 \ $(top_srcdir)/m4/ax_pkg_swig.m4 \ $(top_srcdir)/m4/ax_prog_python_version.m4 \ $(top_srcdir)/m4/ax_pthread.m4 \ $(top_srcdir)/m4/ax_python_devel.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man3dir = $(mandir)/man3 am__installdirs = "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man5dir)" man5dir = $(mandir)/man5 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_LIBS = @BASE_LIBS@ BUILTIN_MDNS_LIBS = @BUILTIN_MDNS_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CM108GPIO_LIBS = @CM108GPIO_LIBS@ CPLUSPLUS_DIR = @CPLUSPLUS_DIR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_AFSKMDM = @DYNAMIC_AFSKMDM@ DYNAMIC_AX25 = @DYNAMIC_AX25@ DYNAMIC_CERTAUTH = @DYNAMIC_CERTAUTH@ DYNAMIC_CM108GPIO = @DYNAMIC_CM108GPIO@ DYNAMIC_CONACC = @DYNAMIC_CONACC@ DYNAMIC_DGRAM = @DYNAMIC_DGRAM@ DYNAMIC_DUMMY = @DYNAMIC_DUMMY@ DYNAMIC_ECHO = @DYNAMIC_ECHO@ DYNAMIC_FILE = @DYNAMIC_FILE@ DYNAMIC_IPMISOL = @DYNAMIC_IPMISOL@ DYNAMIC_KEEPOPEN = @DYNAMIC_KEEPOPEN@ DYNAMIC_KISS = @DYNAMIC_KISS@ DYNAMIC_MDNS = @DYNAMIC_MDNS@ DYNAMIC_MSGDELIM = @DYNAMIC_MSGDELIM@ DYNAMIC_MUX = @DYNAMIC_MUX@ DYNAMIC_NET = @DYNAMIC_NET@ DYNAMIC_PERF = @DYNAMIC_PERF@ DYNAMIC_PTY = @DYNAMIC_PTY@ DYNAMIC_RATELIMIT = @DYNAMIC_RATELIMIT@ DYNAMIC_RELPKT = @DYNAMIC_RELPKT@ DYNAMIC_SCRIPT = @DYNAMIC_SCRIPT@ DYNAMIC_SCTP = @DYNAMIC_SCTP@ DYNAMIC_SERIALDEV = @DYNAMIC_SERIALDEV@ DYNAMIC_SOUND = @DYNAMIC_SOUND@ DYNAMIC_SSL = @DYNAMIC_SSL@ DYNAMIC_STDIO = @DYNAMIC_STDIO@ DYNAMIC_TELNET = @DYNAMIC_TELNET@ DYNAMIC_TRACE = @DYNAMIC_TRACE@ DYNAMIC_XLT = @DYNAMIC_XLT@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GENSIO_LIB_VERSION = @GENSIO_LIB_VERSION@ GENSIO_PTY_HELPER = @GENSIO_PTY_HELPER@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_DIR = @GLIB_DIR@ GLIB_LIB = @GLIB_LIB@ GLIB_LIBS = @GLIB_LIBS@ GMDNS = @GMDNS@ GMDNSMAN = @GMDNSMAN@ GOPROG = @GOPROG@ GO_DIR = @GO_DIR@ GREP = @GREP@ GTLSSH = @GTLSSH@ GTLSSHD = @GTLSSHD@ GTLSSHDMAN = @GTLSSHDMAN@ GTLSSHMAN = @GTLSSHMAN@ GTLSSH_KEYGEN = @GTLSSH_KEYGEN@ GTLSSH_KEYGENMAN = @GTLSSH_KEYGENMAN@ GTLSSYNC = @GTLSSYNC@ GTLSSYNCMAN = @GTLSSYNCMAN@ HAVE_ALSA = @HAVE_ALSA@ HAVE_AVAHI = @HAVE_AVAHI@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_DNSSD = @HAVE_DNSSD@ HAVE_LIBSCTP = @HAVE_LIBSCTP@ HAVE_MDNS = @HAVE_MDNS@ HAVE_OPENIPMI = @HAVE_OPENIPMI@ HAVE_OPENSSL = @HAVE_OPENSSL@ HAVE_PORTAUDIO = @HAVE_PORTAUDIO@ HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ HAVE_PTY = @HAVE_PTY@ HAVE_UCRED = @HAVE_UCRED@ HAVE_UDEV = @HAVE_UDEV@ HAVE_UNIX = @HAVE_UNIX@ HAVE_WIN32SOUND = @HAVE_WIN32SOUND@ HAVE_WINMDNS = @HAVE_WINMDNS@ HAVE_WORKING_PORT0 = @HAVE_WORKING_PORT0@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LN_SF = @LN_SF@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MDNS_LIBS = @MDNS_LIBS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENIPMI_CPPFLAGS = @OPENIPMI_CPPFLAGS@ OPENIPMI_LIBS = @OPENIPMI_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OSH_LIBS = @OSH_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAMLIB = @PAMLIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_CXX = @PTHREAD_CXX@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYGENSIO_DIR = @PYGENSIO_DIR@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIR = @PYTHON_DIR@ PYTHON_EXECUTABLE = @PYTHON_EXECUTABLE@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_EXT_EXT = @PYTHON_EXT_EXT@ PYTHON_EXT_EXT_SET = @PYTHON_EXT_EXT_SET@ PYTHON_HAS_THREADS = @PYTHON_HAS_THREADS@ PYTHON_INSTALL_DIR = @PYTHON_INSTALL_DIR@ PYTHON_INSTALL_LIB_DIR = @PYTHON_INSTALL_LIB_DIR@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_SWIG_FLAGS = @PYTHON_SWIG_FLAGS@ PYTHON_UNDEF_FLAG = @PYTHON_UNDEF_FLAG@ PYTHON_UNDEF_LIBS = @PYTHON_UNDEF_LIBS@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ REGEX_LIB = @REGEX_LIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOUND_LIBS = @SOUND_LIBS@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_CPP_DIR = @SWIG_CPP_DIR@ SWIG_DIR = @SWIG_DIR@ SWIG_LIB = @SWIG_LIB@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_DIR = @TCL_DIR@ TCL_LIB = @TCL_LIB@ TCL_LIBS = @TCL_LIBS@ USE_GGL_INT = @USE_GGL_INT@ USE_LOGIN_PROGRAM = @USE_LOGIN_PROGRAM@ USE_OPENPTY = @USE_OPENPTY@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gensio_VERSION_MAJOR = @gensio_VERSION_MAJOR@ gensio_VERSION_MINOR = @gensio_VERSION_MINOR@ gensio_VERSION_PATCH = @gensio_VERSION_PATCH@ gensio_VERSION_STRING = @gensio_VERSION_STRING@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduleinstalldir = @moduleinstalldir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgprog = @pkgprog@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ man_MANS = gensio.5 gensio_event.3 str_to_gensio.3 gensio_set_callback.3 \ gensio_set_log_mask.3 gensio_os_funcs.3 gensio_err.3 gensio_write.3 \ gensio_open.3 gensio_alloc_channel.3 gensio_close.3 gensio_control.3 \ gensio_set_read_callback_enable.3 gensio_get_type.3 gensio_set_sync.3 \ gensio_accepter_event.3 gensio_acc_set_callback.3 \ gensio_acc_shutdown.3 gensio_acc_set_accept_callback_enable.3 \ gensio_acc_control.3 gensio_acc_get_type.3 gensio_add_default.3 \ str_to_gensio_accepter.3 gensio_acc_accept_s.3 gensio_acc_startup.3 \ gensio_mdns.3 gensio_bswap.3 RM_F = -rm -f EXTRA_DIST = $(man_MANS) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu man/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu man/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man3: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man3dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.3[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ done; } uninstall-man3: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man3dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.3[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) install-man5: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man5dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.5[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \ done; } uninstall-man5: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man5dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.5[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(MANS) installdirs: for dir in "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man5dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man3 install-man5 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook uninstall-man: uninstall-man3 uninstall-man5 .MAKE: install-am install-data-am install-strip uninstall-am .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-data-hook install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-man3 install-man5 \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am uninstall-hook uninstall-man \ uninstall-man3 uninstall-man5 .PRECIOUS: Makefile # Note that $(LN_SF) is set in configure.ac install-data-hook: $(LN_SF) str_to_gensio.3 $(DESTDIR)$(man3dir)/str_to_gensio_child.3 $(LN_SF) str_to_gensio.3 $(DESTDIR)$(man3dir)/gensio_acc_str_to_gensio.3 $(LN_SF) str_to_gensio.3 $(DESTDIR)$(man3dir)/gensio_terminal_alloc.3 $(LN_SF) str_to_gensio.3 $(DESTDIR)$(man3dir)/gensio_filter_alloc.3 $(LN_SF) gensio_set_callback.3 $(DESTDIR)$(man3dir)/gensio_set_user_data.3 $(LN_SF) gensio_set_callback.3 $(DESTDIR)$(man3dir)/gensio_get_user_data.3 $(LN_SF) gensio_set_log_mask.3 $(DESTDIR)$(man3dir)/gensio_get_log_mask.3 $(LN_SF) gensio_set_log_mask.3 $(DESTDIR)$(man3dir)/gensio_log_level_to_str.3 $(LN_SF) gensio_set_log_mask.3 $(DESTDIR)$(man3dir)/gensio_vlog.3 $(LN_SF) gensio_set_log_mask.3 $(DESTDIR)$(man3dir)/gensio_log.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_default_os_hnd.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_alloc_os_funcs.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_unix_funcs_alloc.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_win_funcs_alloc.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_proc_setup.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_proc_cleanup.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_proc_unix_get_wait_sigset.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_new_thread.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_wait_thread.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_free.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_proc_register_term_handler.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_proc_register_reload_handler.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_proc_register_winsize_handler.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_zalloc.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_zfree.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_alloc_lock.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_free_lock.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_lock.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_unlock.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_get_monotonic_time.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_alloc_timer.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_free_timer.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_start_timer.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_start_timer_abs.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_stop_timer.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_stop_timer_with_done.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_alloc_runner.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_free_runner.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_run.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_set_vlog.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_service.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_handle_fork.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_alloc_waiter.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_free_waiter.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_wait.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_wait_intr.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_wait_intr_sigmask.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_wake.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_set_data.3 $(LN_SF) gensio_os_funcs.3 $(DESTDIR)$(man3dir)/gensio_os_funcs_get_data.3 $(LN_SF) gensio_err.3 $(DESTDIR)$(man3dir)/gensio_err_to_str.3 $(LN_SF) gensio_write.3 $(DESTDIR)$(man3dir)/gensio_write_sg.3 $(LN_SF) gensio_open.3 $(DESTDIR)$(man3dir)/gensio_open_s.3 $(LN_SF) gensio_open.3 $(DESTDIR)$(man3dir)/gensio_open_nochild.3 $(LN_SF) gensio_open.3 $(DESTDIR)$(man3dir)/gensio_open_nochild_s.3 $(LN_SF) gensio_close.3 $(DESTDIR)$(man3dir)/gensio_close_s.3 $(LN_SF) gensio_close.3 $(DESTDIR)$(man3dir)/gensio_disable.3 $(LN_SF) gensio_close.3 $(DESTDIR)$(man3dir)/gensio_free.3 $(LN_SF) gensio_set_read_callback_enable.3 $(DESTDIR)$(man3dir)/gensio_set_write_callback_enable.3 $(LN_SF) gensio_control.3 $(DESTDIR)$(man3dir)/gensio_acontrol.3 $(LN_SF) gensio_control.3 $(DESTDIR)$(man3dir)/gensio_acontrol_s.3 $(LN_SF) gensio_control.3 $(DESTDIR)$(man3dir)/gensio_parity_to_str.3 $(LN_SF) gensio_control.3 $(DESTDIR)$(man3dir)/gensio_str_to_parity.3 $(LN_SF) gensio_control.3 $(DESTDIR)$(man3dir)/gensio_flowcontrol_to_str.3 $(LN_SF) gensio_control.3 $(DESTDIR)$(man3dir)/gensio_str_to_flowcontrol.3 $(LN_SF) gensio_control.3 $(DESTDIR)$(man3dir)/gensio_onoff_to_str.3 $(LN_SF) gensio_control.3 $(DESTDIR)$(man3dir)/gensio_str_to_onoff.3 $(LN_SF) gensio_get_type.3 $(DESTDIR)$(man3dir)/gensio_get_child.3 $(LN_SF) gensio_get_type.3 $(DESTDIR)$(man3dir)/gensio_is_client.3 $(LN_SF) gensio_get_type.3 $(DESTDIR)$(man3dir)/gensio_is_reliable.3 $(LN_SF) gensio_get_type.3 $(DESTDIR)$(man3dir)/gensio_is_packet.3 $(LN_SF) gensio_get_type.3 $(DESTDIR)$(man3dir)/gensio_is_message.3 $(LN_SF) gensio_get_type.3 $(DESTDIR)$(man3dir)/gensio_is_authenticated.3 $(LN_SF) gensio_get_type.3 $(DESTDIR)$(man3dir)/gensio_is_encrypted.3 $(LN_SF) gensio_get_type.3 $(DESTDIR)$(man3dir)/gensio_is_mux.3 $(LN_SF) gensio_set_sync.3 $(DESTDIR)$(man3dir)/gensio_clear_sync.3 $(LN_SF) gensio_set_sync.3 $(DESTDIR)$(man3dir)/gensio_read_s.3 $(LN_SF) gensio_set_sync.3 $(DESTDIR)$(man3dir)/gensio_write_s.3 $(LN_SF) str_to_gensio_accepter.3 $(DESTDIR)$(man3dir)/str_to_gensio_accepter_child.3 $(LN_SF) str_to_gensio_accepter.3 $(DESTDIR)$(man3dir)/gensio_terminal_acc_alloc.3 $(LN_SF) str_to_gensio_accepter.3 $(DESTDIR)$(man3dir)/gensio_filter_acc_alloc.3 $(LN_SF) gensio_acc_set_callback.3 $(DESTDIR)$(man3dir)/gensio_acc_set_user_data.3 $(LN_SF) gensio_acc_set_callback.3 $(DESTDIR)$(man3dir)/gensio_acc_get_user_data.3 $(LN_SF) gensio_acc_shutdown.3 $(DESTDIR)$(man3dir)/gensio_acc_shutdown_s.3 $(LN_SF) gensio_acc_shutdown.3 $(DESTDIR)$(man3dir)/gensio_acc_disable.3 $(LN_SF) gensio_acc_shutdown.3 $(DESTDIR)$(man3dir)/gensio_acc_free.3 $(LN_SF) gensio_acc_set_accept_callback_enable.3 $(DESTDIR)$(man3dir)/gensio_acc_set_accept_callback_enable_cb.3 $(LN_SF) gensio_acc_set_accept_callback_enable.3 $(DESTDIR)$(man3dir)/gensio_acc_set_accept_callback_enable_s.3 $(LN_SF) gensio_acc_get_type.3 $(DESTDIR)$(man3dir)/gensio_acc_is_reliable.3 $(LN_SF) gensio_acc_get_type.3 $(DESTDIR)$(man3dir)/gensio_acc_is_packet.3 $(LN_SF) gensio_acc_get_type.3 $(DESTDIR)$(man3dir)/gensio_acc_is_message.3 $(LN_SF) gensio_acc_get_type.3 $(DESTDIR)$(man3dir)/gensio_acc_is_mux.3 $(LN_SF) gensio_add_default.3 $(DESTDIR)$(man3dir)/gensio_set_default.3 $(LN_SF) gensio_add_default.3 $(DESTDIR)$(man3dir)/gensio_get_default.3 $(LN_SF) gensio_add_default.3 $(DESTDIR)$(man3dir)/gensio_get_defaultaddr.3 $(LN_SF) gensio_add_default.3 $(DESTDIR)$(man3dir)/gensio_del_default.3 $(LN_SF) gensio_add_default.3 $(DESTDIR)$(man3dir)/gensio_reset_defaults.3 $(LN_SF) gensio_acc_accept_s.3 $(DESTDIR)$(man3dir)/gensio_acc_set_sync.3 $(LN_SF) gensio_mdns.3 $(DESTDIR)$(man3dir)/gensio_alloc_mdns.3 $(LN_SF) gensio_mdns.3 $(DESTDIR)$(man3dir)/gensio_free_mdns.3 $(LN_SF) gensio_mdns.3 $(DESTDIR)$(man3dir)/gensio_mdns_add_service.3 $(LN_SF) gensio_mdns.3 $(DESTDIR)$(man3dir)/gensio_mdns_remove_service.3 $(LN_SF) gensio_mdns.3 $(DESTDIR)$(man3dir)/gensio_mdns_add_watch.3 $(LN_SF) gensio_mdns.3 $(DESTDIR)$(man3dir)/gensio_mdns_remove_watch.3 uninstall-hook: $(RM_F) $(DESTDIR)$(man3dir)/str_to_gensio_child.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_terminal_alloc.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_filter_alloc.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_acc_str_to_gensio.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_set_user_data.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_get_user_data.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_get_log_mask.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_log_level_to_str.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_vlog.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_log.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_default_os_hnd.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_alloc_os_funcs.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_unix_funcs_alloc.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_win_funcs_alloc.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_proc_setup.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_proc_cleanup.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_proc_unix_get_wait_sigset.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_new_thread.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_wait_thread.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_write_sg.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_err_to_str.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_open_s.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_open_nochild.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_open_nochild_s.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_close_s.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_disable.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_free.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_set_write_callback_enable.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_acontrol.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_parity_to_str.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_str_to_parity.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_flowcontrol_to_str.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_str_to_flowcontrol.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_onoff_to_str.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_str_to_onoff.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_acontrol_s.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_get_child.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_is_client.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_is_reliable.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_is_packet.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_is_message.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_is_authenticated.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_is_encrypted.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_is_mux.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_clear_sync.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_read_s.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_write_s.3 $(RM_F) $(DESTDIR)$(man3dir)/str_to_gensio_accepter_child.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_terminal_acc_alloc.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_filter_acc_alloc.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_acc_set_user_data.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_acc_get_user_data.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_acc_shutdown_s.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_acc_disable.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_acc_free.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_acc_set_accept_callback_enable_cb.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_acc_set_accept_callback_enable_s.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_acc_is_reliable.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_acc_is_packet.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_acc_is_message.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_acc_is_mux.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_set_default.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_get_default.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_get_defaultaddr.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_del_default.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_reset_defaults.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_acc_set_sync.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_alloc_mdns.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_free_mdns.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_mdns_add_service.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_mdns_remove_service.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_mdns_add_watch.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_mdns_remove_watch.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_unix_funcs_alloc.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_win_funcs_alloc.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_proc_setup.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_proc_cleanup.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_proc_unix_get_wait_sigset.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_new_thread.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_wait_thread.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_free.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_proc_register_term_handler.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_proc_register_reload_handler.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_proc_register_winsize_handler.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_zalloc.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_zfree.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_alloc_lock.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_free_lock.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_lock.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_unlock.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_get_monotonic_time.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_alloc_timer.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_free_timer.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_start_timer.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_start_timer_abs.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_stop_timer.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_stop_timer_with_done.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_alloc_runner.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_free_runner.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_run.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_set_vlog.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_service.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_handle_fork.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_alloc_waiter.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_free_waiter.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_wait.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_wait_intr.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_wait_intr_sigmask.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_wake.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_set_data.3 $(RM_F) $(DESTDIR)$(man3dir)/gensio_os_funcs_get_data.3 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gensio-3.0.0/man/gensio_set_log_mask.30000664000175000017500000000276114664224267013356 .TH gensio_set_log_mask 3 "23 Feb 2019" .SH NAME gensio_set_log_mask, gensio_get_log_mask, gensio_log_level_to_str, \- Logging and seting which gensio logs are passed or ignored .SH SYNOPSIS .B #include .TP 20 .B void gensio_set_log_mask(unsigned int mask); .PP .TP 20 .B unsigned int gensio_get_log_mask(void); .PP .TP 20 .B const char *gensio_log_level_to_str(enum gensio_log_levels level); .PP .TP 20 .B void gensio_vlog(struct gensio_os_funcs *o, .br .B enum gensio_log_levels level, .br .B const char *str, va_list args); .PP .TP 20 .B void gensio_log(struct gensio_os_funcs *o, .br .B enum gensio_log_levels level, .br .B const char *str, ...); .SH "DESCRIPTION" The log mask is a global variable in the gensio library that sets what level of logs are delivered through the vlog function pointer in .B gensio_os_funcs. Log levels are: .IP GENSIO_LOG_FATAL GENSIO_LOG_ERR GENSIO_LOG_WARNING GENSIO_LOG_INFO GENSIO_LOG_DEBUG .PP with obvious meanings. There is also: .IP GENSIO_LOG_MASK_ALL .PP which is a bitmask of all the log levels. The default log mask is .B (1 << GENSIO_LOG_FATAL | 1 << GENSIO_LOG_ERR). Setting other log values can be helpful in debugging problems with gensios. .B gensio_log_level_to_str converts a log level to a string representation of that level. .B gensio_vlog and .B gensio_log are the functions used to generate logs. These are primarily for use in the gensio library, though you may use them, too, if you like. .SH "SEE ALSO" gensio(5), gensio_os_funcs(3) gensio-3.0.0/man/gensio_mdns.30000664000175000017500000001756014664224267011653 .TH gensio_mdns 3 "15 Oct 2020" .SH NAME gensio_alloc_mdns, gensio_free_mdns, gensio_mdns_add_service, gensio_mdns_remove_service, gensio_mdns_add_watch, gensio_mdns_remove_watch \- Functions for doing mDNS operations .SH SYNOPSIS .B #include .TP 20 .B typedef void (*gensio_mdns_done)(struct gensio_mdns *m, .br .B void *userdata); .TP 20 .B int gensio_alloc_mdns(struct gensio_os_funcs *o, .br .B struct gensio_mdns **m); .TP 20 .B int gensio_free_mdns(struct gensio_mdns *m, gensio_mdns_done done, .br .B void *userdata); .TP 20 .B int gensio_mdns_add_service(struct gensio_mdns *m, int interface, .br .B int ipdomain, const char *name, const char *type, .br .B const char *domain, const char *host, .br .B int port, const char *txt[], .br .B struct gensio_mdns_service **s); .TP 20 .B typedef void (*gensio_mdns_service_cb)(struct gensio_mdns_service *service, .br .B enum gensio_mdns_service_event ev, .br .B const char *info, .br .B void *cb_data); .TP 20 .B int gensio_mdns_add_service2(struct gensio_mdns *m, int interface, .br .B int ipdomain, const char *name, const char *type, .br .B const char *domain, const char *host, .br .B int port, const char *txt[], .br .B gensio_mdns_service_cb cb, void *cb_data, .br .B struct gensio_mdns_service **s); .TP 20 .B int gensio_mdns_remove_service(struct gensio_mdns_service *s); .TP 20 .B typedef void gensio_mdns_watch_cb(struct gensio_mdns_watch *w, .br .B enum gensio_mdns_data_state state, .br .B int interface, int ipdomain, .br .B const char *name, const char *type, .br .B const char *domain, const char *host, .br .B const struct gensio_addr *addr, const char *txt[], .br .B void *userdata); .TP 20 .B int gensio_mdns_add_watch(struct gensio_mdns *m, int interface, .br .B int ipdomain, const char *name, const char *type, .br .B const char *domain, const char *host, .br .B gensio_mdns_watch_cb callback, void *userdata, .br .B struct gensio_mdns_watch **w); .TP 20 .B int gensio_mdns_remove_watch(struct gensio_mdns_watch *w); .SH "DESCRIPTION" These functions and type deal with mDNS (Multicast DNS) discovery of services on a local network. They can be used to advertise services or find services. These provide a powerful and easy to use interface to mDNS capabilities. To do these things, you must first use .B gensio_alloc_mdns to allocate an mdns structure with the standard gensio OS functions structure. You must, of course, do the standard OS functions wait loops and such. When you are finished, you should free the mdns structure with .B gensio_free_mdns. Note that code may still be in mdns callbacks when the free returns, you have to make sure to wait until the done callback is called to know the code is out of all callbacks. The done callback is optional if you don't care. Also note that the mdns will not be freed (and done not called) until all the services and watches are freed for it. For the remaining functions, the .I interface parameter is the system interface number of the network device, and may be -1 to specify all interfaces. The .I ipdomain parameter is one of: .TP .I GENSIO_NETTYPE_UNSPEC Do both IPV4 and IPV4 .TP .I GENSIO_NETTYPE_IPV4 IPV4 only .TP .I GENSIO_NETTYPE_IPV6 IPV6 only .br .PP The .I name, type, domain, and host parameters are the standard mDNS fields, see documentation on mDNS for details. The .I txt parameter is for mDNS text fields, and is a standard argv-like array. Once you have an mdns structure, you can advertise a service on the net with it using .B gensio_mdns_add_service2. That service will continue to be advertised until you call .B gensio_mdns_remove_service on it or your program terminates. The .I domain and .I host parameters should generally be NULL to take the system defaults. The .I txt parameter may be NULL if you don't have any. .B gensio_mdns_add_service2 takes a callback, it will be called when the service has been registered, and possible with a new name if there was a name conflict. You may pass in a NULL for the callback if you don't care. The callback .B parameter can take the following values: .TP .I GENSIO_MDNS_SERVICE_READY The service is now registered, and the name is the same as the name you passed in. .TP .I GENSIO_MDNS_SERVICE_READY_NEW_NAME The service is now registered, but the name was changed, it will be in the info parameter. .TP .I GENSIO_MDNS_SERVICE_REMOVED You requested the service be removed, the remove is now complete and the callback will not be called again. .TP .I GENSIO_MDNS_SERVICE_ERROR An error occurred as part of service registration. .PP There is a .B gensio_mdns_add_service function for backwards compatibility, it is equivalent to calling .B gensio_mdns_add_service2 with a NULL callback. Don't use it in new code. To find services on the network, you add a watch with .B gensio_mdns_add_watch. Any service that matches your query will be reported with the callback functions and all fields will be provided in the callback. Once you are done with a watch, you may call .B gensio_mdns_remove_watch Note that code may still be in mdns callbacks when the remove returns, you have to make sure to wait until the done callback is called to know the code is out of all callbacks. The done callback is optional if you don't care. Some MDNS libraries do not support an NULL .B type for the watch, and some do. For portable code, always specify the watch. If the library does not support a null .B type the function will return .B GE_INCONSISTENT. The watch callback state has three possible values: .TP .I GENSIO_MDNS_WATCH_NEW_DATA This is a new entry being reported. .TP .I GENSIO_MDNS_WATCH_DATA_GONE An entry that was previously reported as gone away. .TP .I GENSIO_MDNS_WATCH_ALL_FOR_NOW This is called one time after the watch is created, it reports that all currently known entries have been reported. New ones may be reported in the future, but those will have been dynamically added later. .PP In the watch callback, you must make copies of all the strings and addresses passed to you to keep them. Their continued existence is not guaranteed. In watches, all of the string fields may be NULL, meaning you want to take anything in that field. So if all the strings are NULL and the interface is -1 and the ipdomain is .I GENSIO_NETTYPE_UNSPEC you will get all of the fields. .SH "STRING VALUES FOR WATCHES" The string values to the watch add function may use regular expressions. If the string starts with '%', then the data after it is treated as a regular expression and fields are matched against that. See the regex(7) man page for details. Globs are supported on some platforms, but their use is discouraged because they aren't available on some platforms. If the string starts with '@', the the data after it is treated as a standard glob. See the glob(7) man page for details. An error will be returned if the platform doesn't have glob matching. If the string starts with '=', an exact comparison is done with the data after it. If the string starts with a-z0-9_ or a space, then an exact string comparison is done, including the first character. The behavior of matching for any other starting character is undefined. In general, you should always use '@', '%', or '=' as the starting character of all your query strings to be sure. .SH "RETURN VALUES" Zero is returned on success, or a gensio error on failure. .SH "SEE ALSO" gensio_err(3), gensio_os_funcs(3), regex(7), glob(7) gensio-3.0.0/man/gensio_acc_control.30000644000175000017500000000427113727775405013175 .TH gensio_acc_control 3 "27 Feb 2019" .SH NAME gensio_acc_control \- Perform gensio accepter specific actions .SH SYNOPSIS .B #include .TP 20 .B int gensio_acc_control(struct gensio_accepter *acc, int depth, .br .B bool get, unsigned int option, .br .B char *data, gensiods *datalen); .SH "DESCRIPTION" .B gensio_acc_control performs a gensio accepter specific operation on the gensio accepter. This works exactly like gensio_control(3), see that for details on get, depth, and how the data and datalen work. gensio control operations in .I option depend on the particular gensio. Below some are documented, but there may be other controls available. See the gensio documentation in gensio(5) for details. .SS "GENSIO_ACC_CONTROL_LADDR" Return the given local address for the given gensio. Since a single gensio may have more than one local address, this control provides a means to tell which one. The .I data string passed in should be the string representation of a the number (like created with snprintf()) for the particular index you want to fetch. If you specify a number larger than the number of open listen sockets, .I GE_NOTFOUND is returned. The return data is a string holding the address. Note that a single fetched string may contain more than one address. These will be separated by semicolons. In some cases addresses may change dynamically (like with SCTP), so you get a single set of addresses. .SS "GENSIO_ACC_CONTROL_LPORT" Return the port for the given local address for the given gensio. Since a single gensio may have more than one local address, this control provides a means to tell which one. The .I data string passed in should be the string representation of a the number (like created with snprintf()) for the particular index you want to fetch. If you specify a number larger than the number of open listen sockets, .I GE_NOTFOUND is returned. The return data is a string holding the port number. .SS "GENSIO_ACC_CONTROL_TCPDNAME" Get or set the TCPD name for the gensio, only for TCP gensios. .SH "RETURN VALUES" Zero is returned on success, or a gensio error on failure. .SH "SEE ALSO" gensio_err(3), gensio(5), gensio_control(3) gensio-3.0.0/man/gensio_err.30000664000175000017500000000536314664224267011500 .TH gensio_err 3 "24 Feb 2019" .SH NAME gensio_err \- Error reporting values for gensio functions .SH SYNOPSIS .B #include .br .B const char *gensio_err_to_str(int err) .SH "DESCRIPTION" The return values for gensio functions that return errors and the reported values in callbacks from the gensio library are all gensio errors. Possible values are: .IP GE_NOERR No error .br GE_NOMEM Out of memory .br GE_NOTSUP Operation not supported .br GE_INVAL Invalid data to parameter .br GE_NOTFOUND Value or file not found .br GE_EXISTS Value already exists .br GE_OUTOFRANGE Value out of range .br GE_INCONSISTENT Parameters inconsistent in call .br GE_NODATA No data was available for the function .br GE_OSERR OS error, see logs .br GE_INUSE Object was already in use .br GE_INPROGRESS Operation is in progress .br GE_NOTREADY Object was not ready for operation .br GE_TOOBIG Value was too large for data .br GE_TIMEDOUT Operation timed out .br GE_RETRY Retry operation later .br GE_KEYNOTFOUND Unable to find the given key .br GE_CERTREVOKED Key was revoked .br GE_CERTEXPIRED Key was expired .br GE_KEYINVALID Key is not valid .br GE_NOCERT Certificate not provided .br GE_CERTINVALID Certificate is not valid .br GE_PROTOERR Protocol error .br GE_COMMERR Communication error .br GE_IOERR Internal I/O error .br GE_REMCLOSE Remote end closed connection .br GE_HOSTDOWN Host could not be reached .br GE_CONNREFUSE Connection refused .br GE_DATAMISSING Data was missing .br GE_CERTNOTFOUND Unable to find given certificate .br GE_AUTHREJECT Authentication tokens rejected .br GE_ADDRINUSE Address already in use .br GE_INTERRUPTED Operation was interrupted by a signal .br GE_SHUTDOWN Operation on shutdown file descriptor .br GE_LOCALCLOSED Local side closed connection .br GE_PERM Permission denied .br GE_APPERR Application error .br GE_UNKNOWN_NAME_ERROR Unknown name server lookup failure .br GE_NAME_ERROR Unable to find a valid name on the name server .br GE_NAME_SERVER_FAILURE Serious name server failure .br GE_NAME_INVALID Invalid name server information .br GE_NAME_NET_NOT_UP Network address for the given name is not available .PP .B gensio_err_to_str converts an integer error value to the given string. .SH "SEE ALSO" gensio(5), gensio_err(3), gensio_log(3) gensio-3.0.0/man/str_to_gensio_accepter.30000664000175000017500000000542714664224267014071 .TH str_to_gensio_accepter 3 "27 Feb 2019" .SH NAME str_to_gensio_accepter \- Create a gensio accepter from a string .SH SYNOPSIS .B #include .TP 20 .B int str_to_gensio_accepter(const char *str, .br .B struct gensio_os_funcs *o, .br .B gensio_accepter_event cb, .br .B void *user_data, .br .B struct gensio_accepter **acc); .TP 20 .B int str_to_gensio_accepter_child(struct gensio_accepter *child, .br .B const char *str, .br .B struct gensio_os_funcs *o, .br .B gensio_accepter_event cb, .br .B void *user_data, .br .B struct gensio_accepter **acc); .TP 20 .B int gensio_terminal_acc_alloc(const char *gensiotype, .br .B const void *gdata, .br .B const char * const args[], .br .B struct gensio_os_funcs *o, .br .B gensio_accepter_event cb, void *user_data, .br .B struct gensio_accepter **accepter); .TP 20 .B int gensio_filter_acc_alloc(const char *gensiotype, .br .B struct gensio_accepter *child, .br .B const char * const args[], .br .B struct gensio_os_funcs *o, .br .B gensio_accepter_event cb, void *user_data, .br .B struct gensio_accepter **accepter); .SH "DESCRIPTION" .B str_to_gensio_accepter allocates a new gensio accepter stack based upon the given string .B str. .B str_to_gensio_accepter_child allocates a new gensio accepter stack based upon the given string .B str and stacks it on top of the given child accepter. To allocate an accepter directly, use one of .B gensio_terminal_acc_alloc or .B gensio_filter_acc_alloc. A terminal accepter is one at the bottom of the stack. The .B gdata parameter depends on the particular gensio. For instance, for tcp it is a pointer to a gensio_addr structure. For stdio it is an argv array. See gensio.5 under "Direct Allocation" for the particular gensio for what gdata is. A filter accepter is one that has a child. You can use these two functions to allocate an accepter stack directly, not using a string format. The .B cb and .B user_data parameters set a function that will be called when events come in on the gensio accepter. .B user_data is unused by the gensio stack itself, it is there for the user and may be anything the user wishes. The new gensio accepter is returned in .B acc. It will be in the shutdown state. .SH "RETURN VALUES" Zero is returned on success, or a gensio error on failure. .SH "SEE ALSO" gensio_acc_set_callback(3), gensio_err(3), gensio(5) gensio-3.0.0/man/gensio.50000664000175000017500000032637715045153771010640 .TH gensio 5 01/02/19 "Specifying a gensio" .SH NAME gensio \- How to specify a gensio .SH SYNOPSIS .B [(options)][,gensio|terminaloptions] .SH DESCRIPTION .BR gensio stands for GENeral Stream Input Output. It provides an abstraction for all kinds of stream I/O, and even makes some packet I/O look like stream I/O (like UDP). In particular, gensio makes it easy to create encrypted and authenticated connections. The .BR gensio library specifies a connection (gensio) using a string format. This consists of a gensio type, optional options in parenthesis. For a terminal gensio (one that is at the bottom of the stack), it may take more options separated by a comma. For filter gensios (ones not on the bottom of the stack) another gensio must be specified after the comma. For instance: .IP serialdev,/dev/ttyS0 .PP specifies a serial port gensio. Or: .IP tcp(readbuf=100),localhost,4000 .PP specifies a TCP connection with a 100 byte read buffer, to connect to port 4000 on localhost. Or: .IP telnet,tcp,localhost,4000 .PP specifies a telnet filter on top of a TCP connection. When specifying a gensio, you can add quotes (single or double) to remove the special meaning for some characters, so you can have commas in options and such. They may also be escaped with a "\e". For instance, if you are specifying a laddr in an sctp address, you need to do this. The following address: .IP sctp(laddr=localhost,4001),localhost,3023 .PP will result in a failure because the option splitting code will split at the commas. Instead, do: .IP sctp(laddr="localhost,4001"),localhost,3023 .PP and it will work. Accepter gensios, gensios used for accepting connections, as opposed to connecting gensios, are specified in the same way. Each individual type can vary, and some gensios are only connecting gensios. The options can vary from the accepter and connecting gensios of the same type. For instance, an accepting TCP gensio does not have to have a hostname, but a connecting one does. When an accepter gensio receives a connection, it will create an accepted gensio. This works mostly like a connecting gensio, except some functions may be limited. You may not be able to close and then open an accepted gensio. The gensio library has a concept of client and server. The accepted gensios are generally considered servers. Connecting gensios are generally considered clients. Some gensios may allow this to be overridden. A gensio may be reliable or not. A reliable gensio will reliably deliver all data in sequence, like TCP. An gensio that is not reliable may drop data or deliver data out of sequence, like UDP. This can be queried with .B gensio_is_reliable(). A gensio may be packet or not. A packet gensio will exactly match up writes and reads. So if you write 15 bytes into one side, a 15 byte read for that data will appear on the other side. A gensio that is not packet will not respect write boundaries, that 15 byte write may result in multiple reads or it may be combined with another write into more than 15 bytes. Packet I/O requires careful use to make it work correctly. If the gensio doesn't have room for another packet, a write will succeed but write 0 bytes. Otherwise if you write larger than a packet size, it will only take the number of bytes that can fit into a packet, so it will truncate. This is useful if you want to stream over a packet interface, but if you really want packets you have to make sure all the sizes are set properly. Particularly, you must set the max read and write size to the same value. You should check on writes that it wrote all the data. You can do partial read handling, if you like, but you will only get the rest of the packet on the second and following read. A gensio may be message oriented. This implementation is stolen from SCTP (even though it's not really supported on Linux at the moment). It basically means you can explicitly mark message boundaries when sending data, and that explicit mark will be set on the read side. You do this by adding an "eom" auxdata on the write; the end of that write it assumed to be the end of a message. If the write does not accept all the data, the "eom" is ignored, you must write the remaining data again with "eom" set. You may also do partial write of messages and set "eom" at the end. On the receive side, "eom" will be set when the end of a message is delivered. The data delivered in the receive callback will be only the data for that message. If the user does not accept all the data, the data left in the message is again presented to the user with "eom" set. The options vary greatly between the different gensios. Each gensio type will be covered in a separate section. Also note that gensio types can be dynamically added by the user, so there may be gensios available that are not described here. Unless otherwise noted, every gensio takes a: .TP .B readbuf= option to specify the read buffer size. .SH "DEFAULTS" Every option to a gensio (including the serialdev and ipmisol options), unless othersize stated, is available as a default for the gensios. You can use gensio_set_default() to set the default value used by all gensios allocated after that point. If you leave the class NULL, it will set the base default, which will affect all gensios unless they have an override. If you set the class, it will only affect gensios with that class name. Be very careful with some defaults. Setting "mode" default, for instance, could really screw things up. For string defaults, setting the default value to NULL causes the gensio to use it's backup default. .SH "Streams and Channels" Some gensios support the concept of a stream and/or a channel. A stream is delivered as part of the normal data stream of a gensio. The "default" stream will be treated normally. All other streams will have "stream=" given in the auxdata to specify which stream to write on or which stream was read from. Streams cannot be individually flow controlled. A channel is a flow of data like a stream, but it can be individually flow controlled. It appears as a new gensio in the .I GENSIO\_EVENT\_NEW\_CHANNEL callback. You can create a channel with .B gensio\_alloc\_channel() and then open it with .B gensio\_open(). Once open, a channel works like a normal gensio. If you close the main channel for a gensio, the other channels will stay open; the resources for the main channel will still be kept around until all channels are closed. See the indvidual gensio description for more information on streams and channels. .SH "PUBLIC KEY CRYPTOGRAPHY" The ssl and certauth gensios use public key cryptography. This section gives a little overview of how that works. You can safely skip this section if you already understand these concepts. Public key cryptography is used to authenticate and encrypt information at the beginning of a session. It is a fairly expensive operation and is not generally used to encrypt information after the beginning. In public key cryptography, you have three basic things: A private key, a certificate (or public key), and a certificate authority (CA). The private key is just that: private. You don't even send your private key to a certificate authority for signing of your certificate. Keep it private, non-readable by everyone else. Protect it, if it becomes known your certificate becomes useless to you, anyone can impersonate you. The certificate is the public key, and is mathematically associated with a single private key. It's just that, public, anyone can use it to test that you have the private key by asking you to sign some data. The data in the certificate (like the Common Name) is part of the certificate. If that data is modified, the certificate validation will fail. The CA is generally a trusted third-party that validates you and signs your certificate (generally for a fee). CAs issue their own public certificates that are well-known and generally available on your system. The CA certificates are used to prove that your certificate is valid. .SS "SIGNING" The process if signing has been mentioned already, but not described. Basically, you use your private key to generate a value over some given data that proves you have the private key. The certificate is ised to mathematically verify the signature. Two things are normally done with this: In a public key exchange, the entity wishing to be authorized sends a certificate. The authorizing entity will look through it's CA for a certificate that has signed the sent certificate. If the authorizing entity finds a certificate that can be used to validate the sent certificate, the sent certificate is valid. After that, the authorizing entity sends some generally random data to the other entity. The other entity will take that data, perhaps some other important data that it want to make sure is not modified in the transfer, and signs that data. It sends the signature back to the authorizing entity. The authorizing entity can then use the data and the signature to validate that the sending entity has the private key associated with the certificate. This is basically how https works. Note it is the .B web client that authenticates the .B web server, not the other way around. This proves that you are connecting to the entity you say you are connecting to. The authentication of a web client to the web server is generally done via a different mechanism (though SSL/TLS used by the ssl gensio has a way to do it, it is not generally used for that purpose). In the web server scenario, data in the certificate (specifically the Common Name and Subject Alternate Name) must match the name of the web page to which you are connecting. The ssl and certauth gensios do not do this authentication, that is up to the user if it is necessary. .SS "ENCRYPTING" The certificate can be used to encrypt data that can only be decrypted with the private key. When establishing an encrypted connection, this is generally used to transfer a symmetric cryptography key from one entity to another (the authorizing entity to the requesting entity in the case above). You could encrypt all the data with the public key, but that is very expensive and in our example above would require certificates and private keys on both ends. .SS "SELF-SIGNED CERTIFICATES" It is possible to create a certificate that can act as its own certificate authority. This is how ssh works. You create a public and private key. You put the public key in the .ssh/authorized_keys directory on systems where you want to log in. The certificate acts as both the public key (as part of the initial transfer) and the CA (in the authorized_key directory) for authorizing you use of the system you are logging in to. ssh also stores places it has connected to in .ssh/known_hosts, which is the CA in the opposite direction. This is why it asks you if you have never connected to a system before, it doesn't have the key in its CA. Or why, if you connect to a system you have connected to before and the certificates don't match or fail validation, it complains about it. So if you are using self-signed certificates, you need to be careful to put only ones you trust in the CA. This is obviously not possible in a large system like the world wide web, thus the creation of third-party trusted CAs. .SS "TRUST AND CRYPTOGRAPHY" The above discussions mention trust several times. Cryptography does not remove the need for trust. It just makes trust more convenient. If someone sends you a certificate, you need to validate that it was actually them that sent you the certificate, and that it was not modified in transit. If you add that certificate to your CA, you are trusting the certificate, and you better make sure (with fingerprints, generally, see the openssl docs for details) that it came from a trusted entity. The hardest part of cryptography in general is key management. Breaking cryptographic algorithms is really hard. Getting people to divulge private keys or use the wrong keys is a lot easier. For more on cryptography in general, and cryptography and trust, Bruce Schneier has some excellent books on the subject. .SH "IPv6, IPv4, and host names" Note that a single hostname may result in more than one address. For instance, it may have both an IPv4 and IPv6 address. These are treated just like multiple hostnames. For instance, if you use localhost as a host name, you generally get the IPv4 and IPv6 version: .IP $ gensiot -a -p tcp,localhost,1234 .br Address 0(0): ipv6,::1,1234 .br Address 1(0): ipv4,127.0.0.1,1234 .PP The hostname may be prefixed with ipv4 or ipv6, which will force the connections to those protocols. Specifying ipv6n4 will create a socket that is IPv6 but will handle IPv4 connections. Note that using ipv6n4 will not automatically create a socket that is available to IPv4. You can do, say .B tcp,ipv6n4,::1,1234 and it will work, but since .B ::1 is not IPv4, you won't be able to get to it from IPv4. You have to specify an IPv4 address, like: .B tcp,ipv6n4,127.0.0.1,1234 which will result in a single IPv6 socket mapped into IPv4 space: .IP $ gensiot -a -p tcp,ipv6n4,localhost,1234 .br Address 0(0): ipv6,::ffff:127.0.0.1,1234 .PP If you do not specify a hostname on an accepting gensio (like sctp,1234) it will only create an IPv6 socket that is IPv4 mapped. This way it will accept both IPv4 and IPv6 connections. Even though getaddrinfo would normally return two addresses, only the IPv6 one is used unless there are no IPv6 addresses configured where it will return an IPv4 address. In general, for connecting gensios only the first address that is found will be used. SCTP is the exception, it will do multi-homing on all the addresses that come up. Do you may need to be fairly specific with addresses. In general IPv6 addresses are preferred if both are available. .SH "gtime" Time consists of a set of numbers each followed by a single letter. That letter may be 'D', 'H', 'M', 's', 'm', 'u', or 'n', meaning days, hours, minutes, seconds, milliseconds, microseconds, or nanoseconds. So, for instance, "10D5H4M9s100u" would be ten days, 5 hours, 4 minutes, 9 seconds, 100 microseconds. If a plain number with no letter at the end is given, the value may default to a specific unit. That will be specified by the specific gensio. .SH "Drain Timeout" Many gensios store data queued to be sent. On a close, by default they will wait until the output has completely been sent before finishing the close. This is normally what you want, but may not be desirable in some situations. So these gensios will implement a .B drain_timeout option, and there is a corresponding control for setting it after creation. The .B drain_timeout is he amount of time to wait for data to drain on a close. This sets the time (in milliseconds) that the gensio will wait for the data to drain before shutting down with pending data. If you set this to a negative value, it will wait forever, which is the default. Though not really forever, some lower layer is going to time out and shut the connection down before you reach this. .SH "TCP" .B tcp[()][,],[[,],[...]] .br .B hostname = [ipv4|ipv6|ipv6n4,] A TCP connecting gensio must have the hostname specified. Multiple hostname/port pairs may be specified. For a connecting TCP gensio, each one will be tried in sequence until a connection is established. For acceptor gensios, every specified hostname/port pair will be listened to. .SS Dynamic Ports For accepters, if the port is specified as zero, a random port in the dynamic port range specified by IANA will be chosen. If more than one address is present, the same port will be chosen for all addresses. You can fetch the port using the gensio_acc_control() function with the option GENSIO_ACC_CONTROL_LPORT. .SS Out Of Band Data TCP supports out of band (oob) data, which is data that will be delivered out of order as soon as possible. This comes in a normal read, but with "oob" in the auxdata. You can send oob data by adding "oob" to the write auxdata, but oob writes are limited to 1 byte and writing any more than this results in undefined behavior. Note that "oobtcp" is also delivered and accepted in auxdata, so you can tell TCP oob data from other oob data. .SS Options In addition to readbuf, the tcp gensio takes the following options: .TP .B nodelay[=true|false] Sets nodelay on the socket. .TP .B laddr= An address specification to bind to on the local socket to set the local address. .TP .B reuseaddr[=true|false] Set SO_REUSEADDR on the socket, good for accepting gensios only. Defaults to true. .TP .B tcpd=on|print|off Accepter only, sets tcpd handling on the socket. If "on", tcpd is enforced and the connection is just closed on a tcpd denial. "print" is like on, except it writes "Access Denied" on the socket before closing it. "off" disabled tcpd handling on the socket. Defaults to on. Not available if tcpd is disabled at compile time. .TP .B tcpdname= Accepter only, sets the name to use for tcpd access control. This defaults to "gensio", and the default can be overridden with gensio_set_progname(). This option allows you to override it on a per-gensio accepter basis. Not available if tcpd is disabled at compile time. .SS Remote Address String The remote address will be in the format "[ipv4|ipv6],," where the address is in numeric format, IPv4, or IPv6. .SS Remote Address TCP returns a standard struct sockaddr for GENSIO_CONTROL_RADDR_BIN control. .SS "Direct Allocation" Allocated as a terminal gensio with gdata as a "const struct gensio_addr *" .SH "UDP" .B udp[()][,],[[,],[...]] .br .B hostname = [ipv4|ipv6|ipv6n4,] .B unixdgram[()][,] A UDP gensio creates a UDP socket, but it makes it look like an unrealiable stream of data. The specification is the same as a TCP socket, except that a UDP socket is created, obviously. A unixdgram socket is a Unix datagram socket. It has similar semantics to UDP as described below. The only difference is that if you transmit without assigning an laddr, you will not have an address. The accepting gensio will not get an address, and if it tries to transmit back to you it will get an error. The semantics of a UDP socket are a little bit strange. A connecting UDP socket is fairly straightforward, it opens a local socket and sends data to the remote socket. A UDP accepter gensio is not so straightforward. The accepter gensio will create a new accepted gensio for any packet it receives from a new remote host. If you disable read on any of the accepted gensio or disable accepts on the accepting gensio, it will stop all reads on all gensios associated with that accepting gensio. Note that UDP accepter gensios are not really required for using UDP, the are primarily there for handling ser2net accepter semantics. You can create two connecting UDP gensios and communicate between them. UDP gensios are not reliable, but are obviously packet-oriented. Port 0 is supported just like TCP for accepters, see Dynamic Ports in the TCP section above for details. The destination address defaults to the one specified on the gensio specifier (for connecting gensios) or the remote address that initiated the connection (for accepting gensios), but may be overridden using "addr:" in the write auxdata. .SS Options In addition to readbuf, the udp gensio takes the following options: .TP .B laddr= An address specification to bind to on the local socket to set the local address. .TP .B nocon[=true|false] Don't be connection oriented, just receive all packets and deliver them without establishing connections. Only valid for the client gensio. The receive address is passed into the auxdata prefixed by "addr:", this is the address formatted by gensio_addr_to_str(). .TP .B mloop[=true|false] UDP only. If false, multicast packets transmitted will not be received on the local host. If true, they will. .TP .B mttl=[1-255] UDP only. Set the multicast time-to-live value. The default is 1, meaning multicast stays in the local network. Increasing this value increases the number of hops over multicast routers a send packet will traverse. .TP .B mcast= UDP only. Add an address to receive multicast packets on. There is no port number, this is just addresses. You can specify multiple addresses in a single multicast option and/or the multicast option can be used multiple times to add multiple multicast addresses. .TP .B reuseaddr[=true|false] UDP only. Set SO_REUSEADDR on the socket, good for connecting and accepting gensios. Defaults to false. .B delsock[=true|false] unixdomain only. If the socket path already exists, delete it before opening the socket. .TP .B umode=[0-7|[rwx]*] unixdomain only. Set the user file mode for the unix socket file. This is the usual read(4)/write(2)/execute(2) bitmask per chmod, but only for the user portion. If a mode is specified, all other modes default to "6" (rw) +unless they are specified, and the final mode is modified by the umask +per standard *nix semantics. If no mode is specified, it is set to +the default and not modified. Note that the perm option below is +probably a better way to set this. .TP .B gmode=[0-7|[rwx]*] unixdomain only. Set the group file mode for the unix socket file, see umode for details. .TP .B omode=[0-7|[rwx]*] unixdomain only. Set the other file mode for the uix socket file, see umode for details. .TP .B perm=[0-7][0-7][0-7] unixdomain only. Set the full mode for the unix socket file per standard *nix semantics, modified by umask as the above mode operations are. .TP .B owner= unixdomain only. Set the owner of the unix socket file to the given user. .TP .B group= unixdomain only. Set the group of the unix socket file to the given group. .SS "Remote Address String" The remote address will be in the format "[ipv4|ipv6],," where the address is in numeric format, IPv4, or IPv6. Or it will be "unix," for unixdomain. .SS "Remote Address" UDP returns a standard struct sockaddr for GENSIO_CONTROL_RADDR_BIN control. .SS "UDP Multicast" Multicast can be used on UDP gensios with the .B nocon, maddr and .B laddr options. To set up a multicast, create a client UDP gensio and set the laddr for the receive port and the destination address to the multicast and enable nocon, like: .IP "udp(mcast='ff02::1',laddr='ipv6,3000',nocon),ff02::1,3000" .PP and you will receive and send data on the multicast address. The .B laddr option is required to set the port to receive on. It means you will have a local address, too, and will receive packets on that, too. .SS "Direct Allocation" Allocated as a terminal gensio with gdata as a "const struct gensio_addr *" .SH "SCTP" .B sctp[()][,],[[,],[...]] .br .B hostname = [ipv4|ipv6|ipv6n4,] An SCTP gensio is specified like a UDP or TCP one. However, the semantics are different. For a connecting gensio, it will attempt to create a multi-homed connect with all the specified hostnames and ports. All the ports must be the same. For an accepter gensio, it will create a single socket with all the specified addresses as possible destinations. Again, all the ports must be the same. SCTP gensios are reliable. They are not, at the moment, packet oriented. There is currently no support of SCTP_EXPLICIT_EOR in the Linux implementation of SCTP, and without that it would be hard to make it packet oriented. When specifying IPv6 addresses that might map to IPv4, you must be careful. If one side can do IPv4 and the other side can only do IPv6, the connection may come up, but will disconnect quickly because it cannot communicate on the IPv4 side. For instance, the following accepter: .IP tools/gensiot -a "sctp,ipv6,::,1234" .PP and the following connector: .IP tools/gensiot "sctp,::1,1234" .PP will fail this way because the connector will support IPv4 add but the accepter will not. .SS Nagle and SCTP SCTP implements the Nagle algorithm by default, which can interact badly if .B sack_freq is set to more than one. At least Linux defaults .B sack_freq to 2, but the gensio overrides this to avoid surprising behaviour. What happens is in some situations you can get an outstanding packet that is unacked, since .B sack_freq is greater than one. The Nagle algorithm will not send any new data until any already sent data is acked. So one end is waiting for a new packet to send a sack, and the other end is holding data until it gets a sack. So you get stuck waiting for the .B sack_delay where the sack will go out and kick things back off again. You need to be aware of this if you modify sack_freq. .SS Options In addition to readbuf, the sctp gensio takes the following options: .TP .B instreams= .TP .B ostreams= These specify the number of incoming and outgoing streams for the connection. The default is one. The stream is given in the auxdata for read and write in the format "stream=". .TP .B sack_freq= .TP .B sack_delay= These specify the handling of selective acknowledgements (sacks). .B sack_freq sets the number of outstanding packets that must be received before sending a sack. The default is 1, meaning it doesn't wait at all. .B sack_delay sets the maximum time before a sack is sent if outstanding packets are present, in milliseconds. The default is 10, but this is disabled if .B sack_freq is set to 1. Setting either of these to 0 enables the system defaults. .TP .B nodelay[=true|false] Sets nodelay on the socket. .TP .B laddr= An address specification to bind to on the local socket to set the local address. .TP .B reuseaddr[=true|false] Set SO_REUSEADDR on the socket, good for accepting gensios only. Defaults to true. Port 0 is supported just like TCP for accepters, see Dynamic Ports in the TCP section above for details. SCTP support out of band (oob) data, which is data that will be delivered out of order as soon as possible. This comes in a normal read, but with "oob" in the auxdata. You can send oob data by adding "oob" to the write auxdata. See documentation on SCTP for more details. .SS "Remote Address String" The remote address will be in the format "[ipv4|ipv6],,[;[ipv4|ipv6],,[...]]" where the address is in numeric format, IPv4, or IPv6. Each remote address for the SCTP connection is listed. .SS "Remote Address" SCTP returns a packed struct sockaddr for GENSIO_CONTROL_RADDR_BIN control, per SCTP semantics. .SS "Direct Allocation" Allocated as a terminal gensio with gdata as a "const struct gensio_addr *" .SH "UNIX" .B unix[()], .B unixseq[()], Create a unix domain stream socket as an accepter, or connect to a unix domain socket as a connecter. unixseq is like unix, but creates a SOCK_SEQPACKET sockets instead of a SOCK_STREAM socket. It works the same as unix, except that it is packet-oriented. Though it may sound strange, the unix gensio is available on Windows, and works about the same as it does on Unix systems. unixseq and unixdgram are not currently available on Windows, though. However, you cannot set the permissions like you can on Windows. It's possible to create something that might work, but it's complicated. For permissions, you can create a directory with the permissions you want and then create the socket in that directory. The socket will inherit the permissions of the directory by default. A file will be created with the given socket path, you must have permissions to create a writeable file in that location. If the file already exists, an error will be returned on an accepter socket unless you specify .I delsock which will cause the file to be deleted. You should read the unix(7) man page for details on the semantics of these sockets, especially permissions. The options below allow setting various permission and ownership of the file, but this may not have any effect on who can open socket depending on the particular operating system. .B Portable programs should not rely on these permissions for security. Also note that Linux remote credentials are not currently implemented. .SS Options In addition to readbuf, the unix gensio takes the following options: .TP .B delsock[=true|false] If the socket path already exists, delete it before opening the socket. .TP .B umode=[0-7|[rwx]*] Set the user file mode for the unix socket file. This is the usual read(4)/write(2)/execute(1) bitmask per chmod, but only for the user portion. If a mode is specified, all other modes default to "6" (rw) unless they are specified, and the final mode is modified by the umask per standard *nix semantics. If no mode is specified, it is set to the default and not modified. Note that the perm option below is probably a better way to set this. Not available on Windows. .TP .B gmode=[0-7|[rwx]*] Set the group file mode for the unix socket file, see umode for details. .TP .B omode=[0-7|[rwx]*] Set the other file mode for the uix socket file, see umode for details. .TP .B perm=[0-7][0-7][0-7] Set the full mode for the unix socket file per standard *nix semantics, modified by umask as the above mode operations are. Not available on windows. .TP .B owner= Set the owner of the unix socket file to the given user. Not available on windows. .TP .B group= Set the group of the unix socket file to the given group. Not available on windows. .TP .B peerusers=[;[;...]] Sets the *nix users allowed to connect to this socket. If set, any connection received from a user that is not in this user list will cause the connection to be immediately closed. You may use peerusers and peergroups together, if so the connection is permitted if either check succeeds. Not available on windows. .TP .B peergrps=[;[;...]] Sets the *nix groups allowed to connect to this socket. If set, any connection received from a users that whose group is not in this list will cause the connection to be immediately closed. Not available on windows. .SS Remote Address String The remote address will be: "unix,". .SS Remote Address UNIX returns a standard struct sockaddr_un for GENSIO_CONTROL_RADDR_BIN control. .SS "Direct Allocation" Allocated as a terminal gensio with gdata as a "const struct gensio_addr *" .SH "serialdev" connecting = .B serialdev[()],[,[,]] A serialdev connection is a local serial port. The device is a .B /dev/xxx type on Unix-type systems, and should be real stream device of some type that normal termios or serial processing work on. On Windows system, the device is .B //./COM where is the port number that you see in the device manager. Note that these can move around when you reboot; I'm not sure there is a way to fix that. For non-serial devices, use the "dev" gensio. This is, no surprise, a serial gensio. You can also use "sdev" instead of "serialdev" for shorthand. One problem with serialdev and UUCP locking is that if you fork() a process while one is open, the forked process will have the serialdev but the value in the UUCP lockfile will be incorrect. There's not much that can be done about this, so be careful. .SS Options In addition to readbuf, the serialdev gensio takes the following options: .TP .B uucplock[=true|false] Enable or disable UUCP locking on the device. The default is true for everything except pty devices and /dev/tty. This is ignored on systems that don't support this. .TP .B flock[=true|false] Enable or disable flock locking on the device. The default is true for everything except /dev/tty. Note that this does both an "flock(fd, LOCK_EX | LOCK_NB)" and an "ioctl(fd, TIOCNXCL)" to lock the device. This is ignored on systems that don't support this. .TP .B drain_time=off|