Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

Location:
vendor/current/lib/talloc
Files:
42 added
5 deleted
11 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/lib/talloc/doc/mainpage.dox

    r740 r988  
    1111 * on the samba public source archive.
    1212 *
     13 * @section main-tutorial Tutorial
     14 *
     15 * You should start by reading @subpage libtalloc_tutorial, then reading the documentation of
     16 * the interesting functions as you go.
     17
    1318 * @section talloc_bugs Discussion and bug reports
    1419 *
     
    98103 *     context implicitly refers to a hidden "null context" global variable, so
    99104 *     this should not be used in a multi-threaded environment without proper
    100  *     synchronization.
     105 *     synchronization. In threaded code turn off null tracking using
     106 *     talloc_disable_null_tracking().
    101107 *   - the context returned by talloc_autofree_context() is also global so
    102108 *     shouldn't be used by several threads simultaneously without
  • vendor/current/lib/talloc/doxy.config

    r740 r988  
    1 # Doxyfile 1.6.1
     1# Doxyfile 1.8.0
    22
    33# This file describes the settings to be used by the documentation system
    4 # doxygen (www.doxygen.org) for a project
     4# doxygen (www.doxygen.org) for a project.
    55#
    6 # All text after a hash (#) is considered a comment and will be ignored
     6# All text after a hash (#) is considered a comment and will be ignored.
    77# The format is:
    88#       TAG = value [value, ...]
    99# For lists items can also be appended using:
    1010#       TAG += value [value, ...]
    11 # Values that contain spaces should be placed between quotes (" ")
     11# Values that contain spaces should be placed between quotes (" ").
    1212
    1313#---------------------------------------------------------------------------
     
    2323DOXYFILE_ENCODING      = UTF-8
    2424
    25 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded
    26 # by quotes) that should identify the project.
     25# The PROJECT_NAME tag is a single word (or sequence of words) that should
     26# identify the project. Note that if you do not use Doxywizard you need
     27# to put quotes around the project name if it contains spaces.
    2728
    2829PROJECT_NAME           = talloc
     
    3334
    3435PROJECT_NUMBER         = 2.0
     36
     37# Using the PROJECT_BRIEF tag one can provide an optional one line description
     38# for a project that appears at the top of each page and should give viewer
     39# a quick idea about the purpose of the project. Keep the description short.
     40
     41PROJECT_BRIEF          =
     42
     43# With the PROJECT_LOGO tag one can specify an logo or icon that is
     44# included in the documentation. The maximum height of the logo should not
     45# exceed 55 pixels and the maximum width should not exceed 200 pixels.
     46# Doxygen will copy the logo to the output directory.
     47
     48PROJECT_LOGO           =
    3549
    3650# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
     
    5872# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
    5973# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
    60 # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
     74# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
    6175# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
    6276
     
    137151
    138152# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
    139 # (but less readable) file names. This can be useful is your file systems
     153# (but less readable) file names. This can be useful if your file system
    140154# doesn't support long names like on DOS, Mac, or CD-ROM.
    141155
     
    192206ALIASES                =
    193207
     208# This tag can be used to specify a number of word-keyword mappings (TCL only).
     209# A mapping has the form "name=value". For example adding
     210# "class=itcl::class" will allow you to use the command class in the
     211# itcl::class meaning.
     212
     213TCL_SUBST              =
     214
    194215# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
    195216# sources only. Doxygen will then generate output that is more tailored for C.
     
    218239OPTIMIZE_OUTPUT_VHDL   = NO
    219240
    220 # Doxygen selects the parser to use depending on the extension of the files it parses.
    221 # With this tag you can assign which parser to use for a given extension.
    222 # Doxygen has a built-in mapping, but you can override or extend it using this tag.
    223 # The format is ext=language, where ext is a file extension, and language is one of
    224 # the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
    225 # Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat
    226 # .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran),
    227 # use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
     241# Doxygen selects the parser to use depending on the extension of the files it
     242# parses. With this tag you can assign which parser to use for a given extension.
     243# Doxygen has a built-in mapping, but you can override or extend it using this
     244# tag. The format is ext=language, where ext is a file extension, and language
     245# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
     246# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
     247# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
     248# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
     249# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
    228250
    229251EXTENSION_MAPPING      =
     252
     253# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all
     254# comments according to the Markdown format, which allows for more readable
     255# documentation. See http://daringfireball.net/projects/markdown/ for details.
     256# The output of markdown processing is further processed by doxygen, so you
     257# can mix doxygen, HTML, and XML commands with Markdown formatting.
     258# Disable only in case of backward compatibilities issues.
     259
     260MARKDOWN_SUPPORT       = YES
    230261
    231262# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
     
    233264# set this tag to YES in order to let doxygen match functions declarations and
    234265# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
    235 # func(std::string) {}). This also make the inheritance and collaboration
     266# func(std::string) {}). This also makes the inheritance and collaboration
    236267# diagrams that involve STL classes more complete and accurate.
    237268
     
    251282# For Microsoft's IDL there are propget and propput attributes to indicate getter
    252283# and setter methods for a property. Setting this option to YES (the default)
    253 # will make doxygen to replace the get and set methods by a property in the
     284# will make doxygen replace the get and set methods by a property in the
    254285# documentation. This will only work if the methods are indeed getting or
    255286# setting a simple type. If this is not the case, or you want to show the
     
    272303
    273304SUBGROUPING            = YES
     305
     306# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
     307# unions are shown inside the group in which they are included (e.g. using
     308# @ingroup) instead of on a separate page (for HTML and Man pages) or
     309# section (for LaTeX and RTF).
     310
     311INLINE_GROUPED_CLASSES = NO
     312
     313# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
     314# unions with only public data fields will be shown inline in the documentation
     315# of the scope in which they are defined (i.e. file, namespace, or group
     316# documentation), provided this scope is documented. If set to NO (the default),
     317# structs, classes, and unions are shown on a separate page (for HTML and Man
     318# pages) or section (for LaTeX and RTF).
     319
     320INLINE_SIMPLE_STRUCTS  = NO
    274321
    275322# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
     
    289336# probably good enough. For larger projects a too small cache size can cause
    290337# doxygen to be busy swapping symbols to and from disk most of the time
    291 # causing a significant performance penality.
     338# causing a significant performance penalty.
    292339# If the system has enough physical memory increasing the cache will improve the
    293340# performance by keeping more symbols in memory. Note that the value works on
    294 # a logarithmic scale so increasing the size by one will rougly double the
     341# a logarithmic scale so increasing the size by one will roughly double the
    295342# memory usage. The cache size is given by this formula:
    296343# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
    297 # corresponding to a cache size of 2^16 = 65536 symbols
     344# corresponding to a cache size of 2^16 = 65536 symbols.
    298345
    299346SYMBOL_CACHE_SIZE      = 0
     347
     348# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
     349# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
     350# their name and scope. Since this can be an expensive process and often the
     351# same symbol appear multiple times in the code, doxygen keeps a cache of
     352# pre-resolved symbols. If the cache is too small doxygen will become slower.
     353# If the cache is too large, memory is wasted. The cache size is given by this
     354# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
     355# corresponding to a cache size of 2^16 = 65536 symbols.
     356
     357LOOKUP_CACHE_SIZE      = 0
    300358
    301359#---------------------------------------------------------------------------
     
    315373EXTRACT_PRIVATE        = NO
    316374
     375# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation.
     376
     377EXTRACT_PACKAGE        = NO
     378
    317379# If the EXTRACT_STATIC tag is set to YES all static members of a file
    318380# will be included in the documentation.
     
    337399# 'anonymous_namespace{file}', where file will be replaced with the base
    338400# name of the file that contains the anonymous namespace. By default
    339 # anonymous namespace are hidden.
     401# anonymous namespaces are hidden.
    340402
    341403EXTRACT_ANON_NSPACES   = NO
     
    397459SHOW_INCLUDE_FILES     = YES
    398460
     461# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
     462# will list include files with double quotes in the documentation
     463# rather than with sharp brackets.
     464
     465FORCE_LOCAL_INCLUDES   = NO
     466
    399467# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
    400468# is inserted in the documentation for inline members.
     
    416484SORT_BRIEF_DOCS        = NO
    417485
    418 # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
     486# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
     487# will sort the (brief and detailed) documentation of class members so that
     488# constructors and destructors are listed first. If set to NO (the default)
     489# the constructors will appear in the respective orders defined by
     490# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
     491# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
     492# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
    419493
    420494SORT_MEMBERS_CTORS_1ST = NO
     
    436510SORT_BY_SCOPE_NAME     = NO
    437511
     512# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
     513# do proper type resolution of all parameters of a function it will reject a
     514# match between the prototype and the implementation of a member function even
     515# if there is only one candidate or it is obvious which candidate to choose
     516# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
     517# will still accept a match between prototype and implementation in such cases.
     518
     519STRICT_PROTO_MATCHING  = NO
     520
    438521# The GENERATE_TODOLIST tag can be used to enable (YES) or
    439522# disable (NO) the todo list. This list is created by putting \todo
     
    466549
    467550# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
    468 # the initial value of a variable or define consists of for it to appear in
     551# the initial value of a variable or macro consists of for it to appear in
    469552# the documentation. If the initializer consists of more lines than specified
    470553# here it will be hidden. Use a value of 0 to hide initializers completely.
    471 # The appearance of the initializer of individual variables and defines in the
     554# The appearance of the initializer of individual variables and macros in the
    472555# documentation can be controlled using \showinitializer or \hideinitializer
    473556# command in the documentation regardless of this setting.
     
    480563
    481564SHOW_USED_FILES        = YES
    482 
    483 # If the sources in your project are distributed over multiple directories
    484 # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
    485 # in the documentation. The default is NO.
    486 
    487 SHOW_DIRECTORIES       = NO
    488565
    489566# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
     
    510587FILE_VERSION_FILTER    =
    511588
    512 # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
    513 # doxygen. The layout file controls the global structure of the generated output files
    514 # in an output format independent way. The create the layout file that represents
    515 # doxygen's defaults, run doxygen with the -l option. You can optionally specify a
    516 # file name after the option, if omitted DoxygenLayout.xml will be used as the name
    517 # of the layout file.
     589# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
     590# by doxygen. The layout file controls the global structure of the generated
     591# output files in an output format independent way. The create the layout file
     592# that represents doxygen's defaults, run doxygen with the -l option.
     593# You can optionally specify a file name after the option, if omitted
     594# DoxygenLayout.xml will be used as the name of the layout file.
    518595
    519596LAYOUT_FILE            =
     597
     598# The CITE_BIB_FILES tag can be used to specify one or more bib files
     599# containing the references data. This must be a list of .bib files. The
     600# .bib extension is automatically appended if omitted. Using this command
     601# requires the bibtex tool to be installed. See also
     602# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
     603# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
     604# feature you need bibtex and perl available in the search path.
     605
     606CITE_BIB_FILES         =
    520607
    521608#---------------------------------------------------------------------------
     
    547634WARN_IF_DOC_ERROR      = YES
    548635
    549 # This WARN_NO_PARAMDOC option can be abled to get warnings for
     636# The WARN_NO_PARAMDOC option can be enabled to get warnings for
    550637# functions that are documented, but have no documentation for their parameters
    551638# or return value. If set to NO (the default) doxygen will only warn about
     
    579666# with spaces.
    580667
    581 INPUT                  = . doc
     668INPUT                  = . \
     669                         doc
    582670
    583671# This tag can be used to specify the character encoding of the source files
     
    593681# and *.h) to filter out the source-files in the directories. If left
    594682# blank the following patterns are tested:
    595 # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
    596 # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
     683# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
     684# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
     685# *.f90 *.f *.for *.vhd *.vhdl
    597686
    598687FILE_PATTERNS          = *.cpp \
     
    610699RECURSIVE              = NO
    611700
    612 # The EXCLUDE tag can be used to specify files and/or directories that should
     701# The EXCLUDE tag can be used to specify files and/or directories that should be
    613702# excluded from the INPUT source files. This way you can easily exclude a
    614703# subdirectory from a directory tree whose root is specified with the INPUT tag.
     704# Note that relative paths are relative to the directory from which doxygen is
     705# run.
    615706
    616707EXCLUDE                =
    617708
    618 # The EXCLUDE_SYMLINKS tag can be used select whether or not files or
    619 # directories that are symbolic links (a Unix filesystem feature) are excluded
     709# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
     710# directories that are symbolic links (a Unix file system feature) are excluded
    620711# from the input.
    621712
     
    628719# for example use the pattern */test/*
    629720
    630 EXCLUDE_PATTERNS       = */.git/* \
    631                          */.svn/* \
    632                          */cmake/* \
    633                          */build/*
     721EXCLUDE_PATTERNS       = */.git/*
    634722
    635723# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
     
    665753# the \image command).
    666754
    667 IMAGE_PATH             =
     755IMAGE_PATH             = doc
    668756
    669757# The INPUT_FILTER tag can be used to specify a program that doxygen should
     
    684772# The filters are a list of the form:
    685773# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
    686 # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
    687 # is applied to all files.
     774# info on how filters are used. If FILTER_PATTERNS is empty or if
     775# non of the patterns match the file name, INPUT_FILTER is applied.
    688776
    689777FILTER_PATTERNS        =
     
    694782
    695783FILTER_SOURCE_FILES    = NO
     784
     785# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
     786# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
     787# and it is also possible to disable source filtering for a specific pattern
     788# using *.ext= (so without naming a filter). This option only has effect when
     789# FILTER_SOURCE_FILES is enabled.
     790
     791FILTER_SOURCE_PATTERNS =
    696792
    697793#---------------------------------------------------------------------------
     
    783879GENERATE_HTML          = YES
    784880
    785 # If the HTML_FOOTER_DESCRIPTION tag is set to YES, Doxygen will
    786 # add generated date, project name and doxygen version to HTML footer.
    787 
    788 HTML_FOOTER_DESCRIPTION= NO
    789 
    790881# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
    791882# If a relative path is entered the value of OUTPUT_DIRECTORY will be
     
    802893# The HTML_HEADER tag can be used to specify a personal HTML header for
    803894# each generated HTML page. If it is left blank doxygen will generate a
    804 # standard header.
     895# standard header. Note that when using a custom header you are responsible
     896#  for the proper inclusion of any scripts and style sheets that doxygen
     897# needs, which is dependent on the configuration options used.
     898# It is advised to generate a default header using "doxygen -w html
     899# header.html footer.html stylesheet.css YourConfigFile" and then modify
     900# that header. Note that the header is subject to change so you typically
     901# have to redo this when upgrading to a newer version of doxygen or when
     902# changing the value of configuration settings such as GENERATE_TREEVIEW!
    805903
    806904HTML_HEADER            =
     
    817915# will generate a default style sheet. Note that doxygen will try to copy
    818916# the style sheet file to the HTML output directory, so don't put your own
    819 # stylesheet in the HTML output directory as well, or it will be erased!
     917# style sheet in the HTML output directory as well, or it will be erased!
    820918
    821919HTML_STYLESHEET        =
     920
     921# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
     922# other source files which should be copied to the HTML output directory. Note
     923# that these files will be copied to the base HTML output directory. Use the
     924# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
     925# files. In the HTML_STYLESHEET file, use the file name only. Also note that
     926# the files will be copied as-is; there are no commands or markers available.
     927
     928HTML_EXTRA_FILES       =
     929
     930# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
     931# Doxygen will adjust the colors in the style sheet and background images
     932# according to this color. Hue is specified as an angle on a colorwheel,
     933# see http://en.wikipedia.org/wiki/Hue for more information.
     934# For instance the value 0 represents red, 60 is yellow, 120 is green,
     935# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
     936# The allowed range is 0 to 359.
     937
     938HTML_COLORSTYLE_HUE    = 220
     939
     940# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
     941# the colors in the HTML output. For a value of 0 the output will use
     942# grayscales only. A value of 255 will produce the most vivid colors.
     943
     944HTML_COLORSTYLE_SAT    = 100
     945
     946# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
     947# the luminance component of the colors in the HTML output. Values below
     948# 100 gradually make the output lighter, whereas values above 100 make
     949# the output darker. The value divided by 100 is the actual gamma applied,
     950# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
     951# and 100 does not change the gamma.
     952
     953HTML_COLORSTYLE_GAMMA  = 80
     954
     955# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
     956# page will contain the date and time when the page was generated. Setting
     957# this to NO can help when comparing the output of multiple runs.
     958
     959HTML_TIMESTAMP         = NO
    822960
    823961# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
     
    843981# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
    844982# it at startup.
    845 # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
     983# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
     984# for more information.
    846985
    847986GENERATE_DOCSET        = NO
     
    8611000DOCSET_BUNDLE_ID       = org.doxygen.Project
    8621001
     1002# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
     1003# the documentation publisher. This should be a reverse domain-name style
     1004# string, e.g. com.mycompany.MyDocSet.documentation.
     1005
     1006DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
     1007
     1008# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
     1009
     1010DOCSET_PUBLISHER_NAME  = Publisher
     1011
    8631012# If the GENERATE_HTMLHELP tag is set to YES, additional index files
    8641013# will be generated that can be used as input for tools like the
     
    9051054TOC_EXPAND             = NO
    9061055
    907 # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER
    908 # are set, an additional index file will be generated that can be used as input for
    909 # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated
    910 # HTML documentation.
     1056# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
     1057# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
     1058# that can be used as input for Qt's qhelpgenerator to generate a
     1059# Qt Compressed Help (.qch) of the generated HTML documentation.
    9111060
    9121061GENERATE_QHP           = NO
     
    9301079QHP_VIRTUAL_FOLDER     = doc
    9311080
    932 # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add.
    933 # For more information please see
     1081# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
     1082# add. For more information please see
    9341083# http://doc.trolltech.com/qthelpproject.html#custom-filters
    9351084
    9361085QHP_CUST_FILTER_NAME   =
    9371086
    938 # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see
    939 # <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
     1087# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
     1088# custom filter to add. For more information please see
     1089# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
     1090# Qt Help Project / Custom Filters</a>.
    9401091
    9411092QHP_CUST_FILTER_ATTRS  =
    9421093
    943 # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
     1094# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
     1095# project's
    9441096# filter section matches.
    945 # <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
     1097# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
     1098# Qt Help Project / Filter Attributes</a>.
    9461099
    9471100QHP_SECT_FILTER_ATTRS  =
     
    9541107QHG_LOCATION           =
    9551108
    956 # The DISABLE_INDEX tag can be used to turn on/off the condensed index at
    957 # top of each HTML page. The value NO (the default) enables the index and
    958 # the value YES disables it.
     1109# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
     1110#  will be generated, which together with the HTML files, form an Eclipse help
     1111# plugin. To install this plugin and make it available under the help contents
     1112# menu in Eclipse, the contents of the directory containing the HTML and XML
     1113# files needs to be copied into the plugins directory of eclipse. The name of
     1114# the directory within the plugins directory should be the same as
     1115# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
     1116# the help appears.
     1117
     1118GENERATE_ECLIPSEHELP   = NO
     1119
     1120# A unique identifier for the eclipse help plugin. When installing the plugin
     1121# the directory name containing the HTML and XML files should also have
     1122# this name.
     1123
     1124ECLIPSE_DOC_ID         = org.doxygen.Project
     1125
     1126# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
     1127# at top of each HTML page. The value NO (the default) enables the index and
     1128# the value YES disables it. Since the tabs have the same information as the
     1129# navigation tree you can set this option to NO if you already set
     1130# GENERATE_TREEVIEW to YES.
    9591131
    9601132DISABLE_INDEX          = NO
    961 
    962 # This tag can be used to set the number of enum values (range [1..20])
    963 # that doxygen will group on one line in the generated HTML documentation.
    964 
    965 ENUM_VALUES_PER_LINE   = 4
    9661133
    9671134# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
     
    9721139# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
    9731140# Windows users are probably better off using the HTML help feature.
     1141# Since the tree basically has the same information as the tab index you
     1142# could consider to set DISABLE_INDEX to NO when enabling this option.
    9741143
    9751144GENERATE_TREEVIEW      = NONE
    9761145
    977 # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
    978 # and Class Hierarchy pages using a tree view instead of an ordered list.
    979 
    980 USE_INLINE_TREES       = NO
     1146# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
     1147# (range [0,1..20]) that doxygen will group on one line in the generated HTML
     1148# documentation. Note that a value of 0 will completely suppress the enum
     1149# values from appearing in the overview section.
     1150
     1151ENUM_VALUES_PER_LINE   = 4
    9811152
    9821153# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
     
    9851156
    9861157TREEVIEW_WIDTH         = 250
     1158
     1159# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
     1160# links to external symbols imported via tag files in a separate window.
     1161
     1162EXT_LINKS_IN_WINDOW    = NO
    9871163
    9881164# Use this tag to change the font size of Latex formulas included
     
    9941170FORMULA_FONTSIZE       = 10
    9951171
    996 # When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript
    997 # and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP)
    998 # there is already a search function so this one should typically
    999 # be disabled.
     1172# Use the FORMULA_TRANPARENT tag to determine whether or not the images
     1173# generated for formulas are transparent PNGs. Transparent PNGs are
     1174# not supported properly for IE 6.0, but are supported on all modern browsers.
     1175# Note that when changing this option you need to delete any form_*.png files
     1176# in the HTML output before the changes have effect.
     1177
     1178FORMULA_TRANSPARENT    = YES
     1179
     1180# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
     1181# (see http://www.mathjax.org) which uses client side Javascript for the
     1182# rendering instead of using prerendered bitmaps. Use this if you do not
     1183# have LaTeX installed or if you want to formulas look prettier in the HTML
     1184# output. When enabled you may also need to install MathJax separately and
     1185# configure the path to it using the MATHJAX_RELPATH option.
     1186
     1187USE_MATHJAX            = NO
     1188
     1189# When MathJax is enabled you need to specify the location relative to the
     1190# HTML output directory using the MATHJAX_RELPATH option. The destination
     1191# directory should contain the MathJax.js script. For instance, if the mathjax
     1192# directory is located at the same level as the HTML output directory, then
     1193# MATHJAX_RELPATH should be ../mathjax. The default value points to
     1194# the MathJax Content Delivery Network so you can quickly see the result without
     1195# installing MathJax.
     1196# However, it is strongly recommended to install a local
     1197# copy of MathJax from http://www.mathjax.org before deployment.
     1198
     1199MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
     1200
     1201# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
     1202# names that should be enabled during MathJax rendering.
     1203
     1204MATHJAX_EXTENSIONS     =
     1205
     1206# When the SEARCHENGINE tag is enabled doxygen will generate a search box
     1207# for the HTML output. The underlying search engine uses javascript
     1208# and DHTML and should work on any modern browser. Note that when using
     1209# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
     1210# (GENERATE_DOCSET) there is already a search function so this one should
     1211# typically be disabled. For large projects the javascript based search engine
     1212# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
    10001213
    10011214SEARCHENGINE           = NO
     1215
     1216# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
     1217# implemented using a PHP enabled web server instead of at the web client
     1218# using Javascript. Doxygen will generate the search PHP script and index
     1219# file to put on the web server. The advantage of the server
     1220# based approach is that it scales better to large projects and allows
     1221# full text search. The disadvantages are that it is more difficult to setup
     1222# and does not have live searching capabilities.
     1223
     1224SERVER_BASED_SEARCH    = NO
    10021225
    10031226#---------------------------------------------------------------------------
     
    10181241# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
    10191242# invoked. If left blank `latex' will be used as the default command name.
     1243# Note that when enabling USE_PDFLATEX this option is only used for
     1244# generating bitmaps for formulas in the HTML output, but not in the
     1245# Makefile that is written to the output directory.
    10201246
    10211247LATEX_CMD_NAME         = latex
     
    10341260
    10351261# The PAPER_TYPE tag can be used to set the paper type that is used
    1036 # by the printer. Possible values are: a4, a4wide, letter, legal and
     1262# by the printer. Possible values are: a4, letter, legal and
    10371263# executive. If left blank a4wide will be used.
    10381264
     
    10511277LATEX_HEADER           =
    10521278
     1279# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
     1280# the generated latex document. The footer should contain everything after
     1281# the last chapter. If it is left blank doxygen will generate a
     1282# standard footer. Notice: only use this tag if you know what you are doing!
     1283
     1284LATEX_FOOTER           =
     1285
    10531286# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
    10541287# is prepared for conversion to pdf (using ps2pdf). The pdf file will
     
    10771310LATEX_HIDE_INDICES     = NO
    10781311
    1079 # If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER.
     1312# If LATEX_SOURCE_CODE is set to YES then doxygen will include
     1313# source code with syntax highlighting in the LaTeX output.
     1314# Note that which sources are shown also depends on other settings
     1315# such as SOURCE_BROWSER.
    10801316
    10811317LATEX_SOURCE_CODE      = NO
     1318
     1319# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
     1320# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
     1321# http://en.wikipedia.org/wiki/BibTeX for more info.
     1322
     1323LATEX_BIB_STYLE        = plain
    10821324
    10831325#---------------------------------------------------------------------------
     
    11121354RTF_HYPERLINKS         = NO
    11131355
    1114 # Load stylesheet definitions from file. Syntax is similar to doxygen's
     1356# Load style sheet definitions from file. Syntax is similar to doxygen's
    11151357# config file, i.e. a series of assignments. You only have to provide
    11161358# replacements, missing definitions are set to their default value.
     
    12571499
    12581500# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
    1259 # in the INCLUDE_PATH (see below) will be search if a #include is found.
     1501# pointed to by INCLUDE_PATH will be searched when a #include is found.
    12601502
    12611503SEARCH_INCLUDES        = YES
     
    12821524# instead of the = operator.
    12831525
    1284 PREDEFINED             = DOXYGEN PRINTF_ATTRIBUTE(x,y)=
     1526PREDEFINED             = DOXYGEN \
     1527                         PRINTF_ATTRIBUTE(x,y)=
    12851528
    12861529# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
    12871530# this tag can be used to specify a list of macro names that should be expanded.
    12881531# The macro definition that is found in the sources will be used.
    1289 # Use the PREDEFINED tag if you want to use a different macro definition.
     1532# Use the PREDEFINED tag if you want to use a different macro definition that
     1533# overrules the definition found in the source code.
    12901534
    12911535EXPAND_AS_DEFINED      =
    12921536
    12931537# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
    1294 # doxygen's preprocessor will remove all function-like macros that are alone
    1295 # on a line, have an all uppercase name, and do not end with a semicolon. Such
    1296 # function macros are typically used for boiler-plate code, and will confuse
    1297 # the parser if not removed.
     1538# doxygen's preprocessor will remove all references to function-like macros
     1539# that are alone on a line, have an all uppercase name, and do not end with a
     1540# semicolon, because these will confuse the parser if not removed.
    12981541
    12991542SKIP_FUNCTION_MACROS   = YES
     
    13031546#---------------------------------------------------------------------------
    13041547
    1305 # The TAGFILES option can be used to specify one or more tagfiles.
    1306 # Optionally an initial location of the external documentation
    1307 # can be added for each tagfile. The format of a tag file without
    1308 # this location is as follows:
     1548# The TAGFILES option can be used to specify one or more tagfiles. For each
     1549# tag file the location of the external documentation should be added. The
     1550# format of a tag file without this location is as follows:
    13091551#
    13101552# TAGFILES = file1 file2 ...
     
    13121554#
    13131555# TAGFILES = file1=loc1 "file2 = loc2" ...
    1314 # where "loc1" and "loc2" can be relative or absolute paths or
    1315 # URLs. If a location is present for each tag, the installdox tool
    1316 # does not have to be run to correct the links.
    1317 # Note that each tag file must have a unique name
    1318 # (where the name does NOT include the path)
    1319 # If a tag file is not located in the directory in which doxygen
    1320 # is run, you must also specify the path to the tagfile here.
     1556# where "loc1" and "loc2" can be relative or absolute paths
     1557# or URLs. Note that each tag file must have a unique name (where the name does
     1558# NOT include the path). If a tag file is not located in the directory in which
     1559# doxygen is run, you must also specify the path to the tagfile here.
    13211560
    13221561TAGFILES               =
     
    13511590# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
    13521591# or super classes. Setting the tag to NO turns the diagrams off. Note that
    1353 # this option is superseded by the HAVE_DOT option below. This is only a
    1354 # fallback. It is recommended to install and use dot, since it yields more
    1355 # powerful graphs.
     1592# this option also works with HAVE_DOT disabled, but it is recommended to
     1593# install and use dot, since it yields more powerful graphs.
    13561594
    13571595CLASS_DIAGRAMS         = YES
     
    13791617HAVE_DOT               = NO
    13801618
    1381 # By default doxygen will write a font called FreeSans.ttf to the output
    1382 # directory and reference it in all dot files that doxygen generates. This
    1383 # font does not include all possible unicode characters however, so when you need
    1384 # these (or just want a differently looking font) you can specify the font name
    1385 # using DOT_FONTNAME. You need need to make sure dot is able to find the font,
    1386 # which can be done by putting it in a standard location or by setting the
    1387 # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
    1388 # containing the font.
     1619# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
     1620# allowed to run in parallel. When set to 0 (the default) doxygen will
     1621# base this on the number of processors available in the system. You can set it
     1622# explicitly to a value larger than 0 to get control over the balance
     1623# between CPU load and processing speed.
     1624
     1625DOT_NUM_THREADS        = 0
     1626
     1627# By default doxygen will use the Helvetica font for all dot files that
     1628# doxygen generates. When you want a differently looking font you can specify
     1629# the font name using DOT_FONTNAME. You need to make sure dot is able to find
     1630# the font, which can be done by putting it in a standard location or by setting
     1631# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
     1632# directory containing the font.
    13891633
    13901634DOT_FONTNAME           = FreeSans
     
    13951639DOT_FONTSIZE           = 10
    13961640
    1397 # By default doxygen will tell dot to use the output directory to look for the
    1398 # FreeSans.ttf font (which doxygen will put there itself). If you specify a
    1399 # different font using DOT_FONTNAME you can set the path where dot
    1400 # can find it using this tag.
     1641# By default doxygen will tell dot to use the Helvetica font.
     1642# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
     1643# set the path where dot can find it.
    14011644
    14021645DOT_FONTPATH           =
     
    14051648# will generate a graph for each documented class showing the direct and
    14061649# indirect inheritance relations. Setting this tag to YES will force the
    1407 # the CLASS_DIAGRAMS tag to NO.
     1650# CLASS_DIAGRAMS tag to NO.
    14081651
    14091652CLASS_GRAPH            = YES
     
    14261669
    14271670UML_LOOK               = NO
     1671
     1672# If the UML_LOOK tag is enabled, the fields and methods are shown inside
     1673# the class node. If there are many fields or methods and many nodes the
     1674# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
     1675# threshold limits the number of items for each type to make the size more
     1676# managable. Set this to 0 for no limit. Note that the threshold may be
     1677# exceeded by 50% before the limit is enforced.
     1678
     1679UML_LIMIT_NUM_FIELDS   = 10
    14281680
    14291681# If set to YES, the inheritance and collaboration graphs will show the
     
    14631715
    14641716# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
    1465 # will graphical hierarchy of all classes instead of a textual one.
     1717# will generate a graphical hierarchy of all classes instead of a textual one.
    14661718
    14671719GRAPHICAL_HIERARCHY    = YES
    14681720
    1469 # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
     1721# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES
    14701722# then doxygen will show the dependencies a directory has on other directories
    14711723# in a graphical way. The dependency relations are determined by the #include
     
    14751727
    14761728# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
    1477 # generated by dot. Possible values are png, jpg, or gif
    1478 # If left blank png will be used.
     1729# generated by dot. Possible values are svg, png, jpg, or gif.
     1730# If left blank png will be used. If you choose svg you need to set
     1731# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
     1732# visible in IE 9+ (other browsers do not have this requirement).
    14791733
    14801734DOT_IMAGE_FORMAT       = png
     1735
     1736# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
     1737# enable generation of interactive SVG images that allow zooming and panning.
     1738# Note that this requires a modern browser other than Internet Explorer.
     1739# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
     1740# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
     1741# visible. Older versions of IE do not have SVG support.
     1742
     1743INTERACTIVE_SVG        = NO
    14811744
    14821745# The tag DOT_PATH can be used to specify the path where the dot tool can be
     
    14901753
    14911754DOTFILE_DIRS           =
     1755
     1756# The MSCFILE_DIRS tag can be used to specify one or more directories that
     1757# contain msc files that are included in the documentation (see the
     1758# \mscfile command).
     1759
     1760MSCFILE_DIRS           =
    14921761
    14931762# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
  • vendor/current/lib/talloc/pytalloc-util.pc.in

    r740 r988  
    77Description: Utility functions for using talloc objects with Python
    88Version: @TALLOC_VERSION@
    9 Libs: -L${libdir} -lpytalloc-util
    10 Cflags: @LIB_RPATH@ -I${includedir}
     9Libs: @LIB_RPATH@ -L${libdir} -lpytalloc-util@PYTHON_SO_ABI_FLAG@
     10Cflags: -I${includedir}
    1111URL: http://talloc.samba.org/
  • vendor/current/lib/talloc/pytalloc.c

    r740 r988  
    22   Unix SMB/CIFS implementation.
    33   Python Talloc Module
    4    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2010
     4   Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2010-2011
    55
    66   This program is free software; you can redistribute it and/or modify
     
    2121#include <talloc.h>
    2222#include <pytalloc.h>
    23 
    24 void inittalloc(void);
     23#include "pytalloc_private.h"
     24
     25static PyTypeObject TallocObject_Type;
     26
     27#if PY_MAJOR_VERSION >= 3
     28#define PyStr_FromFormat PyUnicode_FromFormat
     29#else
     30#define PyStr_FromFormat PyString_FromFormat
     31#endif
    2532
    2633/* print a talloc tree report for a talloc python object */
    27 static PyObject *py_talloc_report_full(PyObject *self, PyObject *args)
     34static PyObject *pytalloc_report_full(PyObject *self, PyObject *args)
    2835{
    2936        PyObject *py_obj = Py_None;
    30         PyTypeObject *type;
    3137
    3238        if (!PyArg_ParseTuple(args, "|O", &py_obj))
     
    3642                talloc_report_full(NULL, stdout);
    3743        } else {
    38                 type = (PyTypeObject*)PyObject_Type(py_obj);
    39                 talloc_report_full(py_talloc_get_mem_ctx(py_obj), stdout);
     44                talloc_report_full(pytalloc_get_mem_ctx(py_obj), stdout);
    4045        }
    4146        return Py_None;
     
    4348
    4449/* enable null tracking */
    45 static PyObject *py_talloc_enable_null_tracking(PyObject *self)
     50static PyObject *pytalloc_enable_null_tracking(PyObject *self)
    4651{
    4752        talloc_enable_null_tracking();
     
    5055
    5156/* return the number of talloc blocks */
    52 static PyObject *py_talloc_total_blocks(PyObject *self, PyObject *args)
     57static PyObject *pytalloc_total_blocks(PyObject *self, PyObject *args)
    5358{
    5459        PyObject *py_obj = Py_None;
    55         PyTypeObject *type;
    5660
    5761        if (!PyArg_ParseTuple(args, "|O", &py_obj))
     
    6266        }
    6367
    64         type = (PyTypeObject*)PyObject_Type(py_obj);
    65 
    66         return PyLong_FromLong(talloc_total_blocks(py_talloc_get_mem_ctx(py_obj)));
     68        return PyLong_FromLong(talloc_total_blocks(pytalloc_get_mem_ctx(py_obj)));
    6769}
    6870
    6971static PyMethodDef talloc_methods[] = {
    70         { "report_full", (PyCFunction)py_talloc_report_full, METH_VARARGS,
     72        { "report_full", (PyCFunction)pytalloc_report_full, METH_VARARGS,
    7173                "show a talloc tree for an object"},
    72         { "enable_null_tracking", (PyCFunction)py_talloc_enable_null_tracking, METH_NOARGS,
     74        { "enable_null_tracking", (PyCFunction)pytalloc_enable_null_tracking, METH_NOARGS,
    7375                "enable tracking of the NULL object"},
    74         { "total_blocks", (PyCFunction)py_talloc_total_blocks, METH_VARARGS,
     76        { "total_blocks", (PyCFunction)pytalloc_total_blocks, METH_VARARGS,
    7577                "return talloc block count"},
    7678        { NULL }
     
    8082 * Default (but only slightly more useful than the default) implementation of Repr().
    8183 */
    82 static PyObject *py_talloc_default_repr(PyObject *obj)
    83 {
    84         py_talloc_Object *talloc_obj = (py_talloc_Object *)obj;
     84static PyObject *pytalloc_default_repr(PyObject *obj)
     85{
     86        pytalloc_Object *talloc_obj = (pytalloc_Object *)obj;
    8587        PyTypeObject *type = (PyTypeObject*)PyObject_Type(obj);
    8688
    87         return PyString_FromFormat("<%s talloc object at 0x%p>",
    88                                    type->tp_name, talloc_obj->ptr);
     89        return PyStr_FromFormat("<%s talloc object at 0x%p>",
     90                                type->tp_name, talloc_obj->ptr);
    8991}
    9092
     
    9294 * Simple dealloc for talloc-wrapping PyObjects
    9395 */
    94 static void py_talloc_dealloc(PyObject* self)
    95 {
    96         py_talloc_Object *obj = (py_talloc_Object *)self;
     96static void pytalloc_dealloc(PyObject* self)
     97{
     98        pytalloc_Object *obj = (pytalloc_Object *)self;
    9799        assert(talloc_unlink(NULL, obj->talloc_ctx) != -1);
    98100        obj->talloc_ctx = NULL;
     
    103105 * Default (but only slightly more useful than the default) implementation of cmp.
    104106 */
    105 static int py_talloc_default_cmp(PyObject *_obj1, PyObject *_obj2)
    106 {
    107         py_talloc_Object *obj1 = (py_talloc_Object *)_obj1,
    108                                          *obj2 = (py_talloc_Object *)_obj2;
     107#if PY_MAJOR_VERSION >= 3
     108static PyObject *pytalloc_default_richcmp(PyObject *obj1, PyObject *obj2, int op)
     109{
     110        void *ptr1;
     111        void *ptr2;
     112        if (Py_TYPE(obj1) == Py_TYPE(obj2)) {
     113                /* When types match, compare pointers */
     114                ptr1 = pytalloc_get_ptr(obj1);
     115                ptr2 = pytalloc_get_ptr(obj2);
     116        } else if (PyObject_TypeCheck(obj2, &TallocObject_Type)) {
     117                /* Otherwise, compare types */
     118                ptr1 = Py_TYPE(obj1);
     119                ptr2 = Py_TYPE(obj2);
     120        } else {
     121                Py_INCREF(Py_NotImplemented);
     122                return Py_NotImplemented;
     123        }
     124        switch (op) {
     125                case Py_EQ: return PyBool_FromLong(ptr1 == ptr2);
     126                case Py_NE: return PyBool_FromLong(ptr1 != ptr2);
     127                case Py_LT: return PyBool_FromLong(ptr1 < ptr2);
     128                case Py_GT: return PyBool_FromLong(ptr1 > ptr2);
     129                case Py_LE: return PyBool_FromLong(ptr1 <= ptr2);
     130                case Py_GE: return PyBool_FromLong(ptr1 >= ptr2);
     131        }
     132        Py_INCREF(Py_NotImplemented);
     133        return Py_NotImplemented;
     134}
     135#else
     136static int pytalloc_default_cmp(PyObject *_obj1, PyObject *_obj2)
     137{
     138        pytalloc_Object *obj1 = (pytalloc_Object *)_obj1,
     139                                         *obj2 = (pytalloc_Object *)_obj2;
    109140        if (obj1->ob_type != obj2->ob_type)
    110                 return (obj1->ob_type - obj2->ob_type);
    111 
    112         return ((char *)py_talloc_get_ptr(obj1) - (char *)py_talloc_get_ptr(obj2));
    113 }
     141                return ((char *)obj1->ob_type - (char *)obj2->ob_type);
     142
     143        return ((char *)pytalloc_get_ptr(obj1) - (char *)pytalloc_get_ptr(obj2));
     144}
     145#endif
    114146
    115147static PyTypeObject TallocObject_Type = {
    116148        .tp_name = "talloc.Object",
    117149        .tp_doc = "Python wrapper for a talloc-maintained object.",
    118         .tp_basicsize = sizeof(py_talloc_Object),
    119         .tp_dealloc = (destructor)py_talloc_dealloc,
     150        .tp_basicsize = sizeof(pytalloc_Object),
     151        .tp_dealloc = (destructor)pytalloc_dealloc,
    120152        .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
    121         .tp_repr = py_talloc_default_repr,
    122         .tp_compare = py_talloc_default_cmp,
    123 };
    124 
    125 void inittalloc(void)
     153        .tp_repr = pytalloc_default_repr,
     154#if PY_MAJOR_VERSION >= 3
     155        .tp_richcompare = pytalloc_default_richcmp,
     156#else
     157        .tp_compare = pytalloc_default_cmp,
     158#endif
     159};
     160
     161/**
     162 * Default (but only slightly more useful than the default) implementation of Repr().
     163 */
     164static PyObject *pytalloc_base_default_repr(PyObject *obj)
     165{
     166        pytalloc_BaseObject *talloc_obj = (pytalloc_BaseObject *)obj;
     167        PyTypeObject *type = (PyTypeObject*)PyObject_Type(obj);
     168
     169        return PyStr_FromFormat("<%s talloc based object at 0x%p>",
     170                                type->tp_name, talloc_obj->ptr);
     171}
     172
     173/**
     174 * Simple dealloc for talloc-wrapping PyObjects
     175 */
     176static void pytalloc_base_dealloc(PyObject* self)
     177{
     178        pytalloc_BaseObject *obj = (pytalloc_BaseObject *)self;
     179        assert(talloc_unlink(NULL, obj->talloc_ctx) != -1);
     180        obj->talloc_ctx = NULL;
     181        self->ob_type->tp_free(self);
     182}
     183
     184/**
     185 * Default (but only slightly more useful than the default) implementation of cmp.
     186 */
     187#if PY_MAJOR_VERSION >= 3
     188static PyObject *pytalloc_base_default_richcmp(PyObject *obj1, PyObject *obj2, int op)
     189{
     190        void *ptr1;
     191        void *ptr2;
     192        if (Py_TYPE(obj1) == Py_TYPE(obj2)) {
     193                /* When types match, compare pointers */
     194                ptr1 = pytalloc_get_ptr(obj1);
     195                ptr2 = pytalloc_get_ptr(obj2);
     196        } else if (PyObject_TypeCheck(obj2, &TallocObject_Type)) {
     197                /* Otherwise, compare types */
     198                ptr1 = Py_TYPE(obj1);
     199                ptr2 = Py_TYPE(obj2);
     200        } else {
     201                Py_INCREF(Py_NotImplemented);
     202                return Py_NotImplemented;
     203        }
     204        switch (op) {
     205                case Py_EQ: return PyBool_FromLong(ptr1 == ptr2);
     206                case Py_NE: return PyBool_FromLong(ptr1 != ptr2);
     207                case Py_LT: return PyBool_FromLong(ptr1 < ptr2);
     208                case Py_GT: return PyBool_FromLong(ptr1 > ptr2);
     209                case Py_LE: return PyBool_FromLong(ptr1 <= ptr2);
     210                case Py_GE: return PyBool_FromLong(ptr1 >= ptr2);
     211        }
     212        Py_INCREF(Py_NotImplemented);
     213        return Py_NotImplemented;
     214}
     215#else
     216static int pytalloc_base_default_cmp(PyObject *_obj1, PyObject *_obj2)
     217{
     218        pytalloc_BaseObject *obj1 = (pytalloc_BaseObject *)_obj1,
     219                                         *obj2 = (pytalloc_BaseObject *)_obj2;
     220        if (obj1->ob_type != obj2->ob_type)
     221                return ((char *)obj1->ob_type - (char *)obj2->ob_type);
     222
     223        return ((char *)pytalloc_get_ptr(obj1) - (char *)pytalloc_get_ptr(obj2));
     224}
     225#endif
     226
     227static PyTypeObject TallocBaseObject_Type = {
     228        .tp_name = "talloc.BaseObject",
     229        .tp_doc = "Python wrapper for a talloc-maintained object.",
     230        .tp_basicsize = sizeof(pytalloc_BaseObject),
     231        .tp_dealloc = (destructor)pytalloc_base_dealloc,
     232        .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     233        .tp_repr = pytalloc_base_default_repr,
     234#if PY_MAJOR_VERSION >= 3
     235        .tp_richcompare = pytalloc_base_default_richcmp,
     236#else
     237        .tp_compare = pytalloc_base_default_cmp,
     238#endif
     239};
     240
     241#define MODULE_DOC PyDoc_STR("Python wrapping of talloc-maintained objects.")
     242
     243#if PY_MAJOR_VERSION >= 3
     244static struct PyModuleDef moduledef = {
     245    PyModuleDef_HEAD_INIT,
     246    .m_name = "talloc",
     247    .m_doc = MODULE_DOC,
     248    .m_size = -1,
     249    .m_methods = talloc_methods,
     250};
     251#endif
     252
     253static PyObject *module_init(void);
     254static PyObject *module_init(void)
    126255{
    127256        PyObject *m;
    128257
    129258        if (PyType_Ready(&TallocObject_Type) < 0)
    130                 return;
    131 
    132         m = Py_InitModule3("talloc", talloc_methods,
    133                                            "Python wrapping of talloc-maintained objects.");
     259                return NULL;
     260
     261        if (PyType_Ready(&TallocBaseObject_Type) < 0)
     262                return NULL;
     263
     264#if PY_MAJOR_VERSION >= 3
     265        m = PyModule_Create(&moduledef);
     266#else
     267        m = Py_InitModule3("talloc", talloc_methods, MODULE_DOC);
     268#endif
    134269        if (m == NULL)
    135                 return;
     270                return NULL;
    136271
    137272        Py_INCREF(&TallocObject_Type);
    138273        PyModule_AddObject(m, "Object", (PyObject *)&TallocObject_Type);
    139 }
     274        Py_INCREF(&TallocBaseObject_Type);
     275        PyModule_AddObject(m, "BaseObject", (PyObject *)&TallocBaseObject_Type);
     276        return m;
     277}
     278
     279#if PY_MAJOR_VERSION >= 3
     280PyMODINIT_FUNC PyInit_talloc(void);
     281PyMODINIT_FUNC PyInit_talloc(void)
     282{
     283        return module_init();
     284}
     285#else
     286void inittalloc(void);
     287void inittalloc(void)
     288{
     289        module_init();
     290}
     291#endif
  • vendor/current/lib/talloc/pytalloc.h

    r740 r988  
    1818*/
    1919
    20 #ifndef _PY_TALLOC_H_
    21 #define _PY_TALLOC_H_
     20#ifndef _PYTALLOC_H_
     21#define _PYTALLOC_H_
    2222
    2323#include <Python.h>
     
    2727        PyObject_HEAD
    2828        TALLOC_CTX *talloc_ctx;
    29         void *ptr;
    30 } py_talloc_Object;
     29        void *ptr; /* eg the array element */
     30} pytalloc_Object;
    3131
    32 PyTypeObject *PyTalloc_GetObjectType(void);
    33 int PyTalloc_Check(PyObject *);
     32/* Return the PyTypeObject for pytalloc_Object. Returns a new reference. */
     33PyTypeObject *pytalloc_GetObjectType(void);
    3434
    35 /* Retrieve the pointer for a py_talloc_object. Like talloc_get_type()
    36  * but for py_talloc_Objects. */
     35/* Return the PyTypeObject for pytalloc_BaseObject. Returns a new reference. */
     36PyTypeObject *pytalloc_GetBaseObjectType(void);
    3737
    38 /* FIXME: Call PyErr_SetString(PyExc_TypeError, "expected " __STR(type) ")
    39  * when talloc_get_type() returns NULL. */
    40 #define py_talloc_get_type(py_obj, type) (talloc_get_type(py_talloc_get_ptr(py_obj), type))
     38/* Check whether a specific object is a talloc Object. */
     39int pytalloc_Check(PyObject *);
    4140
    42 #define py_talloc_get_ptr(py_obj) (((py_talloc_Object *)py_obj)->ptr)
    43 #define py_talloc_get_mem_ctx(py_obj)  ((py_talloc_Object *)py_obj)->talloc_ctx
     41int pytalloc_BaseObject_check(PyObject *);
    4442
    45 PyObject *py_talloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr);
    46 PyObject *py_talloc_steal(PyTypeObject *py_type, void *ptr);
    47 PyObject *py_talloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr);
    48 #define py_talloc_reference(py_type, talloc_ptr) py_talloc_reference_ex(py_type, talloc_ptr, talloc_ptr)
     43/* Retrieve the pointer for a pytalloc_object. Like talloc_get_type()
     44 * but for pytalloc_Objects. */
     45void *_pytalloc_get_type(PyObject *py_obj, const char *type_name);
     46#define pytalloc_get_type(py_obj, type) ((type *)_pytalloc_get_type((PyObject *)(py_obj), #type))
    4947
    50 #define py_talloc_new(type, typeobj) py_talloc_steal(typeobj, talloc_zero(NULL, type))
     48void *_pytalloc_get_ptr(PyObject *py_obj);
     49#define pytalloc_get_ptr(py_obj) _pytalloc_get_ptr((PyObject *)(py_obj))
     50TALLOC_CTX *_pytalloc_get_mem_ctx(PyObject *py_obj);
     51#define pytalloc_get_mem_ctx(py_obj) _pytalloc_get_mem_ctx((PyObject *)(py_obj))
    5152
    52 PyObject *PyCObject_FromTallocPtr(void *);
     53PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr);
     54PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr);
     55PyObject *pytalloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr);
     56#define pytalloc_reference(py_type, talloc_ptr) pytalloc_reference_ex(py_type, talloc_ptr, talloc_ptr)
    5357
    54 PyObject *PyString_FromString_check_null(const char *ptr);
     58#define pytalloc_new(type, typeobj) pytalloc_steal(typeobj, talloc_zero(NULL, type))
    5559
    56 #endif /* _PY_TALLOC_H_ */
     60#if PY_MAJOR_VERSION < 3
     61PyObject *pytalloc_CObject_FromTallocPtr(void *);
     62#endif
     63
     64size_t pytalloc_BaseObject_size(void);
     65
     66int pytalloc_BaseObject_PyType_Ready(PyTypeObject *type);
     67
     68#endif /* _PYTALLOC_H_ */
  • vendor/current/lib/talloc/pytalloc_util.c

    r740 r988  
    2323#include "pytalloc.h"
    2424#include <assert.h>
    25 
    26 _PUBLIC_ PyTypeObject *PyTalloc_GetObjectType(void)
     25#include "pytalloc_private.h"
     26
     27_PUBLIC_ PyTypeObject *pytalloc_GetObjectType(void)
    2728{
    2829        static PyTypeObject *type = NULL;
     
    3940
    4041        type = (PyTypeObject *)PyObject_GetAttrString(mod, "Object");
     42        Py_DECREF(mod);
     43
     44        return type;
     45}
     46
     47_PUBLIC_ PyTypeObject *pytalloc_GetBaseObjectType(void)
     48{
     49        static PyTypeObject *type = NULL;
     50        PyObject *mod;
     51
     52        if (type != NULL) {
     53                return type;
     54        }
     55
     56        mod = PyImport_ImportModule("talloc");
     57        if (mod == NULL) {
     58                return NULL;
     59        }
     60
     61        type = (PyTypeObject *)PyObject_GetAttrString(mod, "BaseObject");
    4162        Py_DECREF(mod);
    4263
     
    4768 * Import an existing talloc pointer into a Python object.
    4869 */
    49 _PUBLIC_ PyObject *py_talloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx,
    50                                                    void *ptr)
    51 {
    52         py_talloc_Object *ret = (py_talloc_Object *)py_type->tp_alloc(py_type, 0);
    53         ret->talloc_ctx = talloc_new(NULL);
    54         if (ret->talloc_ctx == NULL) {
    55                 return NULL;
    56         }
    57         if (talloc_steal(ret->talloc_ctx, mem_ctx) == NULL) {
    58                 return NULL;
    59         }
    60         talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
    61         ret->ptr = ptr;
    62         return (PyObject *)ret;
     70_PUBLIC_ PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx,
     71                                     void *ptr)
     72{
     73        PyTypeObject *BaseObjectType = pytalloc_GetBaseObjectType();
     74        PyTypeObject *ObjectType = pytalloc_GetObjectType();
     75
     76        if (mem_ctx == NULL) {
     77                return PyErr_NoMemory();
     78        }
     79
     80        if (PyType_IsSubtype(py_type, BaseObjectType)) {
     81                pytalloc_BaseObject *ret
     82                        = (pytalloc_BaseObject *)py_type->tp_alloc(py_type, 0);
     83
     84                ret->talloc_ctx = talloc_new(NULL);
     85                if (ret->talloc_ctx == NULL) {
     86                        return NULL;
     87                }
     88
     89                /*
     90                 * This allows us to keep multiple references to this object -
     91                 * we only reference this context, which is per ptr, not the
     92                 * talloc_ctx, which is per pytalloc_Object
     93                 */
     94                if (talloc_steal(ret->talloc_ctx, mem_ctx) == NULL) {
     95                        return NULL;
     96                }
     97                ret->talloc_ptr_ctx = mem_ctx;
     98                talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
     99                ret->ptr = ptr;
     100                return (PyObject *)ret;
     101
     102        } else if (PyType_IsSubtype(py_type, ObjectType)) {
     103                pytalloc_Object *ret
     104                        = (pytalloc_Object *)py_type->tp_alloc(py_type, 0);
     105
     106                ret->talloc_ctx = talloc_new(NULL);
     107                if (ret->talloc_ctx == NULL) {
     108                        return NULL;
     109                }
     110
     111                if (talloc_steal(ret->talloc_ctx, mem_ctx) == NULL) {
     112                        return NULL;
     113                }
     114                talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
     115                ret->ptr = ptr;
     116                return (PyObject *)ret;
     117        } else {
     118                PyErr_SetString(PyExc_RuntimeError,
     119                                "pytalloc_steal_ex() called for object type "
     120                                "not based on talloc");
     121                return NULL;
     122        }
    63123}
    64124
     
    66126 * Import an existing talloc pointer into a Python object.
    67127 */
    68 _PUBLIC_ PyObject *py_talloc_steal(PyTypeObject *py_type, void *ptr)
    69 {
    70         return py_talloc_steal_ex(py_type, ptr, ptr);
     128_PUBLIC_ PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr)
     129{
     130        return pytalloc_steal_ex(py_type, ptr, ptr);
    71131}
    72132
     
    75135 * Import an existing talloc pointer into a Python object, leaving the
    76136 * original parent, and creating a reference to the object in the python
    77  * object
     137 * object.
     138 *
     139 * We remember the object we hold the reference to (a
     140 * possibly-non-talloc pointer), the existing parent (typically the
     141 * start of the array) and the new referenced parent.  That way we can
     142 * cope with the fact that we will have multiple parents, one per time
     143 * python sees the object.
    78144 */
    79 _PUBLIC_ PyObject *py_talloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr)
    80 {
    81         py_talloc_Object *ret;
    82 
     145_PUBLIC_ PyObject *pytalloc_reference_ex(PyTypeObject *py_type,
     146                                         TALLOC_CTX *mem_ctx, void *ptr)
     147{
     148        PyTypeObject *BaseObjectType = pytalloc_GetBaseObjectType();
     149        PyTypeObject *ObjectType = pytalloc_GetObjectType();
     150
     151        if (mem_ctx == NULL) {
     152                return PyErr_NoMemory();
     153        }
     154
     155        if (PyType_IsSubtype(py_type, BaseObjectType)) {
     156                pytalloc_BaseObject *ret
     157                        = (pytalloc_BaseObject *)py_type->tp_alloc(py_type, 0);
     158                ret->talloc_ctx = talloc_new(NULL);
     159                if (ret->talloc_ctx == NULL) {
     160                        return NULL;
     161                }
     162                if (talloc_reference(ret->talloc_ctx, mem_ctx) == NULL) {
     163                        return NULL;
     164                }
     165                talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
     166                ret->talloc_ptr_ctx = mem_ctx;
     167                ret->ptr = ptr;
     168                return (PyObject *)ret;
     169        } else if (PyType_IsSubtype(py_type, ObjectType)) {
     170                pytalloc_Object *ret
     171                        = (pytalloc_Object *)py_type->tp_alloc(py_type, 0);
     172                ret->talloc_ctx = talloc_new(NULL);
     173                if (ret->talloc_ctx == NULL) {
     174                        return NULL;
     175                }
     176                if (talloc_reference(ret->talloc_ctx, mem_ctx) == NULL) {
     177                        return NULL;
     178                }
     179                talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
     180                ret->ptr = ptr;
     181                return (PyObject *)ret;
     182        } else {
     183                PyErr_SetString(PyExc_RuntimeError,
     184                                "pytalloc_reference_ex() called for object type "
     185                                "not based on talloc");
     186                return NULL;
     187        }
     188}
     189
     190#if PY_MAJOR_VERSION < 3
     191
     192static void py_cobject_talloc_free(void *ptr)
     193{
     194        talloc_free(ptr);
     195}
     196
     197_PUBLIC_ PyObject *pytalloc_CObject_FromTallocPtr(void *ptr)
     198{
    83199        if (ptr == NULL) {
    84200                Py_RETURN_NONE;
    85201        }
    86 
    87         ret = (py_talloc_Object *)py_type->tp_alloc(py_type, 0);
    88         ret->talloc_ctx = talloc_new(NULL);
    89         if (ret->talloc_ctx == NULL) {
    90                 return NULL;
    91         }
    92         if (talloc_reference(ret->talloc_ctx, mem_ctx) == NULL) {
    93                 return NULL;
    94         }
    95         talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
    96         ret->ptr = ptr;
    97         return (PyObject *)ret;
    98 }
    99 
    100 static void py_cobject_talloc_free(void *ptr)
    101 {
    102         talloc_free(ptr);
    103 }
    104 
    105 _PUBLIC_ PyObject *PyCObject_FromTallocPtr(void *ptr)
    106 {
    107         if (ptr == NULL) {
    108                 Py_RETURN_NONE;
    109         }
    110202        return PyCObject_FromVoidPtr(ptr, py_cobject_talloc_free);
    111203}
    112204
    113 _PUBLIC_ int PyTalloc_Check(PyObject *obj)
    114 {
    115         PyTypeObject *tp = PyTalloc_GetObjectType();
     205#endif
     206
     207_PUBLIC_ int pytalloc_Check(PyObject *obj)
     208{
     209        PyTypeObject *tp = pytalloc_GetObjectType();
    116210
    117211        return PyObject_TypeCheck(obj, tp);
    118212}
     213
     214_PUBLIC_ int pytalloc_BaseObject_check(PyObject *obj)
     215{
     216        PyTypeObject *tp = pytalloc_GetBaseObjectType();
     217
     218        return PyObject_TypeCheck(obj, tp);
     219}
     220
     221_PUBLIC_ size_t pytalloc_BaseObject_size(void)
     222{
     223        return sizeof(pytalloc_BaseObject);
     224}
     225
     226_PUBLIC_ void *_pytalloc_get_type(PyObject *py_obj, const char *type_name)
     227{
     228        void *ptr = _pytalloc_get_ptr(py_obj);
     229        void *type_obj = talloc_check_name(ptr, type_name);
     230
     231        if (type_obj == NULL) {
     232                const char *name = talloc_get_name(ptr);
     233                PyErr_Format(PyExc_TypeError, "pytalloc: expected %s, got %s",
     234                             type_name, name);
     235                return NULL;
     236        }
     237
     238        return ptr;
     239}
     240
     241_PUBLIC_ void *_pytalloc_get_ptr(PyObject *py_obj)
     242{
     243        if (pytalloc_BaseObject_check(py_obj)) {
     244                return ((pytalloc_BaseObject *)py_obj)->ptr;
     245        }
     246        if (pytalloc_Check(py_obj)) {
     247                return ((pytalloc_Object *)py_obj)->ptr;
     248        }
     249        return NULL;
     250}
     251
     252_PUBLIC_ TALLOC_CTX *_pytalloc_get_mem_ctx(PyObject *py_obj)
     253{
     254        if (pytalloc_BaseObject_check(py_obj)) {
     255                return ((pytalloc_BaseObject *)py_obj)->talloc_ptr_ctx;
     256        }
     257        if (pytalloc_Check(py_obj)) {
     258                return ((pytalloc_Object *)py_obj)->talloc_ctx;
     259        }
     260        return NULL;
     261}
     262
     263_PUBLIC_ int pytalloc_BaseObject_PyType_Ready(PyTypeObject *type)
     264{
     265        PyTypeObject *talloc_type = pytalloc_GetBaseObjectType();
     266        if (talloc_type == NULL) {
     267                PyErr_Format(PyExc_TypeError, "pytalloc: unable to get talloc.BaseObject type");
     268                return -1;
     269        }
     270
     271        type->tp_base = talloc_type;
     272        type->tp_basicsize = pytalloc_BaseObject_size();
     273
     274        return PyType_Ready(type);
     275}
  • vendor/current/lib/talloc/talloc.c

    r746 r988  
    1 /* 
     1/*
    22   Samba Unix SMB/CIFS implementation.
    33
     
    88   Copyright (C) Andrew Tridgell 2004
    99   Copyright (C) Stefan Metzmacher 2006
    10    
     10
    1111     ** NOTE! The following LGPL license applies to the talloc
    1212     ** library. This does NOT imply that all of Samba is released
    1313     ** under the LGPL
    14    
     14
    1515   This library is free software; you can redistribute it and/or
    1616   modify it under the terms of the GNU Lesser General Public
     
    3333#include "replace.h"
    3434#include "talloc.h"
     35
     36#ifdef HAVE_SYS_AUXV_H
     37#include <sys/auxv.h>
     38#endif
    3539
    3640#ifdef TALLOC_BUILD_VERSION_MAJOR
     
    6165
    6266#define MAX_TALLOC_SIZE 0x10000000
    63 #define TALLOC_MAGIC_BASE 0xe814ec70
    64 #define TALLOC_MAGIC ( \
    65         TALLOC_MAGIC_BASE + \
    66         (TALLOC_VERSION_MAJOR << 12) + \
    67         (TALLOC_VERSION_MINOR << 4) \
    68 )
    6967
    7068#define TALLOC_FLAG_FREE 0x01
     
    7270#define TALLOC_FLAG_POOL 0x04           /* This is a talloc pool */
    7371#define TALLOC_FLAG_POOLMEM 0x08        /* This is allocated in a pool */
     72
     73/*
     74 * Bits above this are random, used to make it harder to fake talloc
     75 * headers during an attack.  Try not to change this without good reason.
     76 */
     77#define TALLOC_FLAG_MASK 0x0F
     78
    7479#define TALLOC_MAGIC_REFERENCE ((const char *)1)
    7580
    76 /* by default we abort when given a bad pointer (such as when talloc_free() is called
     81#define TALLOC_MAGIC_BASE 0xe814ec70
     82static unsigned int talloc_magic = (
     83        TALLOC_MAGIC_BASE +
     84        (TALLOC_VERSION_MAJOR << 12) +
     85        (TALLOC_VERSION_MINOR << 4));
     86
     87/* by default we abort when given a bad pointer (such as when talloc_free() is called
    7788   on a pointer that came from malloc() */
    7889#ifndef TALLOC_ABORT
     
    228239};
    229240
     241struct talloc_memlimit {
     242        struct talloc_chunk *parent;
     243        struct talloc_memlimit *upper;
     244        size_t max_size;
     245        size_t cur_size;
     246};
     247
     248static inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size);
     249static inline void talloc_memlimit_grow(struct talloc_memlimit *limit,
     250                                size_t size);
     251static inline void talloc_memlimit_shrink(struct talloc_memlimit *limit,
     252                                size_t size);
     253static inline void talloc_memlimit_update_on_free(struct talloc_chunk *tc);
     254
     255static inline void _talloc_set_name_const(const void *ptr, const char *name);
     256
    230257typedef int (*talloc_destructor_t)(void *);
    231258
     259struct talloc_pool_hdr;
     260
    232261struct talloc_chunk {
     262        unsigned flags;
    233263        struct talloc_chunk *next, *prev;
    234264        struct talloc_chunk *parent, *child;
     
    237267        const char *name;
    238268        size_t size;
    239         unsigned flags;
    240269
    241270        /*
    242          * "pool" has dual use:
    243          *
    244          * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool"
    245          * marks the end of the currently allocated area.
    246          *
    247          * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
     271         * limit semantics:
     272         * if 'limit' is set it means all *new* children of the context will
     273         * be limited to a total aggregate size ox max_size for memory
     274         * allocations.
     275         * cur_size is used to keep track of the current use
     276         */
     277        struct talloc_memlimit *limit;
     278
     279        /*
     280         * For members of a pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
    248281         * is a pointer to the struct talloc_chunk of the pool that it was
    249282         * allocated from. This way children can quickly find the pool to chew
    250283         * from.
    251284         */
    252         void *pool;
     285        struct talloc_pool_hdr *pool;
    253286};
    254287
     
    268301}
    269302
     303_PUBLIC_ int talloc_test_get_magic(void)
     304{
     305        return talloc_magic;
     306}
     307
    270308static void (*talloc_log_fn)(const char *message);
    271309
     
    274312        talloc_log_fn = log_fn;
    275313}
     314
     315#ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
     316void talloc_lib_init(void) __attribute__((constructor));
     317void talloc_lib_init(void)
     318{
     319        uint32_t random_value;
     320#if defined(HAVE_GETAUXVAL) && defined(AT_RANDOM)
     321        uint8_t *p;
     322        /*
     323         * Use the kernel-provided random values used for
     324         * ASLR.  This won't change per-exec, which is ideal for us
     325         */
     326        p = (uint8_t *) getauxval(AT_RANDOM);
     327        if (p) {
     328                /*
     329                 * We get 16 bytes from getauxval.  By calling rand(),
     330                 * a totally insecure PRNG, but one that will
     331                 * deterministically have a different value when called
     332                 * twice, we ensure that if two talloc-like libraries
     333                 * are somehow loaded in the same address space, that
     334                 * because we choose different bytes, we will keep the
     335                 * protection against collision of multiple talloc
     336                 * libs.
     337                 *
     338                 * This protection is important because the effects of
     339                 * passing a talloc pointer from one to the other may
     340                 * be very hard to determine.
     341                 */
     342                int offset = rand() % (16 - sizeof(random_value));
     343                memcpy(&random_value, p + offset, sizeof(random_value));
     344        } else
     345#endif
     346        {
     347                /*
     348                 * Otherwise, hope the location we are loaded in
     349                 * memory is randomised by someone else
     350                 */
     351                random_value = ((uintptr_t)talloc_lib_init & 0xFFFFFFFF);
     352        }
     353        talloc_magic = random_value & ~TALLOC_FLAG_MASK;
     354}
     355#else
     356#warning "No __attribute__((constructor)) support found on this platform, additional talloc security measures not available"
     357#endif
    276358
    277359static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
     
    323405static void talloc_abort_magic(unsigned magic)
    324406{
    325         unsigned striped = magic - TALLOC_MAGIC_BASE;
    326         unsigned major = (striped & 0xFFFFF000) >> 12;
    327         unsigned minor = (striped & 0x00000FF0) >> 4;
    328         talloc_log("Bad talloc magic[0x%08X/%u/%u] expected[0x%08X/%u/%u]\n",
    329                    magic, major, minor,
    330                    TALLOC_MAGIC, TALLOC_VERSION_MAJOR, TALLOC_VERSION_MINOR);
    331407        talloc_abort("Bad talloc magic value - wrong talloc version used/mixed");
    332408}
     
    347423        const char *pp = (const char *)ptr;
    348424        struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
    349         if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) {
    350                 if ((tc->flags & (~0xFFF)) == TALLOC_MAGIC_BASE) {
    351                         talloc_abort_magic(tc->flags & (~0xF));
     425        if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~TALLOC_FLAG_MASK)) != talloc_magic)) {
     426                if ((tc->flags & (~0xF)) == talloc_magic) {
     427                        talloc_abort_magic(tc->flags & (~TALLOC_FLAG_MASK));
    352428                        return NULL;
    353429                }
     
    438514*/
    439515
    440 #define TALLOC_POOL_HDR_SIZE 16
    441 
    442 #define TC_POOL_SPACE_LEFT(_pool_tc) \
    443         PTR_DIFF(TC_HDR_SIZE + (_pool_tc)->size + (char *)(_pool_tc), \
    444                  (_pool_tc)->pool)
    445 
    446 #define TC_POOL_FIRST_CHUNK(_pool_tc) \
    447         ((void *)(TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE + (char *)(_pool_tc)))
    448 
    449 #define TC_POOLMEM_CHUNK_SIZE(_tc) \
    450         TC_ALIGN16(TC_HDR_SIZE + (_tc)->size)
    451 
    452 #define TC_POOLMEM_NEXT_CHUNK(_tc) \
    453         ((void *)(TC_POOLMEM_CHUNK_SIZE(tc) + (char*)(_tc)))
     516struct talloc_pool_hdr {
     517        void *end;
     518        unsigned int object_count;
     519        size_t poolsize;
     520};
     521
     522#define TP_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_pool_hdr))
     523
     524static inline struct talloc_pool_hdr *talloc_pool_from_chunk(struct talloc_chunk *c)
     525{
     526        return (struct talloc_pool_hdr *)((char *)c - TP_HDR_SIZE);
     527}
     528
     529static inline struct talloc_chunk *talloc_chunk_from_pool(struct talloc_pool_hdr *h)
     530{
     531        return (struct talloc_chunk *)((char *)h + TP_HDR_SIZE);
     532}
     533
     534static inline void *tc_pool_end(struct talloc_pool_hdr *pool_hdr)
     535{
     536        struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr);
     537        return (char *)tc + TC_HDR_SIZE + pool_hdr->poolsize;
     538}
     539
     540static inline size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr)
     541{
     542        return (char *)tc_pool_end(pool_hdr) - (char *)pool_hdr->end;
     543}
     544
     545/* If tc is inside a pool, this gives the next neighbour. */
     546static inline void *tc_next_chunk(struct talloc_chunk *tc)
     547{
     548        return (char *)tc + TC_ALIGN16(TC_HDR_SIZE + tc->size);
     549}
     550
     551static inline void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr)
     552{
     553        struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr);
     554        return tc_next_chunk(tc);
     555}
    454556
    455557/* Mark the whole remaining pool as not accessable */
    456 #define TC_INVALIDATE_FILL_POOL(_pool_tc) do { \
    457         if (unlikely(talloc_fill.enabled)) { \
    458                 size_t _flen = TC_POOL_SPACE_LEFT(_pool_tc); \
    459                 char *_fptr = (char *)(_pool_tc)->pool; \
    460                 memset(_fptr, talloc_fill.fill_value, _flen); \
    461         } \
    462 } while(0)
     558static inline void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr)
     559{
     560        size_t flen = tc_pool_space_left(pool_hdr);
     561
     562        if (unlikely(talloc_fill.enabled)) {
     563                memset(pool_hdr->end, talloc_fill.fill_value, flen);
     564        }
    463565
    464566#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
    465 /* Mark the whole remaining pool as not accessable */
    466 #define TC_INVALIDATE_VALGRIND_POOL(_pool_tc) do { \
    467         size_t _flen = TC_POOL_SPACE_LEFT(_pool_tc); \
    468         char *_fptr = (char *)(_pool_tc)->pool; \
    469         VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \
    470 } while(0)
    471 #else
    472 #define TC_INVALIDATE_VALGRIND_POOL(_pool_tc) do { } while (0)
    473 #endif
    474 
    475 #define TC_INVALIDATE_POOL(_pool_tc) do { \
    476         TC_INVALIDATE_FILL_POOL(_pool_tc); \
    477         TC_INVALIDATE_VALGRIND_POOL(_pool_tc); \
    478 } while (0)
    479 
    480 static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc)
    481 {
    482         return (unsigned int *)((char *)tc + TC_HDR_SIZE);
     567        VALGRIND_MAKE_MEM_NOACCESS(pool_hdr->end, flen);
     568#endif
    483569}
    484570
     
    487573*/
    488574
    489 static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
    490                                               size_t size)
    491 {
    492         struct talloc_chunk *pool_ctx = NULL;
     575static inline struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
     576                                                     size_t size, size_t prefix_len)
     577{
     578        struct talloc_pool_hdr *pool_hdr = NULL;
    493579        size_t space_left;
    494580        struct talloc_chunk *result;
     
    500586
    501587        if (parent->flags & TALLOC_FLAG_POOL) {
    502                 pool_ctx = parent;
     588                pool_hdr = talloc_pool_from_chunk(parent);
    503589        }
    504590        else if (parent->flags & TALLOC_FLAG_POOLMEM) {
    505                 pool_ctx = (struct talloc_chunk *)parent->pool;
    506         }
    507 
    508         if (pool_ctx == NULL) {
     591                pool_hdr = parent->pool;
     592        }
     593
     594        if (pool_hdr == NULL) {
    509595                return NULL;
    510596        }
    511597
    512         space_left = TC_POOL_SPACE_LEFT(pool_ctx);
     598        space_left = tc_pool_space_left(pool_hdr);
    513599
    514600        /*
    515601         * Align size to 16 bytes
    516602         */
    517         chunk_size = TC_ALIGN16(size);
     603        chunk_size = TC_ALIGN16(size + prefix_len);
    518604
    519605        if (space_left < chunk_size) {
     
    521607        }
    522608
    523         result = (struct talloc_chunk *)pool_ctx->pool;
     609        result = (struct talloc_chunk *)((char *)pool_hdr->end + prefix_len);
    524610
    525611#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
    526         VALGRIND_MAKE_MEM_UNDEFINED(result, size);
    527 #endif
    528 
    529         pool_ctx->pool = (void *)((char *)result + chunk_size);
    530 
    531         result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
    532         result->pool = pool_ctx;
    533 
    534         *talloc_pool_objectcount(pool_ctx) += 1;
     612        VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, chunk_size);
     613#endif
     614
     615        pool_hdr->end = (void *)((char *)pool_hdr->end + chunk_size);
     616
     617        result->flags = talloc_magic | TALLOC_FLAG_POOLMEM;
     618        result->pool = pool_hdr;
     619
     620        pool_hdr->object_count++;
    535621
    536622        return result;
    537623}
    538624
    539 /* 
     625/*
    540626   Allocate a bit of memory as a child of an existing pointer
    541627*/
    542 static inline void *__talloc(const void *context, size_t size)
     628static inline void *__talloc_with_prefix(const void *context, size_t size,
     629                                        size_t prefix_len)
    543630{
    544631        struct talloc_chunk *tc = NULL;
     632        struct talloc_memlimit *limit = NULL;
     633        size_t total_len = TC_HDR_SIZE + size + prefix_len;
    545634
    546635        if (unlikely(context == NULL)) {
     
    552641        }
    553642
     643        if (unlikely(total_len < TC_HDR_SIZE)) {
     644                return NULL;
     645        }
     646
    554647        if (context != NULL) {
    555                 tc = talloc_alloc_pool(talloc_chunk_from_ptr(context),
    556                                        TC_HDR_SIZE+size);
     648                struct talloc_chunk *ptc = talloc_chunk_from_ptr(context);
     649
     650                if (ptc->limit != NULL) {
     651                        limit = ptc->limit;
     652                }
     653
     654                tc = talloc_alloc_pool(ptc, TC_HDR_SIZE+size, prefix_len);
    557655        }
    558656
    559657        if (tc == NULL) {
    560                 tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
    561                 if (unlikely(tc == NULL)) return NULL;
    562                 tc->flags = TALLOC_MAGIC;
     658                char *ptr;
     659
     660                /*
     661                 * Only do the memlimit check/update on actual allocation.
     662                 */
     663                if (!talloc_memlimit_check(limit, total_len)) {
     664                        errno = ENOMEM;
     665                        return NULL;
     666                }
     667
     668                ptr = malloc(total_len);
     669                if (unlikely(ptr == NULL)) {
     670                        return NULL;
     671                }
     672                tc = (struct talloc_chunk *)(ptr + prefix_len);
     673                tc->flags = talloc_magic;
    563674                tc->pool  = NULL;
    564         }
    565 
     675
     676                talloc_memlimit_grow(limit, total_len);
     677        }
     678
     679        tc->limit = limit;
    566680        tc->size = size;
    567681        tc->destructor = NULL;
     
    590704}
    591705
     706static inline void *__talloc(const void *context, size_t size)
     707{
     708        return __talloc_with_prefix(context, size, 0);
     709}
     710
    592711/*
    593712 * Create a talloc pool
    594713 */
    595714
    596 _PUBLIC_ void *talloc_pool(const void *context, size_t size)
    597 {
    598         void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE);
     715static inline void *_talloc_pool(const void *context, size_t size)
     716{
    599717        struct talloc_chunk *tc;
     718        struct talloc_pool_hdr *pool_hdr;
     719        void *result;
     720
     721        result = __talloc_with_prefix(context, size, TP_HDR_SIZE);
    600722
    601723        if (unlikely(result == NULL)) {
     
    604726
    605727        tc = talloc_chunk_from_ptr(result);
     728        pool_hdr = talloc_pool_from_chunk(tc);
    606729
    607730        tc->flags |= TALLOC_FLAG_POOL;
    608         tc->pool = TC_POOL_FIRST_CHUNK(tc);
    609 
    610         *talloc_pool_objectcount(tc) = 1;
    611 
    612         TC_INVALIDATE_POOL(tc);
     731        tc->size = 0;
     732
     733        pool_hdr->object_count = 1;
     734        pool_hdr->end = result;
     735        pool_hdr->poolsize = size;
     736
     737        tc_invalidate_pool(pool_hdr);
    613738
    614739        return result;
     740}
     741
     742_PUBLIC_ void *talloc_pool(const void *context, size_t size)
     743{
     744        return _talloc_pool(context, size);
     745}
     746
     747/*
     748 * Create a talloc pool correctly sized for a basic size plus
     749 * a number of subobjects whose total size is given. Essentially
     750 * a custom allocator for talloc to reduce fragmentation.
     751 */
     752
     753_PUBLIC_ void *_talloc_pooled_object(const void *ctx,
     754                                     size_t type_size,
     755                                     const char *type_name,
     756                                     unsigned num_subobjects,
     757                                     size_t total_subobjects_size)
     758{
     759        size_t poolsize, subobjects_slack, tmp;
     760        struct talloc_chunk *tc;
     761        struct talloc_pool_hdr *pool_hdr;
     762        void *ret;
     763
     764        poolsize = type_size + total_subobjects_size;
     765
     766        if ((poolsize < type_size) || (poolsize < total_subobjects_size)) {
     767                goto overflow;
     768        }
     769
     770        if (num_subobjects == UINT_MAX) {
     771                goto overflow;
     772        }
     773        num_subobjects += 1;       /* the object body itself */
     774
     775        /*
     776         * Alignment can increase the pool size by at most 15 bytes per object
     777         * plus alignment for the object itself
     778         */
     779        subobjects_slack = (TC_HDR_SIZE + TP_HDR_SIZE + 15) * num_subobjects;
     780        if (subobjects_slack < num_subobjects) {
     781                goto overflow;
     782        }
     783
     784        tmp = poolsize + subobjects_slack;
     785        if ((tmp < poolsize) || (tmp < subobjects_slack)) {
     786                goto overflow;
     787        }
     788        poolsize = tmp;
     789
     790        ret = _talloc_pool(ctx, poolsize);
     791        if (ret == NULL) {
     792                return NULL;
     793        }
     794
     795        tc = talloc_chunk_from_ptr(ret);
     796        tc->size = type_size;
     797
     798        pool_hdr = talloc_pool_from_chunk(tc);
     799
     800#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
     801        VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, type_size);
     802#endif
     803
     804        pool_hdr->end = ((char *)pool_hdr->end + TC_ALIGN16(type_size));
     805
     806        _talloc_set_name_const(ret, type_name);
     807        return ret;
     808
     809overflow:
     810        return NULL;
    615811}
    616812
     
    628824
    629825/*
    630   increase the reference count on a piece of memory. 
     826  increase the reference count on a piece of memory.
    631827*/
    632828_PUBLIC_ int talloc_increase_ref_count(const void *ptr)
     
    651847
    652848/*
    653    more efficient way to add a name to a pointer - the name must point to a 
     849   more efficient way to add a name to a pointer - the name must point to a
    654850   true string constant
    655851*/
     
    681877  the pointer remains valid until both the original caller and this given
    682878  context are freed.
    683  
    684   the major use for this is when two different structures need to reference the 
     879
     880  the major use for this is when two different structures need to reference the
    685881  same underlying data, and you want to be able to free the two instances separately,
    686882  and in either order
     
    713909                                        const char *location)
    714910{
    715         struct talloc_chunk *pool;
     911        struct talloc_pool_hdr *pool;
     912        struct talloc_chunk *pool_tc;
    716913        void *next_tc;
    717         unsigned int *pool_object_count;
    718 
    719         pool = (struct talloc_chunk *)tc->pool;
    720         next_tc = TC_POOLMEM_NEXT_CHUNK(tc);
     914
     915        pool = tc->pool;
     916        pool_tc = talloc_chunk_from_pool(pool);
     917        next_tc = tc_next_chunk(tc);
    721918
    722919        tc->flags |= TALLOC_FLAG_FREE;
     
    730927        TC_INVALIDATE_FULL_CHUNK(tc);
    731928
    732         pool_object_count = talloc_pool_objectcount(pool);
    733 
    734         if (unlikely(*pool_object_count == 0)) {
     929        if (unlikely(pool->object_count == 0)) {
    735930                talloc_abort("Pool object count zero!");
    736931                return;
    737932        }
    738933
    739         *pool_object_count -= 1;
    740 
    741         if (unlikely(*pool_object_count == 1 && !(pool->flags & TALLOC_FLAG_FREE))) {
     934        pool->object_count--;
     935
     936        if (unlikely(pool->object_count == 1
     937                     && !(pool_tc->flags & TALLOC_FLAG_FREE))) {
    742938                /*
    743939                 * if there is just one object left in the pool
     
    747943                 * again.
    748944                 */
    749                 pool->pool = TC_POOL_FIRST_CHUNK(pool);
    750                 TC_INVALIDATE_POOL(pool);
    751         } else if (unlikely(*pool_object_count == 0)) {
     945                pool->end = tc_pool_first_chunk(pool);
     946                tc_invalidate_pool(pool);
     947                return;
     948        }
     949
     950        if (unlikely(pool->object_count == 0)) {
    752951                /*
    753952                 * we mark the freed memory with where we called the free
     
    755954                 * the first free came from
    756955                 */
    757                 pool->name = location;
    758 
    759                 TC_INVALIDATE_FULL_CHUNK(pool);
    760                 free(pool);
    761         } else if (pool->pool == next_tc) {
     956                pool_tc->name = location;
     957
     958                if (pool_tc->flags & TALLOC_FLAG_POOLMEM) {
     959                        _talloc_free_poolmem(pool_tc, location);
     960                } else {
     961                        /*
     962                         * The talloc_memlimit_update_on_free()
     963                         * call takes into account the
     964                         * prefix TP_HDR_SIZE allocated before
     965                         * the pool talloc_chunk.
     966                         */
     967                        talloc_memlimit_update_on_free(pool_tc);
     968                        TC_INVALIDATE_FULL_CHUNK(pool_tc);
     969                        free(pool);
     970                }
     971                return;
     972        }
     973
     974        if (pool->end == next_tc) {
    762975                /*
    763976                 * if pool->pool still points to end of
     
    765978                 * we can reclaim the memory of 'tc'.
    766979                 */
    767                 pool->pool = tc;
    768         }
     980                pool->end = tc;
     981                return;
     982        }
     983
     984        /*
     985         * Do nothing. The memory is just "wasted", waiting for the pool
     986         * itself to be freed.
     987         */
    769988}
    770989
     
    773992                                                  const char *location);
    774993
    775 /* 
     994/*
    776995   internal talloc_free call
    777996*/
     
    779998{
    780999        struct talloc_chunk *tc;
     1000        void *ptr_to_free;
    7811001
    7821002        if (unlikely(ptr == NULL)) {
     
    8251045                tc->destructor = (talloc_destructor_t)-1;
    8261046                if (d(ptr) == -1) {
    827                         tc->destructor = d;
     1047                        /*
     1048                         * Only replace the destructor pointer if
     1049                         * calling the destructor didn't modify it.
     1050                         */
     1051                        if (tc->destructor == (talloc_destructor_t)-1) {
     1052                                tc->destructor = d;
     1053                        }
    8281054                        return -1;
    8291055                }
     
    8501076        /* we mark the freed memory with where we called the free
    8511077         * from. This means on a double free error we can report where
    852          * the first free came from 
    853          */     
     1078         * the first free came from
     1079         */
    8541080        tc->name = location;
    8551081
    8561082        if (tc->flags & TALLOC_FLAG_POOL) {
    857                 unsigned int *pool_object_count;
    858 
    859                 pool_object_count = talloc_pool_objectcount(tc);
    860 
    861                 if (unlikely(*pool_object_count == 0)) {
     1083                struct talloc_pool_hdr *pool;
     1084
     1085                pool = talloc_pool_from_chunk(tc);
     1086
     1087                if (unlikely(pool->object_count == 0)) {
    8621088                        talloc_abort("Pool object count zero!");
    8631089                        return 0;
    8641090                }
    8651091
    866                 *pool_object_count -= 1;
    867 
    868                 if (unlikely(*pool_object_count == 0)) {
    869                         TC_INVALIDATE_FULL_CHUNK(tc);
    870                         free(tc);
    871                 }
    872         } else if (tc->flags & TALLOC_FLAG_POOLMEM) {
     1092                pool->object_count--;
     1093
     1094                if (likely(pool->object_count != 0)) {
     1095                        return 0;
     1096                }
     1097
     1098                /*
     1099                 * With object_count==0, a pool becomes a normal piece of
     1100                 * memory to free. If it's allocated inside a pool, it needs
     1101                 * to be freed as poolmem, else it needs to be just freed.
     1102                */
     1103                ptr_to_free = pool;
     1104        } else {
     1105                ptr_to_free = tc;
     1106        }
     1107
     1108        if (tc->flags & TALLOC_FLAG_POOLMEM) {
    8731109                _talloc_free_poolmem(tc, location);
    874         } else {
    875                 TC_INVALIDATE_FULL_CHUNK(tc);
    876                 free(tc);
    877         }
     1110                return 0;
     1111        }
     1112
     1113        talloc_memlimit_update_on_free(tc);
     1114
     1115        TC_INVALIDATE_FULL_CHUNK(tc);
     1116        free(ptr_to_free);
    8781117        return 0;
    8791118}
    8801119
    881 /*
     1120static inline size_t _talloc_total_limit_size(const void *ptr,
     1121                                        struct talloc_memlimit *old_limit,
     1122                                        struct talloc_memlimit *new_limit);
     1123
     1124/*
    8821125   move a lump of memory from one talloc context to another return the
    8831126   ptr on success, or NULL if it could not be transferred.
     
    8871130{
    8881131        struct talloc_chunk *tc, *new_tc;
     1132        size_t ctx_size = 0;
    8891133
    8901134        if (unlikely(!ptr)) {
     
    8971141
    8981142        tc = talloc_chunk_from_ptr(ptr);
     1143
     1144        if (tc->limit != NULL) {
     1145
     1146                ctx_size = _talloc_total_limit_size(ptr, NULL, NULL);
     1147
     1148                /* Decrement the memory limit from the source .. */
     1149                talloc_memlimit_shrink(tc->limit->upper, ctx_size);
     1150
     1151                if (tc->limit->parent == tc) {
     1152                        tc->limit->upper = NULL;
     1153                } else {
     1154                        tc->limit = NULL;
     1155                }
     1156        }
    8991157
    9001158        if (unlikely(new_ctx == NULL)) {
     
    9081166                        if (tc->next) tc->next->prev = tc->prev;
    9091167                }
    910                
     1168
    9111169                tc->parent = tc->next = tc->prev = NULL;
    9121170                return discard_const_p(void, ptr);
     
    9341192        _TLIST_ADD(new_tc->child, tc);
    9351193
     1194        if (tc->limit || new_tc->limit) {
     1195                ctx_size = _talloc_total_limit_size(ptr, tc->limit,
     1196                                                    new_tc->limit);
     1197                /* .. and increment it in the destination. */
     1198                if (new_tc->limit) {
     1199                        talloc_memlimit_grow(new_tc->limit, ctx_size);
     1200                }
     1201        }
     1202
    9361203        return discard_const_p(void, ptr);
    9371204}
    9381205
    939 /* 
     1206/*
    9401207   move a lump of memory from one talloc context to another return the
    9411208   ptr on success, or NULL if it could not be transferred.
     
    9491216                return NULL;
    9501217        }
    951        
     1218
    9521219        tc = talloc_chunk_from_ptr(ptr);
    953        
     1220
    9541221        if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) {
    9551222                struct talloc_reference_handle *h;
     
    9711238        }
    9721239#endif
    973        
     1240
    9741241        return _talloc_steal_internal(new_ctx, ptr);
    9751242}
    9761243
    977 /* 
     1244/*
    9781245   this is like a talloc_steal(), but you must supply the old
    9791246   parent. This resolves the ambiguity in a talloc_steal() which is
     
    10031270                        return discard_const_p(void, ptr);
    10041271                }
    1005         }       
     1272        }
    10061273
    10071274        /* it wasn't a parent */
     
    10401307/*
    10411308  remove a specific parent context from a pointer. This is a more
    1042   controlled varient of talloc_free()
     1309  controlled variant of talloc_free()
    10431310*/
    10441311_PUBLIC_ int talloc_unlink(const void *context, void *ptr)
    10451312{
    1046         struct talloc_chunk *tc_p, *new_p;
     1313        struct talloc_chunk *tc_p, *new_p, *tc_c;
    10471314        void *new_parent;
    10481315
     
    10591326        }
    10601327
    1061         if (context == NULL) {
    1062                 if (talloc_parent_chunk(ptr) != NULL) {
    1063                         return -1;
    1064                 }
     1328        if (context != NULL) {
     1329                tc_c = talloc_chunk_from_ptr(context);
    10651330        } else {
    1066                 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
    1067                         return -1;
    1068                 }
    1069         }
    1070        
     1331                tc_c = NULL;
     1332        }
     1333        if (tc_c != talloc_parent_chunk(ptr)) {
     1334                return -1;
     1335        }
     1336
    10711337        tc_p = talloc_chunk_from_ptr(ptr);
    10721338
     
    11491415  return the name of a talloc ptr, or "UNNAMED"
    11501416*/
    1151 _PUBLIC_ const char *talloc_get_name(const void *ptr)
     1417static inline const char *__talloc_get_name(const void *ptr)
    11521418{
    11531419        struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
     
    11611427}
    11621428
     1429_PUBLIC_ const char *talloc_get_name(const void *ptr)
     1430{
     1431        return __talloc_get_name(ptr);
     1432}
    11631433
    11641434/*
     
    11701440        const char *pname;
    11711441        if (unlikely(ptr == NULL)) return NULL;
    1172         pname = talloc_get_name(ptr);
     1442        pname = __talloc_get_name(ptr);
    11731443        if (likely(pname == name || strcmp(pname, name) == 0)) {
    11741444                return discard_const_p(void, ptr);
     
    11771447}
    11781448
    1179 static void talloc_abort_type_missmatch(const char *location,
     1449static void talloc_abort_type_mismatch(const char *location,
    11801450                                        const char *name,
    11811451                                        const char *expected)
     
    12001470
    12011471        if (unlikely(ptr == NULL)) {
    1202                 talloc_abort_type_missmatch(location, NULL, name);
     1472                talloc_abort_type_mismatch(location, NULL, name);
    12031473                return NULL;
    12041474        }
    12051475
    1206         pname = talloc_get_name(ptr);
     1476        pname = __talloc_get_name(ptr);
    12071477        if (likely(pname == name || strcmp(pname, name) == 0)) {
    12081478                return discard_const_p(void, ptr);
    12091479        }
    12101480
    1211         talloc_abort_type_missmatch(location, pname, name);
     1481        talloc_abort_type_mismatch(location, pname, name);
    12121482        return NULL;
    12131483}
     
    12491519                void *child = TC_PTR_FROM_CHUNK(tc->child);
    12501520                const void *new_parent = null_context;
    1251                 struct talloc_chunk *old_parent = NULL;
    12521521                if (unlikely(tc->child->refs)) {
    12531522                        struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
     
    12551524                }
    12561525                if (unlikely(_talloc_free_internal(child, location) == -1)) {
     1526                        if (talloc_parent_chunk(child) != tc) {
     1527                                /*
     1528                                 * Destructor already reparented this child.
     1529                                 * No further reparenting needed.
     1530                                 */
     1531                                return;
     1532                        }
    12571533                        if (new_parent == null_context) {
    12581534                                struct talloc_chunk *p = talloc_parent_chunk(ptr);
     
    13051581}
    13061582
    1307 /* 
     1583/*
    13081584   Allocate a bit of memory as a child of an existing pointer
    13091585*/
     
    13311607}
    13321608
    1333 /* 
    1334    free a talloc pointer. This also frees all child pointers of this 
     1609/*
     1610   free a talloc pointer. This also frees all child pointers of this
    13351611   pointer recursively
    13361612
     
    13461622                return -1;
    13471623        }
    1348        
     1624
    13491625        tc = talloc_chunk_from_ptr(ptr);
    1350        
     1626
    13511627        if (unlikely(tc->refs != NULL)) {
    13521628                struct talloc_reference_handle *h;
     
    13681644                return -1;
    13691645        }
    1370        
     1646
    13711647        return _talloc_free_internal(ptr, location);
    13721648}
     
    13831659        void *new_ptr;
    13841660        bool malloced = false;
    1385         struct talloc_chunk *pool_tc = NULL;
     1661        struct talloc_pool_hdr *pool_hdr = NULL;
     1662        size_t old_size = 0;
     1663        size_t new_size = 0;
    13861664
    13871665        /* size zero is equivalent to free() */
     
    14121690        }
    14131691
    1414         /* don't let anybody try to realloc a talloc_pool */
     1692        if (tc->limit && (size > tc->size)) {
     1693                if (!talloc_memlimit_check(tc->limit, (size - tc->size))) {
     1694                        errno = ENOMEM;
     1695                        return NULL;
     1696                }
     1697        }
     1698
     1699        /* handle realloc inside a talloc_pool */
    14151700        if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) {
    1416                 pool_tc = (struct talloc_chunk *)tc->pool;
     1701                pool_hdr = tc->pool;
    14171702        }
    14181703
    14191704#if (ALWAYS_REALLOC == 0)
    14201705        /* don't shrink if we have less than 1k to gain */
    1421         if (size < tc->size) {
    1422                 if (pool_tc) {
    1423                         void *next_tc = TC_POOLMEM_NEXT_CHUNK(tc);
     1706        if (size < tc->size && tc->limit == NULL) {
     1707                if (pool_hdr) {
     1708                        void *next_tc = tc_next_chunk(tc);
    14241709                        TC_INVALIDATE_SHRINK_CHUNK(tc, size);
    14251710                        tc->size = size;
    1426                         if (next_tc == pool_tc->pool) {
    1427                                 pool_tc->pool = TC_POOLMEM_NEXT_CHUNK(tc);
     1711                        if (next_tc == pool_hdr->end) {
     1712                                /* note: tc->size has changed, so this works */
     1713                                pool_hdr->end = tc_next_chunk(tc);
    14281714                        }
    14291715                        return ptr;
     
    14561742
    14571743#if ALWAYS_REALLOC
    1458         if (pool_tc) {
    1459                 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
    1460                 *talloc_pool_objectcount(pool_tc) -= 1;
     1744        if (pool_hdr) {
     1745                new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0);
     1746                pool_hdr->object_count--;
    14611747
    14621748                if (new_ptr == NULL) {
    14631749                        new_ptr = malloc(TC_HDR_SIZE+size);
    14641750                        malloced = true;
     1751                        new_size = size;
    14651752                }
    14661753
     
    14701757                }
    14711758        } else {
     1759                /* We're doing malloc then free here, so record the difference. */
     1760                old_size = tc->size;
     1761                new_size = size;
    14721762                new_ptr = malloc(size + TC_HDR_SIZE);
    14731763                if (new_ptr) {
     
    14771767        }
    14781768#else
    1479         if (pool_tc) {
    1480                 void *next_tc = TC_POOLMEM_NEXT_CHUNK(tc);
    1481                 size_t old_chunk_size = TC_POOLMEM_CHUNK_SIZE(tc);
     1769        if (pool_hdr) {
     1770                struct talloc_chunk *pool_tc;
     1771                void *next_tc = tc_next_chunk(tc);
     1772                size_t old_chunk_size = TC_ALIGN16(TC_HDR_SIZE + tc->size);
    14821773                size_t new_chunk_size = TC_ALIGN16(TC_HDR_SIZE + size);
    14831774                size_t space_needed;
    14841775                size_t space_left;
    1485                 unsigned int chunk_count = *talloc_pool_objectcount(pool_tc);
    1486 
     1776                unsigned int chunk_count = pool_hdr->object_count;
     1777
     1778                pool_tc = talloc_chunk_from_pool(pool_hdr);
    14871779                if (!(pool_tc->flags & TALLOC_FLAG_FREE)) {
    14881780                        chunk_count -= 1;
     
    14941786                         * chunk in the pool.
    14951787                         */
     1788                        char *start = tc_pool_first_chunk(pool_hdr);
    14961789                        space_needed = new_chunk_size;
    1497                         space_left = pool_tc->size - TALLOC_POOL_HDR_SIZE;
     1790                        space_left = (char *)tc_pool_end(pool_hdr) - start;
    14981791
    14991792                        if (space_left >= space_needed) {
    15001793                                size_t old_used = TC_HDR_SIZE + tc->size;
    15011794                                size_t new_used = TC_HDR_SIZE + size;
    1502                                 pool_tc->pool = TC_POOL_FIRST_CHUNK(pool_tc);
     1795                                new_ptr = start;
     1796
    15031797#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
    1504                                 /*
    1505                                  * we need to prepare the memmove into
    1506                                  * the unaccessable area.
    1507                                  */
    15081798                                {
    1509                                         size_t diff = PTR_DIFF(tc, pool_tc->pool);
    1510                                         size_t flen = MIN(diff, old_used);
    1511                                         char *fptr = (char *)pool_tc->pool;
    1512                                         VALGRIND_MAKE_MEM_UNDEFINED(fptr, flen);
     1799                                        /*
     1800                                         * The area from
     1801                                         * start -> tc may have
     1802                                         * been freed and thus been marked as
     1803                                         * VALGRIND_MEM_NOACCESS. Set it to
     1804                                         * VALGRIND_MEM_UNDEFINED so we can
     1805                                         * copy into it without valgrind errors.
     1806                                         * We can't just mark
     1807                                         * new_ptr -> new_ptr + old_used
     1808                                         * as this may overlap on top of tc,
     1809                                         * (which is why we use memmove, not
     1810                                         * memcpy below) hence the MIN.
     1811                                         */
     1812                                        size_t undef_len = MIN((((char *)tc) - ((char *)new_ptr)),old_used);
     1813                                        VALGRIND_MAKE_MEM_UNDEFINED(new_ptr, undef_len);
    15131814                                }
    15141815#endif
    1515                                 memmove(pool_tc->pool, tc, old_used);
    1516                                 new_ptr = pool_tc->pool;
     1816
     1817                                memmove(new_ptr, tc, old_used);
    15171818
    15181819                                tc = (struct talloc_chunk *)new_ptr;
     
    15241825                                 * too.
    15251826                                 */
    1526                                 pool_tc->pool = new_used + (char *)new_ptr;
    1527                                 TC_INVALIDATE_POOL(pool_tc);
     1827                                pool_hdr->end = new_used + (char *)new_ptr;
     1828                                tc_invalidate_pool(pool_hdr);
    15281829
    15291830                                /* now the aligned pointer */
    1530                                 pool_tc->pool = new_chunk_size + (char *)new_ptr;
     1831                                pool_hdr->end = new_chunk_size + (char *)new_ptr;
    15311832                                goto got_new_ptr;
    15321833                        }
     
    15421843                }
    15431844
    1544                 if (next_tc == pool_tc->pool) {
     1845                if (next_tc == pool_hdr->end) {
    15451846                        /*
    15461847                         * optimize for the case where 'tc' is the last
     
    15481849                         */
    15491850                        space_needed = new_chunk_size - old_chunk_size;
    1550                         space_left = TC_POOL_SPACE_LEFT(pool_tc);
     1851                        space_left = tc_pool_space_left(pool_hdr);
    15511852
    15521853                        if (space_left >= space_needed) {
     
    15541855                                tc->flags &= ~TALLOC_FLAG_FREE;
    15551856                                tc->size = size;
    1556                                 pool_tc->pool = TC_POOLMEM_NEXT_CHUNK(tc);
     1857                                pool_hdr->end = tc_next_chunk(tc);
    15571858                                return ptr;
    15581859                        }
    15591860                }
    15601861
    1561                 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
     1862                new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0);
    15621863
    15631864                if (new_ptr == NULL) {
    15641865                        new_ptr = malloc(TC_HDR_SIZE+size);
    15651866                        malloced = true;
     1867                        new_size = size;
    15661868                }
    15671869
     
    15731875        }
    15741876        else {
     1877                /* We're doing realloc here, so record the difference. */
     1878                old_size = tc->size;
     1879                new_size = size;
    15751880                new_ptr = realloc(tc, size + TC_HDR_SIZE);
    15761881        }
    15771882got_new_ptr:
    15781883#endif
    1579         if (unlikely(!new_ptr)) {       
    1580                 tc->flags &= ~TALLOC_FLAG_FREE; 
    1581                 return NULL; 
     1884        if (unlikely(!new_ptr)) {
     1885                tc->flags &= ~TALLOC_FLAG_FREE;
     1886                return NULL;
    15821887        }
    15831888
     
    16011906        }
    16021907
     1908        if (new_size > old_size) {
     1909                talloc_memlimit_grow(tc->limit, new_size - old_size);
     1910        } else if (new_size < old_size) {
     1911                talloc_memlimit_shrink(tc->limit, old_size - new_size);
     1912        }
     1913
    16031914        tc->size = size;
    16041915        _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
     
    16191930}
    16201931
    1621 /*
    1622   return the total size of a talloc pool (subtree)
    1623 */
    1624 _PUBLIC_ size_t talloc_total_size(const void *ptr)
     1932enum talloc_mem_count_type {
     1933        TOTAL_MEM_SIZE,
     1934        TOTAL_MEM_BLOCKS,
     1935        TOTAL_MEM_LIMIT,
     1936};
     1937
     1938static inline size_t _talloc_total_mem_internal(const void *ptr,
     1939                                         enum talloc_mem_count_type type,
     1940                                         struct talloc_memlimit *old_limit,
     1941                                         struct talloc_memlimit *new_limit)
    16251942{
    16261943        size_t total = 0;
     
    16361953        tc = talloc_chunk_from_ptr(ptr);
    16371954
     1955        if (old_limit || new_limit) {
     1956                if (tc->limit && tc->limit->upper == old_limit) {
     1957                        tc->limit->upper = new_limit;
     1958                }
     1959        }
     1960
     1961        /* optimize in the memlimits case */
     1962        if (type == TOTAL_MEM_LIMIT &&
     1963            tc->limit != NULL &&
     1964            tc->limit != old_limit &&
     1965            tc->limit->parent == tc) {
     1966                return tc->limit->cur_size;
     1967        }
     1968
    16381969        if (tc->flags & TALLOC_FLAG_LOOP) {
    16391970                return 0;
     
    16421973        tc->flags |= TALLOC_FLAG_LOOP;
    16431974
    1644         if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
    1645                 total = tc->size;
    1646         }
    1647         for (c=tc->child;c;c=c->next) {
    1648                 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
     1975        if (old_limit || new_limit) {
     1976                if (old_limit == tc->limit) {
     1977                        tc->limit = new_limit;
     1978                }
     1979        }
     1980
     1981        switch (type) {
     1982        case TOTAL_MEM_SIZE:
     1983                if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
     1984                        total = tc->size;
     1985                }
     1986                break;
     1987        case TOTAL_MEM_BLOCKS:
     1988                total++;
     1989                break;
     1990        case TOTAL_MEM_LIMIT:
     1991                if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
     1992                        /*
     1993                         * Don't count memory allocated from a pool
     1994                         * when calculating limits. Only count the
     1995                         * pool itself.
     1996                         */
     1997                        if (!(tc->flags & TALLOC_FLAG_POOLMEM)) {
     1998                                if (tc->flags & TALLOC_FLAG_POOL) {
     1999                                        /*
     2000                                         * If this is a pool, the allocated
     2001                                         * size is in the pool header, and
     2002                                         * remember to add in the prefix
     2003                                         * length.
     2004                                         */
     2005                                        struct talloc_pool_hdr *pool_hdr
     2006                                                        = talloc_pool_from_chunk(tc);
     2007                                        total = pool_hdr->poolsize +
     2008                                                        TC_HDR_SIZE +
     2009                                                        TP_HDR_SIZE;
     2010                                } else {
     2011                                        total = tc->size + TC_HDR_SIZE;
     2012                                }
     2013                        }
     2014                }
     2015                break;
     2016        }
     2017        for (c = tc->child; c; c = c->next) {
     2018                total += _talloc_total_mem_internal(TC_PTR_FROM_CHUNK(c), type,
     2019                                                    old_limit, new_limit);
    16492020        }
    16502021
     
    16552026
    16562027/*
     2028  return the total size of a talloc pool (subtree)
     2029*/
     2030_PUBLIC_ size_t talloc_total_size(const void *ptr)
     2031{
     2032        return _talloc_total_mem_internal(ptr, TOTAL_MEM_SIZE, NULL, NULL);
     2033}
     2034
     2035/*
    16572036  return the total number of blocks in a talloc pool (subtree)
    16582037*/
    16592038_PUBLIC_ size_t talloc_total_blocks(const void *ptr)
    16602039{
    1661         size_t total = 0;
    1662         struct talloc_chunk *c, *tc;
    1663 
    1664         if (ptr == NULL) {
    1665                 ptr = null_context;
    1666         }
    1667         if (ptr == NULL) {
    1668                 return 0;
    1669         }
    1670 
    1671         tc = talloc_chunk_from_ptr(ptr);
    1672 
    1673         if (tc->flags & TALLOC_FLAG_LOOP) {
    1674                 return 0;
    1675         }
    1676 
    1677         tc->flags |= TALLOC_FLAG_LOOP;
    1678 
    1679         total++;
    1680         for (c=tc->child;c;c=c->next) {
    1681                 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
    1682         }
    1683 
    1684         tc->flags &= ~TALLOC_FLAG_LOOP;
    1685 
    1686         return total;
     2040        return _talloc_total_mem_internal(ptr, TOTAL_MEM_BLOCKS, NULL, NULL);
    16872041}
    16882042
     
    17452099static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
    17462100{
    1747         const char *name = talloc_get_name(ptr);
     2101        const char *name = __talloc_get_name(ptr);
     2102        struct talloc_chunk *tc;
    17482103        FILE *f = (FILE *)_f;
    17492104
     
    17532108        }
    17542109
     2110        tc = talloc_chunk_from_ptr(ptr);
     2111        if (tc->limit && tc->limit->parent == tc) {
     2112                fprintf(f, "%*s%-30s is a memlimit context"
     2113                        " (max_size = %lu bytes, cur_size = %lu bytes)\n",
     2114                        depth*4, "",
     2115                        name,
     2116                        (unsigned long)tc->limit->max_size,
     2117                        (unsigned long)tc->limit->cur_size);
     2118        }
     2119
    17552120        if (depth == 0) {
    1756                 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", 
     2121                fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
    17572122                        (max_depth < 0 ? "full " :""), name,
    17582123                        (unsigned long)talloc_total_size(ptr),
     
    17612126        }
    17622127
    1763         fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n", 
     2128        fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
    17642129                depth*4, "",
    17652130                name,
     
    19002265}
    19012266
    1902 /* 
    1903    talloc and zero memory. 
     2267/*
     2268   talloc and zero memory.
    19042269*/
    19052270_PUBLIC_ void *_talloc_zero(const void *ctx, size_t size, const char *name)
     
    19152280
    19162281/*
    1917   memdup with a talloc. 
     2282  memdup with a talloc.
    19182283*/
    19192284_PUBLIC_ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
     
    20222387{
    20232388        if (unlikely(!s)) {
    2024                 return talloc_strdup(NULL, a);
     2389                return talloc_strndup(NULL, a, n);
    20252390        }
    20262391
     
    20412406
    20422407        if (unlikely(!s)) {
    2043                 return talloc_strdup(NULL, a);
     2408                return talloc_strndup(NULL, a, n);
    20442409        }
    20452410
     
    20692434        char *ret;
    20702435        va_list ap2;
    2071         char c;
     2436        char buf[1024];
    20722437
    20732438        /* this call looks strange, but it makes it work on older solaris boxes */
    20742439        va_copy(ap2, ap);
    2075         len = vsnprintf(&c, 1, fmt, ap2);
     2440        len = vsnprintf(buf, sizeof(buf), fmt, ap2);
    20762441        va_end(ap2);
    20772442        if (unlikely(len < 0)) {
     
    20822447        if (unlikely(!ret)) return NULL;
    20832448
    2084         va_copy(ap2, ap);
    2085         vsnprintf(ret, len+1, fmt, ap2);
    2086         va_end(ap2);
     2449        if (len < sizeof(buf)) {
     2450                memcpy(ret, buf, len+1);
     2451        } else {
     2452                va_copy(ap2, ap);
     2453                vsnprintf(ret, len+1, fmt, ap2);
     2454                va_end(ap2);
     2455        }
    20872456
    20882457        _talloc_set_name_const(ret, ret);
     
    23302699
    23312700        tc = talloc_chunk_from_ptr(context);
    2332         fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
     2701        fprintf(file, "talloc parents of '%s'\n", __talloc_get_name(context));
    23332702        while (tc) {
    2334                 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
     2703                fprintf(file, "\t'%s'\n", __talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
    23352704                while (tc && tc->prev) tc = tc->prev;
    23362705                if (tc) {
     
    23532722
    23542723        tc = talloc_chunk_from_ptr(context);
    2355         while (tc && depth > 0) {
     2724        while (tc) {
     2725                if (depth <= 0) {
     2726                        return 0;
     2727                }
    23562728                if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
    23572729                while (tc && tc->prev) tc = tc->prev;
     
    23712743        return _talloc_is_parent(context, ptr, TALLOC_MAX_DEPTH);
    23722744}
     2745
     2746/*
     2747  return the total size of memory used by this context and all children
     2748*/
     2749static inline size_t _talloc_total_limit_size(const void *ptr,
     2750                                        struct talloc_memlimit *old_limit,
     2751                                        struct talloc_memlimit *new_limit)
     2752{
     2753        return _talloc_total_mem_internal(ptr, TOTAL_MEM_LIMIT,
     2754                                          old_limit, new_limit);
     2755}
     2756
     2757static inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size)
     2758{
     2759        struct talloc_memlimit *l;
     2760
     2761        for (l = limit; l != NULL; l = l->upper) {
     2762                if (l->max_size != 0 &&
     2763                    ((l->max_size <= l->cur_size) ||
     2764                     (l->max_size - l->cur_size < size))) {
     2765                        return false;
     2766                }
     2767        }
     2768
     2769        return true;
     2770}
     2771
     2772/*
     2773  Update memory limits when freeing a talloc_chunk.
     2774*/
     2775static void talloc_memlimit_update_on_free(struct talloc_chunk *tc)
     2776{
     2777        size_t limit_shrink_size;
     2778
     2779        if (!tc->limit) {
     2780                return;
     2781        }
     2782
     2783        /*
     2784         * Pool entries don't count. Only the pools
     2785         * themselves are counted as part of the memory
     2786         * limits. Note that this also takes care of
     2787         * nested pools which have both flags
     2788         * TALLOC_FLAG_POOLMEM|TALLOC_FLAG_POOL set.
     2789         */
     2790        if (tc->flags & TALLOC_FLAG_POOLMEM) {
     2791                return;
     2792        }
     2793
     2794        /*
     2795         * If we are part of a memory limited context hierarchy
     2796         * we need to subtract the memory used from the counters
     2797         */
     2798
     2799        limit_shrink_size = tc->size+TC_HDR_SIZE;
     2800
     2801        /*
     2802         * If we're deallocating a pool, take into
     2803         * account the prefix size added for the pool.
     2804         */
     2805
     2806        if (tc->flags & TALLOC_FLAG_POOL) {
     2807                limit_shrink_size += TP_HDR_SIZE;
     2808        }
     2809
     2810        talloc_memlimit_shrink(tc->limit, limit_shrink_size);
     2811
     2812        if (tc->limit->parent == tc) {
     2813                free(tc->limit);
     2814        }
     2815
     2816        tc->limit = NULL;
     2817}
     2818
     2819/*
     2820  Increase memory limit accounting after a malloc/realloc.
     2821*/
     2822static void talloc_memlimit_grow(struct talloc_memlimit *limit,
     2823                                size_t size)
     2824{
     2825        struct talloc_memlimit *l;
     2826
     2827        for (l = limit; l != NULL; l = l->upper) {
     2828                size_t new_cur_size = l->cur_size + size;
     2829                if (new_cur_size < l->cur_size) {
     2830                        talloc_abort("logic error in talloc_memlimit_grow\n");
     2831                        return;
     2832                }
     2833                l->cur_size = new_cur_size;
     2834        }
     2835}
     2836
     2837/*
     2838  Decrease memory limit accounting after a free/realloc.
     2839*/
     2840static void talloc_memlimit_shrink(struct talloc_memlimit *limit,
     2841                                size_t size)
     2842{
     2843        struct talloc_memlimit *l;
     2844
     2845        for (l = limit; l != NULL; l = l->upper) {
     2846                if (l->cur_size < size) {
     2847                        talloc_abort("logic error in talloc_memlimit_shrink\n");
     2848                        return;
     2849                }
     2850                l->cur_size = l->cur_size - size;
     2851        }
     2852}
     2853
     2854_PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size)
     2855{
     2856        struct talloc_chunk *tc = talloc_chunk_from_ptr(ctx);
     2857        struct talloc_memlimit *orig_limit;
     2858        struct talloc_memlimit *limit = NULL;
     2859
     2860        if (tc->limit && tc->limit->parent == tc) {
     2861                tc->limit->max_size = max_size;
     2862                return 0;
     2863        }
     2864        orig_limit = tc->limit;
     2865
     2866        limit = malloc(sizeof(struct talloc_memlimit));
     2867        if (limit == NULL) {
     2868                return 1;
     2869        }
     2870        limit->parent = tc;
     2871        limit->max_size = max_size;
     2872        limit->cur_size = _talloc_total_limit_size(ctx, tc->limit, limit);
     2873
     2874        if (orig_limit) {
     2875                limit->upper = orig_limit;
     2876        } else {
     2877                limit->upper = NULL;
     2878        }
     2879
     2880        return 0;
     2881}
  • vendor/current/lib/talloc/talloc.h

    r746 r988  
    11#ifndef _TALLOC_H_
    22#define _TALLOC_H_
    3 /* 
     3/*
    44   Unix SMB/CIFS implementation.
    55   Samba temporary memory allocation functions
     
    77   Copyright (C) Andrew Tridgell 2004-2005
    88   Copyright (C) Stefan Metzmacher 2006
    9    
     9
    1010     ** NOTE! The following LGPL license applies to the talloc
    1111     ** library. This does NOT imply that all of Samba is released
    1212     ** under the LGPL
    13    
     13
    1414   This library is free software; you can redistribute it and/or
    1515   modify it under the terms of the GNU Lesser General Public
     
    4848int talloc_version_major(void);
    4949int talloc_version_minor(void);
     50/* This is mostly useful only for testing */
     51int talloc_test_get_magic(void);
    5052
    5153/**
     
    194196 * talloc_set_log_stderr() for more information on talloc logging
    195197 * functions.
     198 *
     199 * If <code>TALLOC_FREE_FILL</code> environment variable is set,
     200 * the memory occupied by the context is filled with the value of this variable.
     201 * The value should be a numeric representation of the character you want to
     202 * use.
    196203 *
    197204 * talloc_free() operates recursively on its children.
     
    745752 *
    746753 * This macro is used together with talloc(mem_ctx, struct foo). If you had to
    747  * assing the talloc chunk pointer to some void pointer variable,
     754 * assign the talloc chunk pointer to some void pointer variable,
    748755 * talloc_get_type_abort() is the recommended way to get the convert the void
    749756 * pointer back to a typed pointer.
     
    757764void *talloc_get_type_abort(const void *ptr, #type);
    758765#else
     766#ifdef TALLOC_GET_TYPE_ABORT_NOOP
     767#define talloc_get_type_abort(ptr, type) (type *)(ptr)
     768#else
    759769#define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__)
     770#endif
    760771void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location);
    761772#endif
     
    823834 * grand-children, their memory is also taken from the talloc pool.
    824835 *
     836 * If there is not enough memory in the pool to allocate the new child,
     837 * it will create a new talloc chunk as if the parent was a normal talloc
     838 * context.
     839 *
    825840 * If you talloc_free() children of a talloc pool, the memory is not given
    826841 * back to the system. Instead, free(3) is only called if the talloc_pool()
     
    839854void *talloc_pool(const void *context, size_t size);
    840855
     856#ifdef DOXYGEN
     857/**
     858 * @brief Allocate a talloc object as/with an additional pool.
     859 *
     860 * This is like talloc_pool(), but's it's more flexible
     861 * and allows an object to be a pool for its children.
     862 *
     863 * @param[in] ctx                   The talloc context to hang the result off.
     864 *
     865 * @param[in] type                  The type that we want to allocate.
     866 *
     867 * @param[in] num_subobjects        The expected number of subobjects, which will
     868 *                                  be allocated within the pool. This allocates
     869 *                                  space for talloc_chunk headers.
     870 *
     871 * @param[in] total_subobjects_size The size that all subobjects can use in total.
     872 *
     873 *
     874 * @return              The allocated talloc object, NULL on error.
     875 */
     876void *talloc_pooled_object(const void *ctx, #type,
     877                           unsigned num_subobjects,
     878                           size_t total_subobjects_size);
     879#else
     880#define talloc_pooled_object(_ctx, _type, \
     881                             _num_subobjects, \
     882                             _total_subobjects_size) \
     883        (_type *)_talloc_pooled_object((_ctx), sizeof(_type), #_type, \
     884                                        (_num_subobjects), \
     885                                        (_total_subobjects_size))
     886void *_talloc_pooled_object(const void *ctx,
     887                            size_t type_size,
     888                            const char *type_name,
     889                            unsigned num_subobjects,
     890                            size_t total_subobjects_size);
     891#endif
     892
    841893/**
    842894 * @brief Free a talloc chunk and NULL out the pointer.
     
    848900 * @param[in]  ctx      The chunk to be freed.
    849901 */
    850 #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0)
     902#define TALLOC_FREE(ctx) do { if (ctx != NULL) { talloc_free(ctx); ctx=NULL; } } while(0)
    851903
    852904/* @} ******************************************************************/
     
    915967 * @return              The original pointer 'ptr', NULL if talloc ran out of
    916968 *                      memory in creating the reference.
     969 *
     970 * @warning You should try to avoid using this interface. It turns a beautiful
     971 *          talloc-tree into a graph. It is often really hard to debug if you
     972 *          screw something up by accident.
    917973 *
    918974 * Example:
     
    9551011 * this function will fail and will return -1.  Likewise, if ptr is NULL,
    9561012 * then the function will make no modifications and return -1.
     1013 *
     1014 * @warning You should try to avoid using this interface. It turns a beautiful
     1015 *          talloc-tree into a graph. It is often really hard to debug if you
     1016 *          screw something up by accident.
    9571017 *
    9581018 * Example:
     
    12911351
    12921352/**
    1293  * @brief Append a string to given string and duplicate the result.
     1353 * @brief Append a string to given string.
     1354 *
     1355 * The destination string is reallocated to take
     1356 * <code>strlen(s) + strlen(a) + 1</code> characters.
     1357 *
     1358 * This functions sets the name of the new pointer to the new
     1359 * string. This is equivalent to:
     1360 *
     1361 * @code
     1362 *      talloc_set_name_const(ptr, ptr)
     1363 * @endcode
     1364 *
     1365 * If <code>s == NULL</code> then new context is created.
    12941366 *
    12951367 * @param[in]  s        The destination to append to.
     
    12971369 * @param[in]  a        The string you want to append.
    12981370 *
    1299  * @return              The duplicated string, NULL on error.
     1371 * @return              The concatenated strings, NULL on error.
    13001372 *
    13011373 * @see talloc_strdup()
     1374 * @see talloc_strdup_append_buffer()
    13021375 */
    13031376char *talloc_strdup_append(char *s, const char *a);
    13041377
    13051378/**
    1306  * @brief Append a string to a given buffer and duplicate the result.
     1379 * @brief Append a string to a given buffer.
     1380 *
     1381 * This is a more efficient version of talloc_strdup_append(). It determines the
     1382 * length of the destination string by the size of the talloc context.
     1383 *
     1384 * Use this very carefully as it produces a different result than
     1385 * talloc_strdup_append() when a zero character is in the middle of the
     1386 * destination string.
     1387 *
     1388 * @code
     1389 *      char *str_a = talloc_strdup(NULL, "hello world");
     1390 *      char *str_b = talloc_strdup(NULL, "hello world");
     1391 *      str_a[5] = str_b[5] = '\0'
     1392 *
     1393 *      char *app = talloc_strdup_append(str_a, ", hello");
     1394 *      char *buf = talloc_strdup_append_buffer(str_b, ", hello");
     1395 *
     1396 *      printf("%s\n", app); // hello, hello (app = "hello, hello")
     1397 *      printf("%s\n", buf); // hello (buf = "hello\0world, hello")
     1398 * @endcode
     1399 *
     1400 * If <code>s == NULL</code> then new context is created.
    13071401 *
    13081402 * @param[in]  s        The destination buffer to append to.
     
    13101404 * @param[in]  a        The string you want to append.
    13111405 *
    1312  * @return              The duplicated string, NULL on error.
     1406 * @return              The concatenated strings, NULL on error.
    13131407 *
    13141408 * @see talloc_strdup()
     1409 * @see talloc_strdup_append()
     1410 * @see talloc_array_length()
    13151411 */
    13161412char *talloc_strdup_append_buffer(char *s, const char *a);
     
    13391435
    13401436/**
    1341  * @brief Append at most n characters of a string to given string and duplicate
    1342  *        the result.
     1437 * @brief Append at most n characters of a string to given string.
     1438 *
     1439 * The destination string is reallocated to take
     1440 * <code>strlen(s) + strnlen(a, n) + 1</code> characters.
     1441 *
     1442 * This functions sets the name of the new pointer to the new
     1443 * string. This is equivalent to:
     1444 *
     1445 * @code
     1446 *      talloc_set_name_const(ptr, ptr)
     1447 * @endcode
     1448 *
     1449 * If <code>s == NULL</code> then new context is created.
    13431450 *
    13441451 * @param[in]  s        The destination string to append to.
     
    13491456 *                      string.
    13501457 *
    1351  * @return              The duplicated string, NULL on error.
     1458 * @return              The concatenated strings, NULL on error.
    13521459 *
    13531460 * @see talloc_strndup()
     1461 * @see talloc_strndup_append_buffer()
    13541462 */
    13551463char *talloc_strndup_append(char *s, const char *a, size_t n);
    13561464
    13571465/**
    1358  * @brief Append at most n characters of a string to given buffer and duplicate
    1359  *        the result.
     1466 * @brief Append at most n characters of a string to given buffer
     1467 *
     1468 * This is a more efficient version of talloc_strndup_append(). It determines
     1469 * the length of the destination string by the size of the talloc context.
     1470 *
     1471 * Use this very carefully as it produces a different result than
     1472 * talloc_strndup_append() when a zero character is in the middle of the
     1473 * destination string.
     1474 *
     1475 * @code
     1476 *      char *str_a = talloc_strdup(NULL, "hello world");
     1477 *      char *str_b = talloc_strdup(NULL, "hello world");
     1478 *      str_a[5] = str_b[5] = '\0'
     1479 *
     1480 *      char *app = talloc_strndup_append(str_a, ", hello", 7);
     1481 *      char *buf = talloc_strndup_append_buffer(str_b, ", hello", 7);
     1482 *
     1483 *      printf("%s\n", app); // hello, hello (app = "hello, hello")
     1484 *      printf("%s\n", buf); // hello (buf = "hello\0world, hello")
     1485 * @endcode
     1486 *
     1487 * If <code>s == NULL</code> then new context is created.
    13601488 *
    13611489 * @param[in]  s        The destination buffer to append to.
     
    13661494 *                      string.
    13671495 *
    1368  * @return              The duplicated string, NULL on error.
     1496 * @return              The concatenated strings, NULL on error.
    13691497 *
    13701498 * @see talloc_strndup()
     1499 * @see talloc_strndup_append()
     1500 * @see talloc_array_length()
    13711501 */
    13721502char *talloc_strndup_append_buffer(char *s, const char *a, size_t n);
     
    14631593 * @endcode
    14641594 *
     1595 * If <code>s == NULL</code> then new context is created.
     1596 *
    14651597 * @param[in]  s        The string to append to.
    14661598 *
     
    14761608 * @brief Append a formatted string to another string.
    14771609 *
     1610 * This is a more efficient version of talloc_asprintf_append(). It determines
     1611 * the length of the destination string by the size of the talloc context.
     1612 *
     1613 * Use this very carefully as it produces a different result than
     1614 * talloc_asprintf_append() when a zero character is in the middle of the
     1615 * destination string.
     1616 *
     1617 * @code
     1618 *      char *str_a = talloc_strdup(NULL, "hello world");
     1619 *      char *str_b = talloc_strdup(NULL, "hello world");
     1620 *      str_a[5] = str_b[5] = '\0'
     1621 *
     1622 *      char *app = talloc_asprintf_append(str_a, "%s", ", hello");
     1623 *      char *buf = talloc_strdup_append_buffer(str_b, "%s", ", hello");
     1624 *
     1625 *      printf("%s\n", app); // hello, hello (app = "hello, hello")
     1626 *      printf("%s\n", buf); // hello (buf = "hello\0world, hello")
     1627 * @endcode
     1628 *
     1629 * If <code>s == NULL</code> then new context is created.
     1630 *
    14781631 * @param[in]  s        The string to append to
    14791632 *
     
    14831636 *
    14841637 * @return              The formatted string, NULL on error.
     1638 *
     1639 * @see talloc_asprintf()
     1640 * @see talloc_asprintf_append()
    14851641 */
    14861642char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
     
    16861842void talloc_enable_leak_report_full(void);
    16871843
     1844/**
     1845 * @brief Set a custom "abort" function that is called on serious error.
     1846 *
     1847 * The default "abort" function is <code>abort()</code>.
     1848 *
     1849 * The "abort" function is called when:
     1850 *
     1851 * <ul>
     1852 *  <li>talloc_get_type_abort() fails</li>
     1853 *  <li>the provided pointer is not a valid talloc context</li>
     1854 *  <li>when the context meta data are invalid</li>
     1855 *  <li>when access after free is detected</li>
     1856 * </ul>
     1857 *
     1858 * Example:
     1859 *
     1860 * @code
     1861 * void my_abort(const char *reason)
     1862 * {
     1863 *      fprintf(stderr, "talloc abort: %s\n", reason);
     1864 *      abort();
     1865 * }
     1866 *
     1867 *      talloc_set_abort_fn(my_abort);
     1868 * @endcode
     1869 *
     1870 * @param[in]  abort_fn      The new "abort" function.
     1871 *
     1872 * @see talloc_set_log_fn()
     1873 * @see talloc_get_type()
     1874 */
     1875void talloc_set_abort_fn(void (*abort_fn)(const char *reason));
     1876
     1877/**
     1878 * @brief Set a logging function.
     1879 *
     1880 * @param[in]  log_fn      The logging function.
     1881 *
     1882 * @see talloc_set_log_stderr()
     1883 * @see talloc_set_abort_fn()
     1884 */
     1885void talloc_set_log_fn(void (*log_fn)(const char *message));
     1886
     1887/**
     1888 * @brief Set stderr as the output for logs.
     1889 *
     1890 * @see talloc_set_log_fn()
     1891 * @see talloc_set_abort_fn()
     1892 */
     1893void talloc_set_log_stderr(void);
     1894
     1895/**
     1896 * @brief Set a max memory limit for the current context hierarchy
     1897 *        This affects all children of this context and constrain any
     1898 *        allocation in the hierarchy to never exceed the limit set.
     1899 *        The limit can be removed by setting 0 (unlimited) as the
     1900 *        max_size by calling the funciton again on the sam context.
     1901 *        Memory limits can also be nested, meaning a hild can have
     1902 *        a stricter memory limit than a parent.
     1903 *        Memory limits are enforced only at memory allocation time.
     1904 *        Stealing a context into a 'limited' hierarchy properly
     1905 *        updates memory usage but does *not* cause failure if the
     1906 *        move causes the new parent to exceed its limits. However
     1907 *        any further allocation on that hierarchy will then fail.
     1908 *
     1909 * @param[in]   ctx             The talloc context to set the limit on
     1910 * @param[in]   max_size        The (new) max_size
     1911 */
     1912int talloc_set_memlimit(const void *ctx, size_t max_size);
     1913
    16881914/* @} ******************************************************************/
    1689 
    1690 void talloc_set_abort_fn(void (*abort_fn)(const char *reason));
    1691 void talloc_set_log_fn(void (*log_fn)(const char *message));
    1692 void talloc_set_log_stderr(void);
    16931915
    16941916#if TALLOC_DEPRECATED
  • vendor/current/lib/talloc/talloc_guide.txt

    r746 r988  
    7070parent context implicitly refers to a hidden "null context" global 
    7171variable, so this should not be used in a multi-threaded environment 
    72 without proper synchronization ;
     72without proper synchronization. In threaded code turn off null tracking using
     73talloc_disable_null_tracking(). ;
    7374- the context returned by talloc_autofree_context() is also global so 
    7475shouldn't be used by several threads simultaneously without 
     
    195196
    196197=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    197 int talloc_unlink(const void *context, const void *ptr);
     198int talloc_unlink(const void *context, void *ptr);
    198199
    199200The talloc_unlink() function removes a specific parent from ptr. The
  • vendor/current/lib/talloc/testsuite.c

    r746 r988  
    2828#include <talloc.h>
    2929
     30#ifdef HAVE_PTHREAD
     31#include <pthread.h>
     32#endif
     33
     34#include <unistd.h>
     35#include <sys/wait.h>
     36
    3037#include "talloc_testsuite.h"
    3138
     
    5764                return false; \
    5865        }
    59 
    60 #if _SAMBA_BUILD_==3
    61 #ifdef malloc
    62 #undef malloc
    63 #endif
    64 #ifdef strdup
    65 #undef strdup
    66 #endif
    67 #endif
    6866
    6967#define CHECK_SIZE(test, ptr, tsize) do { \
     
    151149        CHECK_BLOCKS("ref1", p1, 5);
    152150        CHECK_BLOCKS("ref1", p2, 1);
     151        CHECK_BLOCKS("ref1", ref, 1);
    153152        CHECK_BLOCKS("ref1", r1, 2);
    154153
     
    259258        CHECK_BLOCKS("ref3", p2, 2);
    260259        CHECK_BLOCKS("ref3", r1, 1);
     260        CHECK_BLOCKS("ref3", ref, 1);
    261261
    262262        fprintf(stderr, "Freeing p1\n");
     
    301301        CHECK_BLOCKS("ref4", p1, 5);
    302302        CHECK_BLOCKS("ref4", p2, 1);
     303        CHECK_BLOCKS("ref4", ref, 1);
    303304        CHECK_BLOCKS("ref4", r1, 2);
    304305
     
    351352        CHECK_BLOCKS("unlink", p1, 7);
    352353        CHECK_BLOCKS("unlink", p2, 1);
     354        CHECK_BLOCKS("unlink", ref, 1);
    353355        CHECK_BLOCKS("unlink", r1, 2);
    354356
     
    419421        torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo",
    420422                "failed: wrong name after talloc_set_name(my name is foo)");
     423        torture_assert_str_equal("misc", talloc_get_name(p1), name,
     424                "failed: wrong name after talloc_set_name(my name is foo)");
    421425        CHECK_BLOCKS("misc", p1, 2);
    422426        CHECK_BLOCKS("misc", root, 3);
     
    627631        el2 = talloc(el1->list2, struct el2);
    628632        el2 = talloc(el1->list3, struct el2);
     633        (void)el2;
    629634
    630635        el1->list = talloc_realloc(el1, el1->list, struct el2 *, 100);
     
    839844                        p2 = talloc_strdup(p1, "foo bar");
    840845                        p3 = talloc_size(p1, 300);
     846                        (void)p2;
     847                        (void)p3;
    841848                        talloc_free(p1);
    842849                }
     
    858865                        p2 = talloc_strdup(p1, "foo bar");
    859866                        p3 = talloc_size(p1, 300);
    860                         talloc_free_children(ctx);
     867                        (void)p2;
     868                        (void)p3;
     869                        talloc_free(p1);
    861870                }
    862871                count += 3 * loop;
     
    980989}
    981990
     991struct new_parent {
     992        void *new_parent;
     993        char val[20];
     994};
     995
     996static int reparenting_destructor(struct new_parent *np)
     997{
     998        talloc_set_destructor(np, NULL);
     999        (void)talloc_move(np->new_parent, &np);
     1000        return -1;
     1001}
     1002
     1003static bool test_free_parent_reparent_child(void)
     1004{
     1005        void *top = talloc_new(NULL);
     1006        char *level1;
     1007        char *alternate_level1;
     1008        char *level2;
     1009        struct new_parent *level3;
     1010
     1011        printf("test: free_parent_reparent_child\n# "
     1012                "TALLOC FREE PARENT REPARENT CHILD\n");
     1013
     1014        level1 = talloc_strdup(top, "level1");
     1015        alternate_level1 = talloc_strdup(top, "alternate_level1");
     1016        level2 = talloc_strdup(level1, "level2");
     1017        level3 = talloc(level2, struct new_parent);
     1018        level3->new_parent = alternate_level1;
     1019        memset(level3->val, 'x', sizeof(level3->val));
     1020
     1021        talloc_set_destructor(level3, reparenting_destructor);
     1022        talloc_free(level1);
     1023
     1024        CHECK_PARENT("free_parent_reparent_child",
     1025                level3, alternate_level1);
     1026
     1027        talloc_free(top);
     1028
     1029        printf("success: free_parent_reparent_child\n");
     1030        return true;
     1031}
     1032
     1033static bool test_free_parent_reparent_child_in_pool(void)
     1034{
     1035        void *top = talloc_new(NULL);
     1036        char *level1;
     1037        char *alternate_level1;
     1038        char *level2;
     1039        void *pool;
     1040        struct new_parent *level3;
     1041
     1042        printf("test: free_parent_reparent_child_in_pool\n# "
     1043                "TALLOC FREE PARENT REPARENT CHILD IN POOL\n");
     1044
     1045        pool = talloc_pool(top, 1024);
     1046        level1 = talloc_strdup(pool, "level1");
     1047        alternate_level1 = talloc_strdup(top, "alternate_level1");
     1048        level2 = talloc_strdup(level1, "level2");
     1049        level3 = talloc(level2, struct new_parent);
     1050        level3->new_parent = alternate_level1;
     1051        memset(level3->val, 'x', sizeof(level3->val));
     1052
     1053        talloc_set_destructor(level3, reparenting_destructor);
     1054        talloc_free(level1);
     1055        talloc_set_destructor(level3, NULL);
     1056
     1057        CHECK_PARENT("free_parent_reparent_child_in_pool",
     1058                level3, alternate_level1);
     1059
     1060        /* Even freeing alternate_level1 should leave pool alone. */
     1061        talloc_free(alternate_level1);
     1062        talloc_free(top);
     1063
     1064        printf("success: free_parent_reparent_child_in_pool\n");
     1065        return true;
     1066}
     1067
     1068
    9821069static bool test_talloc_ptrtype(void)
    9831070{
     
    12771364}
    12781365
     1366static bool test_pool_nest(void)
     1367{
     1368        void *p1, *p2, *p3;
     1369        void *e = talloc_new(NULL);
     1370
     1371        p1 = talloc_pool(NULL, 1024);
     1372        torture_assert("talloc_pool", p1 != NULL, "failed");
     1373
     1374        p2 = talloc_pool(p1, 500);
     1375        torture_assert("talloc_pool", p2 != NULL, "failed");
     1376
     1377        p3 = talloc_size(p2, 10);
     1378
     1379        talloc_steal(e, p3);
     1380
     1381        talloc_free(p2);
     1382
     1383        talloc_free(p3);
     1384
     1385        talloc_free(p1);
     1386
     1387        return true;
     1388}
     1389
     1390struct pooled {
     1391        char *s1;
     1392        char *s2;
     1393        char *s3;
     1394};
     1395
     1396static bool test_pooled_object(void)
     1397{
     1398        struct pooled *p;
     1399        const char *s1 = "hello";
     1400        const char *s2 = "world";
     1401        const char *s3 = "";
     1402
     1403        p = talloc_pooled_object(NULL, struct pooled, 3,
     1404                        strlen(s1)+strlen(s2)+strlen(s3)+3);
     1405
     1406        if (talloc_get_size(p) != sizeof(struct pooled)) {
     1407                return false;
     1408        }
     1409
     1410        p->s1 = talloc_strdup(p, s1);
     1411
     1412        TALLOC_FREE(p->s1);
     1413        p->s1 = talloc_strdup(p, s2);
     1414        TALLOC_FREE(p->s1);
     1415
     1416        p->s1 = talloc_strdup(p, s1);
     1417        p->s2 = talloc_strdup(p, s2);
     1418        p->s3 = talloc_strdup(p, s3);
     1419
     1420        TALLOC_FREE(p);
     1421        return true;
     1422}
     1423
    12791424static bool test_free_ref_null_context(void)
    12801425{
     
    13251470{
    13261471        void *root;
    1327         const char *p1, *p2, *name, *name2;
     1472        char *p1, *p2;
     1473        const char *name, *name2;
    13281474
    13291475        talloc_enable_null_tracking();
     
    13311477        p1 = talloc_strdup(root, "foo1");
    13321478        p2 = talloc_strdup(p1, "foo2");
     1479        (void)p2;
    13331480
    13341481        talloc_set_name(p1, "%s", "testname");
     
    13551502        /* but this does */
    13561503        talloc_free_children(p1);
     1504        (void)name2;
    13571505        torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname2") == 0,
    13581506                       "wrong name");
     
    13641512}
    13651513
     1514static bool test_memlimit(void)
     1515{
     1516        void *root;
     1517        char *l1, *l2, *l3, *l4, *l5, *t;
     1518        char *pool;
     1519        int i;
     1520
     1521        printf("test: memlimit\n# MEMORY LIMITS\n");
     1522
     1523        printf("==== talloc_new(NULL)\n");
     1524        root = talloc_new(NULL);
     1525
     1526        talloc_report_full(root, stdout);
     1527
     1528        printf("==== talloc_size(root, 2048)\n");
     1529        l1 = talloc_size(root, 2048);
     1530        torture_assert("memlimit", l1 != NULL,
     1531                "failed: alloc should not fail due to memory limit\n");
     1532
     1533        talloc_report_full(root, stdout);
     1534
     1535        printf("==== talloc_free(l1)\n");
     1536        talloc_free(l1);
     1537
     1538        talloc_report_full(root, stdout);
     1539
     1540        printf("==== talloc_strdup(root, level 1)\n");
     1541        l1 = talloc_strdup(root, "level 1");
     1542        torture_assert("memlimit", l1 != NULL,
     1543                "failed: alloc should not fail due to memory limit\n");
     1544
     1545        talloc_report_full(root, stdout);
     1546
     1547        printf("==== talloc_set_memlimit(l1, 2048)\n");
     1548        torture_assert("memlimit", talloc_set_memlimit(l1, 2048) == 0,
     1549                "failed: setting memlimit should never fail\n");
     1550
     1551        talloc_report_full(root, stdout);
     1552
     1553        printf("==== talloc_size(root, 2048)\n");
     1554        l2 = talloc_size(l1, 2048);
     1555        torture_assert("memlimit", l2 == NULL,
     1556                "failed: alloc should fail due to memory limit\n");
     1557
     1558        talloc_report_full(root, stdout);
     1559
     1560        printf("==== talloc_strdup(l1, level 2)\n");
     1561        l2 = talloc_strdup(l1, "level 2");
     1562        torture_assert("memlimit", l2 != NULL,
     1563                "failed: alloc should not fail due to memory limit\n");
     1564
     1565        talloc_report_full(root, stdout);
     1566
     1567        printf("==== talloc_free(l2)\n");
     1568        talloc_free(l2);
     1569
     1570        talloc_report_full(root, stdout);
     1571
     1572        printf("==== talloc_size(NULL, 2048)\n");
     1573        l2 = talloc_size(NULL, 2048);
     1574
     1575        talloc_report_full(root, stdout);
     1576
     1577        printf("==== talloc_steal(l1, l2)\n");
     1578        talloc_steal(l1, l2);
     1579
     1580        talloc_report_full(root, stdout);
     1581
     1582        printf("==== talloc_strdup(l2, level 3)\n");
     1583        l3 = talloc_strdup(l2, "level 3");
     1584        torture_assert("memlimit", l3 == NULL,
     1585                "failed: alloc should fail due to memory limit\n");
     1586
     1587        talloc_report_full(root, stdout);
     1588
     1589        printf("==== talloc_free(l2)\n");
     1590        talloc_free(l2);
     1591
     1592        talloc_report_full(root, stdout);
     1593
     1594        printf("==== talloc_strdup(NULL, level 2)\n");
     1595        l2 = talloc_strdup(NULL, "level 2");
     1596        talloc_steal(l1, l2);
     1597
     1598        talloc_report_full(root, stdout);
     1599
     1600        printf("==== talloc_strdup(l2, level 3)\n");
     1601        l3 = talloc_strdup(l2, "level 3");
     1602        torture_assert("memlimit", l3 != NULL,
     1603                "failed: alloc should not fail due to memory limit\n");
     1604
     1605        talloc_report_full(root, stdout);
     1606
     1607        printf("==== talloc_set_memlimit(l3, 1024)\n");
     1608        torture_assert("memlimit", talloc_set_memlimit(l3, 1024) == 0,
     1609                "failed: setting memlimit should never fail\n");
     1610
     1611        talloc_report_full(root, stdout);
     1612
     1613        printf("==== talloc_strdup(l3, level 4)\n");
     1614        l4 = talloc_strdup(l3, "level 4");
     1615        torture_assert("memlimit", l4 != NULL,
     1616                "failed: alloc should not fail due to memory limit\n");
     1617
     1618        talloc_report_full(root, stdout);
     1619
     1620        printf("==== talloc_set_memlimit(l4, 512)\n");
     1621        torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0,
     1622                "failed: setting memlimit should never fail\n");
     1623
     1624        talloc_report_full(root, stdout);
     1625
     1626        printf("==== talloc_strdup(l4, level 5)\n");
     1627        l5 = talloc_strdup(l4, "level 5");
     1628        torture_assert("memlimit", l5 != NULL,
     1629                "failed: alloc should not fail due to memory limit\n");
     1630
     1631        talloc_report_full(root, stdout);
     1632
     1633        printf("==== talloc_realloc(NULL, l5, char, 600)\n");
     1634        t = talloc_realloc(NULL, l5, char, 600);
     1635        torture_assert("memlimit", t == NULL,
     1636                "failed: alloc should fail due to memory limit\n");
     1637
     1638        talloc_report_full(root, stdout);
     1639
     1640        printf("==== talloc_realloc(NULL, l5, char, 5)\n");
     1641        l5 = talloc_realloc(NULL, l5, char, 5);
     1642        torture_assert("memlimit", l5 != NULL,
     1643                "failed: alloc should not fail due to memory limit\n");
     1644
     1645        talloc_report_full(root, stdout);
     1646
     1647        printf("==== talloc_strdup(l3, level 4)\n");
     1648        l4 = talloc_strdup(l3, "level 4");
     1649        torture_assert("memlimit", l4 != NULL,
     1650                "failed: alloc should not fail due to memory limit\n");
     1651
     1652        talloc_report_full(root, stdout);
     1653
     1654        printf("==== talloc_set_memlimit(l4, 512)\n");
     1655        torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0,
     1656                "failed: setting memlimit should never fail\n");
     1657
     1658        talloc_report_full(root, stdout);
     1659
     1660        printf("==== talloc_strdup(l4, level 5)\n");
     1661        l5 = talloc_strdup(l4, "level 5");
     1662        torture_assert("memlimit", l5 != NULL,
     1663                "failed: alloc should not fail due to memory limit\n");
     1664
     1665        talloc_report_full(root, stdout);
     1666
     1667        printf("==== Make new temp context and steal l5\n");
     1668        t = talloc_new(root);
     1669        talloc_steal(t, l5);
     1670
     1671        talloc_report_full(root, stdout);
     1672
     1673        printf("==== talloc_size(t, 2048)\n");
     1674        l1 = talloc_size(t, 2048);
     1675        torture_assert("memlimit", l1 != NULL,
     1676                "failed: alloc should not fail due to memory limit\n");
     1677
     1678        talloc_report_full(root, stdout);
     1679        talloc_free(root);
     1680
     1681        /* Test memlimits with pools. */
     1682        pool = talloc_pool(NULL, 10*1024);
     1683        torture_assert("memlimit", pool != NULL,
     1684                "failed: alloc should not fail due to memory limit\n");
     1685        talloc_set_memlimit(pool, 10*1024);
     1686        for (i = 0; i < 9; i++) {
     1687                l1 = talloc_size(pool, 1024);
     1688                torture_assert("memlimit", l1 != NULL,
     1689                        "failed: alloc should not fail due to memory limit\n");
     1690        }
     1691        /* The next alloc should fail. */
     1692        l2 = talloc_size(pool, 1024);
     1693        torture_assert("memlimit", l2 == NULL,
     1694                        "failed: alloc should fail due to memory limit\n");
     1695
     1696        /* Moving one of the children shouldn't change the limit,
     1697           as it's still inside the pool. */
     1698        root = talloc_new(NULL);
     1699        talloc_steal(root, l1);
     1700        l2 = talloc_size(pool, 1024);
     1701        torture_assert("memlimit", l2 == NULL,
     1702                        "failed: alloc should fail due to memory limit\n");
     1703
     1704        talloc_free(pool);
     1705        talloc_free(root);
     1706        printf("success: memlimit\n");
     1707
     1708        return true;
     1709}
     1710
     1711#ifdef HAVE_PTHREAD
     1712
     1713#define NUM_THREADS 100
     1714
     1715/* Sync variables. */
     1716static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
     1717static pthread_cond_t condvar = PTHREAD_COND_INITIALIZER;
     1718static void *intermediate_ptr;
     1719
     1720/* Subthread. */
     1721static void *thread_fn(void *arg)
     1722{
     1723        int ret;
     1724        const char *ctx_name = (const char *)arg;
     1725        void *sub_ctx = NULL;
     1726        /*
     1727         * Do stuff that creates a new talloc hierarchy in
     1728         * this thread.
     1729         */
     1730        void *top_ctx = talloc_named_const(NULL, 0, "top");
     1731        if (top_ctx == NULL) {
     1732                return NULL;
     1733        }
     1734        sub_ctx = talloc_named_const(top_ctx, 100, ctx_name);
     1735        if (sub_ctx == NULL) {
     1736                return NULL;
     1737        }
     1738
     1739        /*
     1740         * Now transfer a pointer from our hierarchy
     1741         * onto the intermediate ptr.
     1742         */
     1743        ret = pthread_mutex_lock(&mtx);
     1744        if (ret != 0) {
     1745                talloc_free(top_ctx);
     1746                return NULL;
     1747        }
     1748        /* Wait for intermediate_ptr to be free. */
     1749        while (intermediate_ptr != NULL) {
     1750                ret = pthread_cond_wait(&condvar, &mtx);
     1751                if (ret != 0) {
     1752                        talloc_free(top_ctx);
     1753                        pthread_mutex_unlock(&mtx);
     1754                        return NULL;
     1755                }
     1756        }
     1757
     1758        /* and move our memory onto it from our toplevel hierarchy. */
     1759        intermediate_ptr = talloc_move(NULL, &sub_ctx);
     1760
     1761        /* Tell the main thread it's ready for pickup. */
     1762        pthread_cond_broadcast(&condvar);
     1763        pthread_mutex_unlock(&mtx);
     1764
     1765        talloc_free(top_ctx);
     1766        return NULL;
     1767}
     1768
     1769/* Main thread. */
     1770static bool test_pthread_talloc_passing(void)
     1771{
     1772        int i;
     1773        int ret;
     1774        char str_array[NUM_THREADS][20];
     1775        pthread_t thread_id;
     1776        void *mem_ctx;
     1777
     1778        /*
     1779         * Important ! Null tracking breaks threaded talloc.
     1780         * It *must* be turned off.
     1781         */
     1782        talloc_disable_null_tracking();
     1783
     1784        printf("test: pthread_talloc_passing\n# PTHREAD TALLOC PASSING\n");
     1785
     1786        /* Main thread toplevel context. */
     1787        mem_ctx = talloc_named_const(NULL, 0, "toplevel");
     1788        if (mem_ctx == NULL) {
     1789                printf("failed to create toplevel context\n");
     1790                return false;
     1791        }
     1792
     1793        /*
     1794         * Spin off NUM_THREADS threads.
     1795         * They will use their own toplevel contexts.
     1796         */
     1797        for (i = 0; i < NUM_THREADS; i++) {
     1798                (void)snprintf(str_array[i],
     1799                                20,
     1800                                "thread:%d",
     1801                                i);
     1802                if (str_array[i] == NULL) {
     1803                        printf("snprintf %d failed\n", i);
     1804                        return false;
     1805                }
     1806                ret = pthread_create(&thread_id,
     1807                                NULL,
     1808                                thread_fn,
     1809                                str_array[i]);
     1810                if (ret != 0) {
     1811                        printf("failed to create thread %d (%d)\n", i, ret);
     1812                        return false;
     1813                }
     1814        }
     1815
     1816        printf("Created %d threads\n", NUM_THREADS);
     1817
     1818        /* Now wait for NUM_THREADS transfers of the talloc'ed memory. */
     1819        for (i = 0; i < NUM_THREADS; i++) {
     1820                ret = pthread_mutex_lock(&mtx);
     1821                if (ret != 0) {
     1822                        printf("pthread_mutex_lock %d failed (%d)\n", i, ret);
     1823                        talloc_free(mem_ctx);
     1824                        return false;
     1825                }
     1826
     1827                /* Wait for intermediate_ptr to have our data. */
     1828                while (intermediate_ptr == NULL) {
     1829                        ret = pthread_cond_wait(&condvar, &mtx);
     1830                        if (ret != 0) {
     1831                                printf("pthread_cond_wait %d failed (%d)\n", i,
     1832                                        ret);
     1833                                talloc_free(mem_ctx);
     1834                                pthread_mutex_unlock(&mtx);
     1835                                return false;
     1836                        }
     1837                }
     1838
     1839                /* and move it onto our toplevel hierarchy. */
     1840                (void)talloc_move(mem_ctx, &intermediate_ptr);
     1841
     1842                /* Tell the sub-threads we're ready for another. */
     1843                pthread_cond_broadcast(&condvar);
     1844                pthread_mutex_unlock(&mtx);
     1845        }
     1846
     1847        CHECK_SIZE("pthread_talloc_passing", mem_ctx, NUM_THREADS * 100);
     1848#if 1
     1849        /* Dump the hierarchy. */
     1850        talloc_report(mem_ctx, stdout);
     1851#endif
     1852        talloc_free(mem_ctx);
     1853        printf("success: pthread_talloc_passing\n");
     1854        return true;
     1855}
     1856#endif
     1857
     1858static void test_magic_protection_abort(const char *reason)
     1859{
     1860        /* exit with errcode 42 to communicate successful test to the parent process */
     1861        if (strcmp(reason, "Bad talloc magic value - unknown value") == 0) {
     1862                _exit(42);
     1863        } else {
     1864                printf("talloc aborted for an unexpected reason\n");
     1865        }
     1866}
     1867
     1868static bool test_magic_protection(void)
     1869{
     1870        void *pool = talloc_pool(NULL, 1024);
     1871        int *p1, *p2;
     1872        pid_t pid;
     1873        int exit_status;
     1874
     1875        printf("test: magic_protection\n");
     1876        p1 = talloc(pool, int);
     1877        p2 = talloc(pool, int);
     1878
     1879        /* To avoid complaints from the compiler assign values to the p1 & p2. */
     1880        *p1 = 6;
     1881        *p2 = 9;
     1882
     1883        pid = fork();
     1884        if (pid == 0) {
     1885                talloc_set_abort_fn(test_magic_protection_abort);
     1886
     1887                /*
     1888                 * Simulate a security attack
     1889                 * by triggering a buffer overflow in memset to overwrite the
     1890                 * constructor in the next pool chunk.
     1891                 *
     1892                 * Real attacks would attempt to set a real destructor.
     1893                 */
     1894                memset(p1, '\0', 32);
     1895
     1896                /* Then the attack takes effect when the memory's freed. */
     1897                talloc_free(pool);
     1898
     1899                /* Never reached. Make compilers happy */
     1900                return true;
     1901        }
     1902
     1903        while (wait(&exit_status) != pid);
     1904
     1905        if (!WIFEXITED(exit_status)) {
     1906                printf("Child exited through unexpected abnormal means\n");
     1907                return false;
     1908        }
     1909        if (WEXITSTATUS(exit_status) != 42) {
     1910                printf("Child exited with wrong exit status\n");
     1911                return false;
     1912        }
     1913        if (WIFSIGNALED(exit_status)) {
     1914                printf("Child recieved unexpected signal\n");
     1915                return false;
     1916        }
     1917
     1918        printf("success: magic_protection\n");
     1919        return true;
     1920}
    13661921
    13671922static void test_reset(void)
     
    13801935
    13811936        test_reset();
     1937        ret &= test_pooled_object();
     1938        test_reset();
     1939        ret &= test_pool_nest();
     1940        test_reset();
    13821941        ret &= test_ref1();
    13831942        test_reset();
     
    14121971        ret &= test_free_parent_deny_child();
    14131972        test_reset();
     1973        ret &= test_free_parent_reparent_child();
     1974        test_reset();
     1975        ret &= test_free_parent_reparent_child_in_pool();
     1976        test_reset();
    14141977        ret &= test_talloc_ptrtype();
    14151978        test_reset();
     
    14251988        test_reset();
    14261989        ret &= test_free_children();
     1990        test_reset();
     1991        ret &= test_memlimit();
     1992#ifdef HAVE_PTHREAD
     1993        test_reset();
     1994        ret &= test_pthread_talloc_passing();
     1995#endif
     1996
    14271997
    14281998        if (ret) {
     
    14322002        test_reset();
    14332003        ret &= test_autofree();
     2004        test_reset();
     2005        ret &= test_magic_protection();
    14342006
    14352007        test_reset();
  • vendor/current/lib/talloc/wscript

    r740 r988  
    22
    33APPNAME = 'talloc'
    4 VERSION = '2.0.5'
     4VERSION = '2.1.6'
    55
    66
     
    1313srcdir = '.'
    1414while not os.path.exists(srcdir+'/buildtools') and len(srcdir.split('/')) < 5:
    15     srcdir = '../' + srcdir
     15    srcdir = srcdir + '/..'
    1616sys.path.insert(0, srcdir + '/buildtools/wafsamba')
    1717
     
    2121
    2222# setup what directories to put in a tarball
    23 samba_dist.DIST_DIRS('lib/talloc:. lib/replace:lib/replace buildtools:buildtools')
     23samba_dist.DIST_DIRS("""lib/talloc:. lib/replace:lib/replace
     24buildtools:buildtools third_party/waf:third_party/waf""")
    2425
    2526
     
    2829    opt.PRIVATE_EXTENSION_DEFAULT('talloc', noextension='talloc')
    2930    opt.RECURSE('lib/replace')
    30     opt.add_option('--enable-talloc-compat1',
    31                    help=("Build talloc 1.x.x compat library [False]"),
    32                    action="store_true", dest='TALLOC_COMPAT1', default=False)
    3331    if opt.IN_LAUNCH_DIR():
     32        opt.add_option('--enable-talloc-compat1',
     33                       help=("Build talloc 1.x.x compat library [False]"),
     34                       action="store_true", dest='TALLOC_COMPAT1', default=False)
    3435        opt.add_option('--disable-python',
    3536                       help=("disable the pytalloc module"),
     
    4546
    4647    if not conf.env.standalone_talloc:
    47         if conf.CHECK_BUNDLED_SYSTEM('talloc', minversion=VERSION,
     48        if conf.CHECK_BUNDLED_SYSTEM_PKG('talloc', minversion=VERSION,
    4849                                     implied_deps='replace'):
    4950            conf.define('USING_SYSTEM_TALLOC', 1)
    50         if conf.CHECK_BUNDLED_SYSTEM('pytalloc-util', minversion=VERSION,
     51        if conf.CHECK_BUNDLED_SYSTEM_PKG('pytalloc-util', minversion=VERSION,
    5152                                     implied_deps='talloc replace'):
    5253            conf.define('USING_SYSTEM_PYTALLOC_UTIL', 1)
    5354
    54     conf.env.TALLOC_COMPAT1 = Options.options.TALLOC_COMPAT1
     55    conf.env.TALLOC_COMPAT1 = False
     56    if conf.env.standalone_talloc:
     57        conf.env.TALLOC_COMPAT1 = Options.options.TALLOC_COMPAT1
    5558
    5659    conf.CHECK_XSLTPROC_MANPAGES()
     
    5861    if not conf.env.disable_python:
    5962        # also disable if we don't have the python libs installed
    60         conf.check_tool('python')
    61         conf.check_python_version((2,4,2))
     63        conf.SAMBA_CHECK_PYTHON(mandatory=False, version=(2,4,2))
    6264        conf.SAMBA_CHECK_PYTHON_HEADERS(mandatory=False)
    6365        if not conf.env.HAVE_PYTHON_H:
     
    6567            conf.env.disable_python = True
    6668
     69    conf.CHECK_HEADERS('sys/auxv.h')
     70    conf.CHECK_FUNCS('getauxval')
     71
    6772    conf.SAMBA_CONFIG_H()
     73
     74    conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS()
    6875
    6976
     
    7481        bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig'
    7582        bld.env.TALLOC_VERSION = VERSION
    76         bld.PKG_CONFIG_FILES('talloc.pc', vnum=VERSION)
    7783        private_library = False
    7884
     
    8288                          public_deps='talloc',
    8389                          soname='libtalloc.so.1',
     90                          pc_files=[],
     91                          public_headers=[],
    8492                          enabled=bld.env.TALLOC_COMPAT1)
    8593
    86         if not bld.env.disable_python:
    87             bld.PKG_CONFIG_FILES('pytalloc-util.pc', vnum=VERSION)
     94        testsuite_deps = 'talloc'
     95        if bld.CONFIG_SET('HAVE_PTHREAD'):
     96            testsuite_deps += ' pthread'
     97
     98        bld.SAMBA_BINARY('talloc_testsuite',
     99                         'testsuite_main.c testsuite.c',
     100                         testsuite_deps,
     101                         install=False)
     102
     103        bld.SAMBA_BINARY('talloc_test_magic_differs_helper',
     104                         'test_magic_differs_helper.c',
     105                         'talloc', install=False)
     106
    88107    else:
    89108        private_library = True
     
    98117                          hide_symbols=True,
    99118                          vnum=VERSION,
    100                           public_headers='talloc.h',
     119                          public_headers=('' if private_library else 'talloc.h'),
     120                          pc_files='talloc.pc',
    101121                          public_headers_install=not private_library,
    102122                          private_library=private_library,
    103                           manpages='talloc.3')
     123                          manpages='man/talloc.3')
    104124
    105125    if not bld.CONFIG_SET('USING_SYSTEM_PYTALLOC_UTIL') and not bld.env.disable_python:
     126        for env in bld.gen_python_environments(['PKGCONFIGDIR']):
     127            name = bld.pyembed_libname('pytalloc-util')
    106128
    107         bld.SAMBA_LIBRARY('pytalloc-util',
    108             source='pytalloc_util.c',
    109             public_deps='talloc',
    110             pyext=True,
    111             vnum=VERSION,
    112             private_library=private_library,
    113             public_headers='pytalloc.h'
    114             )
    115         bld.SAMBA_PYTHON('pytalloc',
    116                          'pytalloc.c',
    117                          deps='talloc pytalloc-util',
    118                          enabled=True,
    119                          realname='talloc.so')
     129            bld.SAMBA_LIBRARY(name,
     130                source='pytalloc_util.c',
     131                public_deps='talloc',
     132                pyembed=True,
     133                vnum=VERSION,
     134                hide_symbols=True,
     135                abi_directory='ABI',
     136                abi_match='pytalloc_* _pytalloc_*',
     137                private_library=private_library,
     138                public_headers=('' if private_library else 'pytalloc.h'),
     139                pc_files='pytalloc-util.pc'
     140                )
     141            bld.SAMBA_PYTHON('pytalloc',
     142                            'pytalloc.c',
     143                            deps='talloc ' + name,
     144                            enabled=True,
     145                            realname='talloc.so')
    120146
    121     if not getattr(bld.env, '_SAMBA_BUILD_', 0) == 4:
    122         # s4 already has the talloc testsuite builtin to smbtorture
    123         bld.SAMBA_BINARY('talloc_testsuite',
    124                          'testsuite_main.c testsuite.c',
    125                          deps='talloc',
    126                          install=False)
     147            bld.SAMBA_PYTHON('test_pytalloc',
     148                            'test_pytalloc.c',
     149                            deps='pytalloc',
     150                            enabled=True,
     151                            realname='_test_pytalloc.so',
     152                            install=False)
    127153
    128154
     
    133159    ret = samba_utils.RUN_COMMAND(cmd)
    134160    print("testsuite returned %d" % ret)
    135     sys.exit(ret)
     161    magic_helper_cmd = os.path.join(Utils.g_module.blddir, 'talloc_test_magic_differs_helper')
     162    magic_cmd = os.path.join(srcdir, 'lib', 'talloc',
     163                             'test_magic_differs.sh')
     164
     165    magic_ret = samba_utils.RUN_COMMAND(magic_cmd + " " +  magic_helper_cmd)
     166    print("magic differs test returned %d" % magic_ret)
     167    pyret = samba_utils.RUN_PYTHON_TESTS(['test_pytalloc.py'])
     168    print("python testsuite returned %d" % pyret)
     169    sys.exit(ret or magic_ret or pyret)
    136170
    137171def dist():
Note: See TracChangeset for help on using the changeset viewer.