Changeset 988 for vendor/current/lib/talloc
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- 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 11 11 * on the samba public source archive. 12 12 * 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 13 18 * @section talloc_bugs Discussion and bug reports 14 19 * … … 98 103 * context implicitly refers to a hidden "null context" global variable, so 99 104 * 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(). 101 107 * - the context returned by talloc_autofree_context() is also global so 102 108 * shouldn't be used by several threads simultaneously without -
vendor/current/lib/talloc/doxy.config
r740 r988 1 # Doxyfile 1. 6.11 # Doxyfile 1.8.0 2 2 3 3 # 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. 5 5 # 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. 7 7 # The format is: 8 8 # TAG = value [value, ...] 9 9 # For lists items can also be appended using: 10 10 # TAG += value [value, ...] 11 # Values that contain spaces should be placed between quotes (" ") 11 # Values that contain spaces should be placed between quotes (" "). 12 12 13 13 #--------------------------------------------------------------------------- … … 23 23 DOXYFILE_ENCODING = UTF-8 24 24 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. 27 28 28 29 PROJECT_NAME = talloc … … 33 34 34 35 PROJECT_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 41 PROJECT_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 48 PROJECT_LOGO = 35 49 36 50 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) … … 58 72 # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English 59 73 # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, 60 # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyril ic, Slovak,74 # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, 61 75 # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. 62 76 … … 137 151 138 152 # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 139 # (but less readable) file names. This can be useful i s your file systems153 # (but less readable) file names. This can be useful if your file system 140 154 # doesn't support long names like on DOS, Mac, or CD-ROM. 141 155 … … 192 206 ALIASES = 193 207 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 213 TCL_SUBST = 214 194 215 # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 195 216 # sources only. Doxygen will then generate output that is more tailored for C. … … 218 239 OPTIMIZE_OUTPUT_VHDL = NO 219 240 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. 228 250 229 251 EXTENSION_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 260 MARKDOWN_SUPPORT = YES 230 261 231 262 # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want … … 233 264 # set this tag to YES in order to let doxygen match functions declarations and 234 265 # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 235 # func(std::string) {}). This also make the inheritance and collaboration266 # func(std::string) {}). This also makes the inheritance and collaboration 236 267 # diagrams that involve STL classes more complete and accurate. 237 268 … … 251 282 # For Microsoft's IDL there are propget and propput attributes to indicate getter 252 283 # and setter methods for a property. Setting this option to YES (the default) 253 # will make doxygen toreplace the get and set methods by a property in the284 # will make doxygen replace the get and set methods by a property in the 254 285 # documentation. This will only work if the methods are indeed getting or 255 286 # setting a simple type. If this is not the case, or you want to show the … … 272 303 273 304 SUBGROUPING = 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 311 INLINE_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 320 INLINE_SIMPLE_STRUCTS = NO 274 321 275 322 # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum … … 289 336 # probably good enough. For larger projects a too small cache size can cause 290 337 # doxygen to be busy swapping symbols to and from disk most of the time 291 # causing a significant performance penal ity.338 # causing a significant performance penalty. 292 339 # If the system has enough physical memory increasing the cache will improve the 293 340 # performance by keeping more symbols in memory. Note that the value works on 294 # a logarithmic scale so increasing the size by one will roug ly double the341 # a logarithmic scale so increasing the size by one will roughly double the 295 342 # memory usage. The cache size is given by this formula: 296 343 # 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. 298 345 299 346 SYMBOL_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 357 LOOKUP_CACHE_SIZE = 0 300 358 301 359 #--------------------------------------------------------------------------- … … 315 373 EXTRACT_PRIVATE = NO 316 374 375 # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation. 376 377 EXTRACT_PACKAGE = NO 378 317 379 # If the EXTRACT_STATIC tag is set to YES all static members of a file 318 380 # will be included in the documentation. … … 337 399 # 'anonymous_namespace{file}', where file will be replaced with the base 338 400 # name of the file that contains the anonymous namespace. By default 339 # anonymous namespace are hidden.401 # anonymous namespaces are hidden. 340 402 341 403 EXTRACT_ANON_NSPACES = NO … … 397 459 SHOW_INCLUDE_FILES = YES 398 460 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 465 FORCE_LOCAL_INCLUDES = NO 466 399 467 # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 400 468 # is inserted in the documentation for inline members. … … 416 484 SORT_BRIEF_DOCS = NO 417 485 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. 419 493 420 494 SORT_MEMBERS_CTORS_1ST = NO … … 436 510 SORT_BY_SCOPE_NAME = NO 437 511 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 519 STRICT_PROTO_MATCHING = NO 520 438 521 # The GENERATE_TODOLIST tag can be used to enable (YES) or 439 522 # disable (NO) the todo list. This list is created by putting \todo … … 466 549 467 550 # The MAX_INITIALIZER_LINES tag determines the maximum number of lines 468 # the initial value of a variable or defineconsists of for it to appear in551 # the initial value of a variable or macro consists of for it to appear in 469 552 # the documentation. If the initializer consists of more lines than specified 470 553 # 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 the554 # The appearance of the initializer of individual variables and macros in the 472 555 # documentation can be controlled using \showinitializer or \hideinitializer 473 556 # command in the documentation regardless of this setting. … … 480 563 481 564 SHOW_USED_FILES = YES 482 483 # If the sources in your project are distributed over multiple directories484 # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy485 # in the documentation. The default is NO.486 487 SHOW_DIRECTORIES = NO488 565 489 566 # Set the SHOW_FILES tag to NO to disable the generation of the Files page. … … 510 587 FILE_VERSION_FILTER = 511 588 512 # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by513 # doxygen. The layout file controls the global structure of the generated output files514 # in an output format independent way. The create the layout file that represents515 # doxygen's defaults, run doxygen with the -l option. You can optionally specify a516 # file name after the option, if omitted DoxygenLayout.xml will be used as the name517 # 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. 518 595 519 596 LAYOUT_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 606 CITE_BIB_FILES = 520 607 521 608 #--------------------------------------------------------------------------- … … 547 634 WARN_IF_DOC_ERROR = YES 548 635 549 # Th is WARN_NO_PARAMDOC option can beabled to get warnings for636 # The WARN_NO_PARAMDOC option can be enabled to get warnings for 550 637 # functions that are documented, but have no documentation for their parameters 551 638 # or return value. If set to NO (the default) doxygen will only warn about … … 579 666 # with spaces. 580 667 581 INPUT = . doc 668 INPUT = . \ 669 doc 582 670 583 671 # This tag can be used to specify the character encoding of the source files … … 593 681 # and *.h) to filter out the source-files in the directories. If left 594 682 # 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 597 686 598 687 FILE_PATTERNS = *.cpp \ … … 610 699 RECURSIVE = NO 611 700 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 613 702 # excluded from the INPUT source files. This way you can easily exclude a 614 703 # 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. 615 706 616 707 EXCLUDE = 617 708 618 # The EXCLUDE_SYMLINKS tag can be used select whether or not files or619 # directories that are symbolic links (a Unix file system feature) are excluded709 # 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 620 711 # from the input. 621 712 … … 628 719 # for example use the pattern */test/* 629 720 630 EXCLUDE_PATTERNS = */.git/* \ 631 */.svn/* \ 632 */cmake/* \ 633 */build/* 721 EXCLUDE_PATTERNS = */.git/* 634 722 635 723 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names … … 665 753 # the \image command). 666 754 667 IMAGE_PATH = 755 IMAGE_PATH = doc 668 756 669 757 # The INPUT_FILTER tag can be used to specify a program that doxygen should … … 684 772 # The filters are a list of the form: 685 773 # 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_FILTER687 # 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. 688 776 689 777 FILTER_PATTERNS = … … 694 782 695 783 FILTER_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 791 FILTER_SOURCE_PATTERNS = 696 792 697 793 #--------------------------------------------------------------------------- … … 783 879 GENERATE_HTML = YES 784 880 785 # If the HTML_FOOTER_DESCRIPTION tag is set to YES, Doxygen will786 # add generated date, project name and doxygen version to HTML footer.787 788 HTML_FOOTER_DESCRIPTION= NO789 790 881 # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 791 882 # If a relative path is entered the value of OUTPUT_DIRECTORY will be … … 802 893 # The HTML_HEADER tag can be used to specify a personal HTML header for 803 894 # 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! 805 903 806 904 HTML_HEADER = … … 817 915 # will generate a default style sheet. Note that doxygen will try to copy 818 916 # the style sheet file to the HTML output directory, so don't put your own 819 # style sheet 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! 820 918 821 919 HTML_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 928 HTML_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 938 HTML_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 944 HTML_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 953 HTML_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 959 HTML_TIMESTAMP = NO 822 960 823 961 # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, … … 843 981 # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 844 982 # 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. 846 985 847 986 GENERATE_DOCSET = NO … … 861 1000 DOCSET_BUNDLE_ID = org.doxygen.Project 862 1001 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 1006 DOCSET_PUBLISHER_ID = org.doxygen.Publisher 1007 1008 # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. 1009 1010 DOCSET_PUBLISHER_NAME = Publisher 1011 863 1012 # If the GENERATE_HTMLHELP tag is set to YES, additional index files 864 1013 # will be generated that can be used as input for tools like the … … 905 1054 TOC_EXPAND = NO 906 1055 907 # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER908 # are set, an additional index file will be generated that can be used as input for909 # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated910 # 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. 911 1060 912 1061 GENERATE_QHP = NO … … 930 1079 QHP_VIRTUAL_FOLDER = doc 931 1080 932 # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add.933 # For more information please see1081 # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to 1082 # add. For more information please see 934 1083 # http://doc.trolltech.com/qthelpproject.html#custom-filters 935 1084 936 1085 QHP_CUST_FILTER_NAME = 937 1086 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>. 940 1091 941 1092 QHP_CUST_FILTER_ATTRS = 942 1093 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 944 1096 # 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>. 946 1099 947 1100 QHP_SECT_FILTER_ATTRS = … … 954 1107 QHG_LOCATION = 955 1108 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 1118 GENERATE_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 1124 ECLIPSE_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. 959 1131 960 1132 DISABLE_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 = 4966 1133 967 1134 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index … … 972 1139 # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). 973 1140 # 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. 974 1143 975 1144 GENERATE_TREEVIEW = NONE 976 1145 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 1151 ENUM_VALUES_PER_LINE = 4 981 1152 982 1153 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be … … 985 1156 986 1157 TREEVIEW_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 1162 EXT_LINKS_IN_WINDOW = NO 987 1163 988 1164 # Use this tag to change the font size of Latex formulas included … … 994 1170 FORMULA_FONTSIZE = 10 995 1171 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 1178 FORMULA_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 1187 USE_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 1199 MATHJAX_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 1204 MATHJAX_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. 1000 1213 1001 1214 SEARCHENGINE = 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 1224 SERVER_BASED_SEARCH = NO 1002 1225 1003 1226 #--------------------------------------------------------------------------- … … 1018 1241 # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 1019 1242 # 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. 1020 1246 1021 1247 LATEX_CMD_NAME = latex … … 1034 1260 1035 1261 # 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 and1262 # by the printer. Possible values are: a4, letter, legal and 1037 1263 # executive. If left blank a4wide will be used. 1038 1264 … … 1051 1277 LATEX_HEADER = 1052 1278 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 1284 LATEX_FOOTER = 1285 1053 1286 # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 1054 1287 # is prepared for conversion to pdf (using ps2pdf). The pdf file will … … 1077 1310 LATEX_HIDE_INDICES = NO 1078 1311 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. 1080 1316 1081 1317 LATEX_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 1323 LATEX_BIB_STYLE = plain 1082 1324 1083 1325 #--------------------------------------------------------------------------- … … 1112 1354 RTF_HYPERLINKS = NO 1113 1355 1114 # Load style sheet definitions from file. Syntax is similar to doxygen's1356 # Load style sheet definitions from file. Syntax is similar to doxygen's 1115 1357 # config file, i.e. a series of assignments. You only have to provide 1116 1358 # replacements, missing definitions are set to their default value. … … 1257 1499 1258 1500 # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 1259 # in the INCLUDE_PATH (see below) will be search ifa #include is found.1501 # pointed to by INCLUDE_PATH will be searched when a #include is found. 1260 1502 1261 1503 SEARCH_INCLUDES = YES … … 1282 1524 # instead of the = operator. 1283 1525 1284 PREDEFINED = DOXYGEN PRINTF_ATTRIBUTE(x,y)= 1526 PREDEFINED = DOXYGEN \ 1527 PRINTF_ATTRIBUTE(x,y)= 1285 1528 1286 1529 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 1287 1530 # this tag can be used to specify a list of macro names that should be expanded. 1288 1531 # 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. 1290 1534 1291 1535 EXPAND_AS_DEFINED = 1292 1536 1293 1537 # 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. 1298 1541 1299 1542 SKIP_FUNCTION_MACROS = YES … … 1303 1546 #--------------------------------------------------------------------------- 1304 1547 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: 1309 1551 # 1310 1552 # TAGFILES = file1 file2 ... … … 1312 1554 # 1313 1555 # 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. 1321 1560 1322 1561 TAGFILES = … … 1351 1590 # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 1352 1591 # 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. 1356 1594 1357 1595 CLASS_DIAGRAMS = YES … … 1379 1617 HAVE_DOT = NO 1380 1618 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 1625 DOT_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. 1389 1633 1390 1634 DOT_FONTNAME = FreeSans … … 1395 1639 DOT_FONTSIZE = 10 1396 1640 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. 1401 1644 1402 1645 DOT_FONTPATH = … … 1405 1648 # will generate a graph for each documented class showing the direct and 1406 1649 # indirect inheritance relations. Setting this tag to YES will force the 1407 # theCLASS_DIAGRAMS tag to NO.1650 # CLASS_DIAGRAMS tag to NO. 1408 1651 1409 1652 CLASS_GRAPH = YES … … 1426 1669 1427 1670 UML_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 1679 UML_LIMIT_NUM_FIELDS = 10 1428 1680 1429 1681 # If set to YES, the inheritance and collaboration graphs will show the … … 1463 1715 1464 1716 # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 1465 # will g raphical hierarchy of all classes instead of a textual one.1717 # will generate a graphical hierarchy of all classes instead of a textual one. 1466 1718 1467 1719 GRAPHICAL_HIERARCHY = YES 1468 1720 1469 # If the DIRECTORY_GRAPH , SHOW_DIRECTORIESand HAVE_DOT tags are set to YES1721 # If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES 1470 1722 # then doxygen will show the dependencies a directory has on other directories 1471 1723 # in a graphical way. The dependency relations are determined by the #include … … 1475 1727 1476 1728 # 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). 1479 1733 1480 1734 DOT_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 1743 INTERACTIVE_SVG = NO 1481 1744 1482 1745 # The tag DOT_PATH can be used to specify the path where the dot tool can be … … 1490 1753 1491 1754 DOTFILE_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 1760 MSCFILE_DIRS = 1492 1761 1493 1762 # 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 7 7 Description: Utility functions for using talloc objects with Python 8 8 Version: @TALLOC_VERSION@ 9 Libs: -L${libdir} -lpytalloc-util10 Cflags: @LIB_RPATH@-I${includedir}9 Libs: @LIB_RPATH@ -L${libdir} -lpytalloc-util@PYTHON_SO_ABI_FLAG@ 10 Cflags: -I${includedir} 11 11 URL: http://talloc.samba.org/ -
vendor/current/lib/talloc/pytalloc.c
r740 r988 2 2 Unix SMB/CIFS implementation. 3 3 Python Talloc Module 4 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2010 4 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2010-2011 5 5 6 6 This program is free software; you can redistribute it and/or modify … … 21 21 #include <talloc.h> 22 22 #include <pytalloc.h> 23 24 void inittalloc(void); 23 #include "pytalloc_private.h" 24 25 static 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 25 32 26 33 /* print a talloc tree report for a talloc python object */ 27 static PyObject *py _talloc_report_full(PyObject *self, PyObject *args)34 static PyObject *pytalloc_report_full(PyObject *self, PyObject *args) 28 35 { 29 36 PyObject *py_obj = Py_None; 30 PyTypeObject *type;31 37 32 38 if (!PyArg_ParseTuple(args, "|O", &py_obj)) … … 36 42 talloc_report_full(NULL, stdout); 37 43 } 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); 40 45 } 41 46 return Py_None; … … 43 48 44 49 /* enable null tracking */ 45 static PyObject *py _talloc_enable_null_tracking(PyObject *self)50 static PyObject *pytalloc_enable_null_tracking(PyObject *self) 46 51 { 47 52 talloc_enable_null_tracking(); … … 50 55 51 56 /* return the number of talloc blocks */ 52 static PyObject *py _talloc_total_blocks(PyObject *self, PyObject *args)57 static PyObject *pytalloc_total_blocks(PyObject *self, PyObject *args) 53 58 { 54 59 PyObject *py_obj = Py_None; 55 PyTypeObject *type;56 60 57 61 if (!PyArg_ParseTuple(args, "|O", &py_obj)) … … 62 66 } 63 67 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))); 67 69 } 68 70 69 71 static PyMethodDef talloc_methods[] = { 70 { "report_full", (PyCFunction)py _talloc_report_full, METH_VARARGS,72 { "report_full", (PyCFunction)pytalloc_report_full, METH_VARARGS, 71 73 "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, 73 75 "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, 75 77 "return talloc block count"}, 76 78 { NULL } … … 80 82 * Default (but only slightly more useful than the default) implementation of Repr(). 81 83 */ 82 static PyObject *py _talloc_default_repr(PyObject *obj)83 { 84 py _talloc_Object *talloc_obj = (py_talloc_Object *)obj;84 static PyObject *pytalloc_default_repr(PyObject *obj) 85 { 86 pytalloc_Object *talloc_obj = (pytalloc_Object *)obj; 85 87 PyTypeObject *type = (PyTypeObject*)PyObject_Type(obj); 86 88 87 return PyStr ing_FromFormat("<%s talloc object at 0x%p>",88 89 return PyStr_FromFormat("<%s talloc object at 0x%p>", 90 type->tp_name, talloc_obj->ptr); 89 91 } 90 92 … … 92 94 * Simple dealloc for talloc-wrapping PyObjects 93 95 */ 94 static void py _talloc_dealloc(PyObject* self)95 { 96 py _talloc_Object *obj = (py_talloc_Object *)self;96 static void pytalloc_dealloc(PyObject* self) 97 { 98 pytalloc_Object *obj = (pytalloc_Object *)self; 97 99 assert(talloc_unlink(NULL, obj->talloc_ctx) != -1); 98 100 obj->talloc_ctx = NULL; … … 103 105 * Default (but only slightly more useful than the default) implementation of cmp. 104 106 */ 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 108 static 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 136 static int pytalloc_default_cmp(PyObject *_obj1, PyObject *_obj2) 137 { 138 pytalloc_Object *obj1 = (pytalloc_Object *)_obj1, 139 *obj2 = (pytalloc_Object *)_obj2; 109 140 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 114 146 115 147 static PyTypeObject TallocObject_Type = { 116 148 .tp_name = "talloc.Object", 117 149 .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, 120 152 .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 */ 164 static 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 */ 176 static 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 188 static 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 216 static 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 227 static 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 244 static 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 253 static PyObject *module_init(void); 254 static PyObject *module_init(void) 126 255 { 127 256 PyObject *m; 128 257 129 258 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 134 269 if (m == NULL) 135 return ;270 return NULL; 136 271 137 272 Py_INCREF(&TallocObject_Type); 138 273 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 280 PyMODINIT_FUNC PyInit_talloc(void); 281 PyMODINIT_FUNC PyInit_talloc(void) 282 { 283 return module_init(); 284 } 285 #else 286 void inittalloc(void); 287 void inittalloc(void) 288 { 289 module_init(); 290 } 291 #endif -
vendor/current/lib/talloc/pytalloc.h
r740 r988 18 18 */ 19 19 20 #ifndef _PY _TALLOC_H_21 #define _PY _TALLOC_H_20 #ifndef _PYTALLOC_H_ 21 #define _PYTALLOC_H_ 22 22 23 23 #include <Python.h> … … 27 27 PyObject_HEAD 28 28 TALLOC_CTX *talloc_ctx; 29 void *ptr; 30 } py _talloc_Object;29 void *ptr; /* eg the array element */ 30 } pytalloc_Object; 31 31 32 PyTypeObject *PyTalloc_GetObjectType(void); 33 int PyTalloc_Check(PyObject *);32 /* Return the PyTypeObject for pytalloc_Object. Returns a new reference. */ 33 PyTypeObject *pytalloc_GetObjectType(void); 34 34 35 /* Ret rieve 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. */ 36 PyTypeObject *pytalloc_GetBaseObjectType(void); 37 37 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. */ 39 int pytalloc_Check(PyObject *); 41 40 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 41 int pytalloc_BaseObject_check(PyObject *); 44 42 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. */ 45 void *_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)) 49 47 50 #define py_talloc_new(type, typeobj) py_talloc_steal(typeobj, talloc_zero(NULL, type)) 48 void *_pytalloc_get_ptr(PyObject *py_obj); 49 #define pytalloc_get_ptr(py_obj) _pytalloc_get_ptr((PyObject *)(py_obj)) 50 TALLOC_CTX *_pytalloc_get_mem_ctx(PyObject *py_obj); 51 #define pytalloc_get_mem_ctx(py_obj) _pytalloc_get_mem_ctx((PyObject *)(py_obj)) 51 52 52 PyObject *PyCObject_FromTallocPtr(void *); 53 PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr); 54 PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr); 55 PyObject *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) 53 57 54 PyObject *PyString_FromString_check_null(const char *ptr); 58 #define pytalloc_new(type, typeobj) pytalloc_steal(typeobj, talloc_zero(NULL, type)) 55 59 56 #endif /* _PY_TALLOC_H_ */ 60 #if PY_MAJOR_VERSION < 3 61 PyObject *pytalloc_CObject_FromTallocPtr(void *); 62 #endif 63 64 size_t pytalloc_BaseObject_size(void); 65 66 int pytalloc_BaseObject_PyType_Ready(PyTypeObject *type); 67 68 #endif /* _PYTALLOC_H_ */ -
vendor/current/lib/talloc/pytalloc_util.c
r740 r988 23 23 #include "pytalloc.h" 24 24 #include <assert.h> 25 26 _PUBLIC_ PyTypeObject *PyTalloc_GetObjectType(void) 25 #include "pytalloc_private.h" 26 27 _PUBLIC_ PyTypeObject *pytalloc_GetObjectType(void) 27 28 { 28 29 static PyTypeObject *type = NULL; … … 39 40 40 41 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"); 41 62 Py_DECREF(mod); 42 63 … … 47 68 * Import an existing talloc pointer into a Python object. 48 69 */ 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 } 63 123 } 64 124 … … 66 126 * Import an existing talloc pointer into a Python object. 67 127 */ 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); 71 131 } 72 132 … … 75 135 * Import an existing talloc pointer into a Python object, leaving the 76 136 * 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. 78 144 */ 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 192 static void py_cobject_talloc_free(void *ptr) 193 { 194 talloc_free(ptr); 195 } 196 197 _PUBLIC_ PyObject *pytalloc_CObject_FromTallocPtr(void *ptr) 198 { 83 199 if (ptr == NULL) { 84 200 Py_RETURN_NONE; 85 201 } 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 }110 202 return PyCObject_FromVoidPtr(ptr, py_cobject_talloc_free); 111 203 } 112 204 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(); 116 210 117 211 return PyObject_TypeCheck(obj, tp); 118 212 } 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 /* 2 2 Samba Unix SMB/CIFS implementation. 3 3 … … 8 8 Copyright (C) Andrew Tridgell 2004 9 9 Copyright (C) Stefan Metzmacher 2006 10 10 11 11 ** NOTE! The following LGPL license applies to the talloc 12 12 ** library. This does NOT imply that all of Samba is released 13 13 ** under the LGPL 14 14 15 15 This library is free software; you can redistribute it and/or 16 16 modify it under the terms of the GNU Lesser General Public … … 33 33 #include "replace.h" 34 34 #include "talloc.h" 35 36 #ifdef HAVE_SYS_AUXV_H 37 #include <sys/auxv.h> 38 #endif 35 39 36 40 #ifdef TALLOC_BUILD_VERSION_MAJOR … … 61 65 62 66 #define MAX_TALLOC_SIZE 0x10000000 63 #define TALLOC_MAGIC_BASE 0xe814ec7064 #define TALLOC_MAGIC ( \65 TALLOC_MAGIC_BASE + \66 (TALLOC_VERSION_MAJOR << 12) + \67 (TALLOC_VERSION_MINOR << 4) \68 )69 67 70 68 #define TALLOC_FLAG_FREE 0x01 … … 72 70 #define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */ 73 71 #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 74 79 #define TALLOC_MAGIC_REFERENCE ((const char *)1) 75 80 76 /* by default we abort when given a bad pointer (such as when talloc_free() is called 81 #define TALLOC_MAGIC_BASE 0xe814ec70 82 static 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 77 88 on a pointer that came from malloc() */ 78 89 #ifndef TALLOC_ABORT … … 228 239 }; 229 240 241 struct talloc_memlimit { 242 struct talloc_chunk *parent; 243 struct talloc_memlimit *upper; 244 size_t max_size; 245 size_t cur_size; 246 }; 247 248 static inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size); 249 static inline void talloc_memlimit_grow(struct talloc_memlimit *limit, 250 size_t size); 251 static inline void talloc_memlimit_shrink(struct talloc_memlimit *limit, 252 size_t size); 253 static inline void talloc_memlimit_update_on_free(struct talloc_chunk *tc); 254 255 static inline void _talloc_set_name_const(const void *ptr, const char *name); 256 230 257 typedef int (*talloc_destructor_t)(void *); 231 258 259 struct talloc_pool_hdr; 260 232 261 struct talloc_chunk { 262 unsigned flags; 233 263 struct talloc_chunk *next, *prev; 234 264 struct talloc_chunk *parent, *child; … … 237 267 const char *name; 238 268 size_t size; 239 unsigned flags;240 269 241 270 /* 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" 248 281 * is a pointer to the struct talloc_chunk of the pool that it was 249 282 * allocated from. This way children can quickly find the pool to chew 250 283 * from. 251 284 */ 252 void*pool;285 struct talloc_pool_hdr *pool; 253 286 }; 254 287 … … 268 301 } 269 302 303 _PUBLIC_ int talloc_test_get_magic(void) 304 { 305 return talloc_magic; 306 } 307 270 308 static void (*talloc_log_fn)(const char *message); 271 309 … … 274 312 talloc_log_fn = log_fn; 275 313 } 314 315 #ifdef HAVE_CONSTRUCTOR_ATTRIBUTE 316 void talloc_lib_init(void) __attribute__((constructor)); 317 void 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 276 358 277 359 static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2); … … 323 405 static void talloc_abort_magic(unsigned magic) 324 406 { 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);331 407 talloc_abort("Bad talloc magic value - wrong talloc version used/mixed"); 332 408 } … … 347 423 const char *pp = (const char *)ptr; 348 424 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 & (~0xF FF)) == 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)); 352 428 return NULL; 353 429 } … … 438 514 */ 439 515 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))) 516 struct 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 524 static 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 529 static 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 534 static 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 540 static 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. */ 546 static inline void *tc_next_chunk(struct talloc_chunk *tc) 547 { 548 return (char *)tc + TC_ALIGN16(TC_HDR_SIZE + tc->size); 549 } 550 551 static 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 } 454 556 455 557 /* 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) 558 static 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 } 463 565 464 566 #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 483 569 } 484 570 … … 487 573 */ 488 574 489 static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,490 size_t size)491 { 492 struct talloc_ chunk *pool_ctx= NULL;575 static 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; 493 579 size_t space_left; 494 580 struct talloc_chunk *result; … … 500 586 501 587 if (parent->flags & TALLOC_FLAG_POOL) { 502 pool_ ctx = parent;588 pool_hdr = talloc_pool_from_chunk(parent); 503 589 } 504 590 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) { 509 595 return NULL; 510 596 } 511 597 512 space_left = TC_POOL_SPACE_LEFT(pool_ctx);598 space_left = tc_pool_space_left(pool_hdr); 513 599 514 600 /* 515 601 * Align size to 16 bytes 516 602 */ 517 chunk_size = TC_ALIGN16(size );603 chunk_size = TC_ALIGN16(size + prefix_len); 518 604 519 605 if (space_left < chunk_size) { … … 521 607 } 522 608 523 result = (struct talloc_chunk *) pool_ctx->pool;609 result = (struct talloc_chunk *)((char *)pool_hdr->end + prefix_len); 524 610 525 611 #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++; 535 621 536 622 return result; 537 623 } 538 624 539 /* 625 /* 540 626 Allocate a bit of memory as a child of an existing pointer 541 627 */ 542 static inline void *__talloc(const void *context, size_t size) 628 static inline void *__talloc_with_prefix(const void *context, size_t size, 629 size_t prefix_len) 543 630 { 544 631 struct talloc_chunk *tc = NULL; 632 struct talloc_memlimit *limit = NULL; 633 size_t total_len = TC_HDR_SIZE + size + prefix_len; 545 634 546 635 if (unlikely(context == NULL)) { … … 552 641 } 553 642 643 if (unlikely(total_len < TC_HDR_SIZE)) { 644 return NULL; 645 } 646 554 647 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); 557 655 } 558 656 559 657 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; 563 674 tc->pool = NULL; 564 } 565 675 676 talloc_memlimit_grow(limit, total_len); 677 } 678 679 tc->limit = limit; 566 680 tc->size = size; 567 681 tc->destructor = NULL; … … 590 704 } 591 705 706 static inline void *__talloc(const void *context, size_t size) 707 { 708 return __talloc_with_prefix(context, size, 0); 709 } 710 592 711 /* 593 712 * Create a talloc pool 594 713 */ 595 714 596 _PUBLIC_ void *talloc_pool(const void *context, size_t size) 597 { 598 void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE); 715 static inline void *_talloc_pool(const void *context, size_t size) 716 { 599 717 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); 600 722 601 723 if (unlikely(result == NULL)) { … … 604 726 605 727 tc = talloc_chunk_from_ptr(result); 728 pool_hdr = talloc_pool_from_chunk(tc); 606 729 607 730 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); 613 738 614 739 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 809 overflow: 810 return NULL; 615 811 } 616 812 … … 628 824 629 825 /* 630 increase the reference count on a piece of memory. 826 increase the reference count on a piece of memory. 631 827 */ 632 828 _PUBLIC_ int talloc_increase_ref_count(const void *ptr) … … 651 847 652 848 /* 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 654 850 true string constant 655 851 */ … … 681 877 the pointer remains valid until both the original caller and this given 682 878 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 685 881 same underlying data, and you want to be able to free the two instances separately, 686 882 and in either order … … 713 909 const char *location) 714 910 { 715 struct talloc_chunk *pool; 911 struct talloc_pool_hdr *pool; 912 struct talloc_chunk *pool_tc; 716 913 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); 721 918 722 919 tc->flags |= TALLOC_FLAG_FREE; … … 730 927 TC_INVALIDATE_FULL_CHUNK(tc); 731 928 732 pool_object_count = talloc_pool_objectcount(pool); 733 734 if (unlikely(*pool_object_count == 0)) { 929 if (unlikely(pool->object_count == 0)) { 735 930 talloc_abort("Pool object count zero!"); 736 931 return; 737 932 } 738 933 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))) { 742 938 /* 743 939 * if there is just one object left in the pool … … 747 943 * again. 748 944 */ 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)) { 752 951 /* 753 952 * we mark the freed memory with where we called the free … … 755 954 * the first free came from 756 955 */ 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) { 762 975 /* 763 976 * if pool->pool still points to end of … … 765 978 * we can reclaim the memory of 'tc'. 766 979 */ 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 */ 769 988 } 770 989 … … 773 992 const char *location); 774 993 775 /* 994 /* 776 995 internal talloc_free call 777 996 */ … … 779 998 { 780 999 struct talloc_chunk *tc; 1000 void *ptr_to_free; 781 1001 782 1002 if (unlikely(ptr == NULL)) { … … 825 1045 tc->destructor = (talloc_destructor_t)-1; 826 1046 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 } 828 1054 return -1; 829 1055 } … … 850 1076 /* we mark the freed memory with where we called the free 851 1077 * 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 */ 854 1080 tc->name = location; 855 1081 856 1082 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)) { 862 1088 talloc_abort("Pool object count zero!"); 863 1089 return 0; 864 1090 } 865 1091 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) { 873 1109 _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); 878 1117 return 0; 879 1118 } 880 1119 881 /* 1120 static inline size_t _talloc_total_limit_size(const void *ptr, 1121 struct talloc_memlimit *old_limit, 1122 struct talloc_memlimit *new_limit); 1123 1124 /* 882 1125 move a lump of memory from one talloc context to another return the 883 1126 ptr on success, or NULL if it could not be transferred. … … 887 1130 { 888 1131 struct talloc_chunk *tc, *new_tc; 1132 size_t ctx_size = 0; 889 1133 890 1134 if (unlikely(!ptr)) { … … 897 1141 898 1142 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 } 899 1157 900 1158 if (unlikely(new_ctx == NULL)) { … … 908 1166 if (tc->next) tc->next->prev = tc->prev; 909 1167 } 910 1168 911 1169 tc->parent = tc->next = tc->prev = NULL; 912 1170 return discard_const_p(void, ptr); … … 934 1192 _TLIST_ADD(new_tc->child, tc); 935 1193 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 936 1203 return discard_const_p(void, ptr); 937 1204 } 938 1205 939 /* 1206 /* 940 1207 move a lump of memory from one talloc context to another return the 941 1208 ptr on success, or NULL if it could not be transferred. … … 949 1216 return NULL; 950 1217 } 951 1218 952 1219 tc = talloc_chunk_from_ptr(ptr); 953 1220 954 1221 if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) { 955 1222 struct talloc_reference_handle *h; … … 971 1238 } 972 1239 #endif 973 1240 974 1241 return _talloc_steal_internal(new_ctx, ptr); 975 1242 } 976 1243 977 /* 1244 /* 978 1245 this is like a talloc_steal(), but you must supply the old 979 1246 parent. This resolves the ambiguity in a talloc_steal() which is … … 1003 1270 return discard_const_p(void, ptr); 1004 1271 } 1005 } 1272 } 1006 1273 1007 1274 /* it wasn't a parent */ … … 1040 1307 /* 1041 1308 remove a specific parent context from a pointer. This is a more 1042 controlled vari ent of talloc_free()1309 controlled variant of talloc_free() 1043 1310 */ 1044 1311 _PUBLIC_ int talloc_unlink(const void *context, void *ptr) 1045 1312 { 1046 struct talloc_chunk *tc_p, *new_p ;1313 struct talloc_chunk *tc_p, *new_p, *tc_c; 1047 1314 void *new_parent; 1048 1315 … … 1059 1326 } 1060 1327 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); 1065 1330 } 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 1071 1337 tc_p = talloc_chunk_from_ptr(ptr); 1072 1338 … … 1149 1415 return the name of a talloc ptr, or "UNNAMED" 1150 1416 */ 1151 _PUBLIC_ const char *talloc_get_name(const void *ptr)1417 static inline const char *__talloc_get_name(const void *ptr) 1152 1418 { 1153 1419 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); … … 1161 1427 } 1162 1428 1429 _PUBLIC_ const char *talloc_get_name(const void *ptr) 1430 { 1431 return __talloc_get_name(ptr); 1432 } 1163 1433 1164 1434 /* … … 1170 1440 const char *pname; 1171 1441 if (unlikely(ptr == NULL)) return NULL; 1172 pname = talloc_get_name(ptr);1442 pname = __talloc_get_name(ptr); 1173 1443 if (likely(pname == name || strcmp(pname, name) == 0)) { 1174 1444 return discard_const_p(void, ptr); … … 1177 1447 } 1178 1448 1179 static void talloc_abort_type_mis smatch(const char *location,1449 static void talloc_abort_type_mismatch(const char *location, 1180 1450 const char *name, 1181 1451 const char *expected) … … 1200 1470 1201 1471 if (unlikely(ptr == NULL)) { 1202 talloc_abort_type_mis smatch(location, NULL, name);1472 talloc_abort_type_mismatch(location, NULL, name); 1203 1473 return NULL; 1204 1474 } 1205 1475 1206 pname = talloc_get_name(ptr);1476 pname = __talloc_get_name(ptr); 1207 1477 if (likely(pname == name || strcmp(pname, name) == 0)) { 1208 1478 return discard_const_p(void, ptr); 1209 1479 } 1210 1480 1211 talloc_abort_type_mis smatch(location, pname, name);1481 talloc_abort_type_mismatch(location, pname, name); 1212 1482 return NULL; 1213 1483 } … … 1249 1519 void *child = TC_PTR_FROM_CHUNK(tc->child); 1250 1520 const void *new_parent = null_context; 1251 struct talloc_chunk *old_parent = NULL;1252 1521 if (unlikely(tc->child->refs)) { 1253 1522 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs); … … 1255 1524 } 1256 1525 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 } 1257 1533 if (new_parent == null_context) { 1258 1534 struct talloc_chunk *p = talloc_parent_chunk(ptr); … … 1305 1581 } 1306 1582 1307 /* 1583 /* 1308 1584 Allocate a bit of memory as a child of an existing pointer 1309 1585 */ … … 1331 1607 } 1332 1608 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 1335 1611 pointer recursively 1336 1612 … … 1346 1622 return -1; 1347 1623 } 1348 1624 1349 1625 tc = talloc_chunk_from_ptr(ptr); 1350 1626 1351 1627 if (unlikely(tc->refs != NULL)) { 1352 1628 struct talloc_reference_handle *h; … … 1368 1644 return -1; 1369 1645 } 1370 1646 1371 1647 return _talloc_free_internal(ptr, location); 1372 1648 } … … 1383 1659 void *new_ptr; 1384 1660 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; 1386 1664 1387 1665 /* size zero is equivalent to free() */ … … 1412 1690 } 1413 1691 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 */ 1415 1700 if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) { 1416 pool_ tc = (struct talloc_chunk *)tc->pool;1701 pool_hdr = tc->pool; 1417 1702 } 1418 1703 1419 1704 #if (ALWAYS_REALLOC == 0) 1420 1705 /* 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); 1424 1709 TC_INVALIDATE_SHRINK_CHUNK(tc, size); 1425 1710 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); 1428 1714 } 1429 1715 return ptr; … … 1456 1742 1457 1743 #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--; 1461 1747 1462 1748 if (new_ptr == NULL) { 1463 1749 new_ptr = malloc(TC_HDR_SIZE+size); 1464 1750 malloced = true; 1751 new_size = size; 1465 1752 } 1466 1753 … … 1470 1757 } 1471 1758 } else { 1759 /* We're doing malloc then free here, so record the difference. */ 1760 old_size = tc->size; 1761 new_size = size; 1472 1762 new_ptr = malloc(size + TC_HDR_SIZE); 1473 1763 if (new_ptr) { … … 1477 1767 } 1478 1768 #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); 1482 1773 size_t new_chunk_size = TC_ALIGN16(TC_HDR_SIZE + size); 1483 1774 size_t space_needed; 1484 1775 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); 1487 1779 if (!(pool_tc->flags & TALLOC_FLAG_FREE)) { 1488 1780 chunk_count -= 1; … … 1494 1786 * chunk in the pool. 1495 1787 */ 1788 char *start = tc_pool_first_chunk(pool_hdr); 1496 1789 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; 1498 1791 1499 1792 if (space_left >= space_needed) { 1500 1793 size_t old_used = TC_HDR_SIZE + tc->size; 1501 1794 size_t new_used = TC_HDR_SIZE + size; 1502 pool_tc->pool = TC_POOL_FIRST_CHUNK(pool_tc); 1795 new_ptr = start; 1796 1503 1797 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) 1504 /*1505 * we need to prepare the memmove into1506 * the unaccessable area.1507 */1508 1798 { 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); 1513 1814 } 1514 1815 #endif 1515 memmove(pool_tc->pool, tc, old_used); 1516 new_ptr = pool_tc->pool;1816 1817 memmove(new_ptr, tc, old_used); 1517 1818 1518 1819 tc = (struct talloc_chunk *)new_ptr; … … 1524 1825 * too. 1525 1826 */ 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); 1528 1829 1529 1830 /* now the aligned pointer */ 1530 pool_ tc->pool= new_chunk_size + (char *)new_ptr;1831 pool_hdr->end = new_chunk_size + (char *)new_ptr; 1531 1832 goto got_new_ptr; 1532 1833 } … … 1542 1843 } 1543 1844 1544 if (next_tc == pool_ tc->pool) {1845 if (next_tc == pool_hdr->end) { 1545 1846 /* 1546 1847 * optimize for the case where 'tc' is the last … … 1548 1849 */ 1549 1850 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); 1551 1852 1552 1853 if (space_left >= space_needed) { … … 1554 1855 tc->flags &= ~TALLOC_FLAG_FREE; 1555 1856 tc->size = size; 1556 pool_ tc->pool = TC_POOLMEM_NEXT_CHUNK(tc);1857 pool_hdr->end = tc_next_chunk(tc); 1557 1858 return ptr; 1558 1859 } 1559 1860 } 1560 1861 1561 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE );1862 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE, 0); 1562 1863 1563 1864 if (new_ptr == NULL) { 1564 1865 new_ptr = malloc(TC_HDR_SIZE+size); 1565 1866 malloced = true; 1867 new_size = size; 1566 1868 } 1567 1869 … … 1573 1875 } 1574 1876 else { 1877 /* We're doing realloc here, so record the difference. */ 1878 old_size = tc->size; 1879 new_size = size; 1575 1880 new_ptr = realloc(tc, size + TC_HDR_SIZE); 1576 1881 } 1577 1882 got_new_ptr: 1578 1883 #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; 1582 1887 } 1583 1888 … … 1601 1906 } 1602 1907 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 1603 1914 tc->size = size; 1604 1915 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name); … … 1619 1930 } 1620 1931 1621 /* 1622 return the total size of a talloc pool (subtree) 1623 */ 1624 _PUBLIC_ size_t talloc_total_size(const void *ptr) 1932 enum talloc_mem_count_type { 1933 TOTAL_MEM_SIZE, 1934 TOTAL_MEM_BLOCKS, 1935 TOTAL_MEM_LIMIT, 1936 }; 1937 1938 static 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) 1625 1942 { 1626 1943 size_t total = 0; … … 1636 1953 tc = talloc_chunk_from_ptr(ptr); 1637 1954 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 1638 1969 if (tc->flags & TALLOC_FLAG_LOOP) { 1639 1970 return 0; … … 1642 1973 tc->flags |= TALLOC_FLAG_LOOP; 1643 1974 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); 1649 2020 } 1650 2021 … … 1655 2026 1656 2027 /* 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 /* 1657 2036 return the total number of blocks in a talloc pool (subtree) 1658 2037 */ 1659 2038 _PUBLIC_ size_t talloc_total_blocks(const void *ptr) 1660 2039 { 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); 1687 2041 } 1688 2042 … … 1745 2099 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f) 1746 2100 { 1747 const char *name = talloc_get_name(ptr); 2101 const char *name = __talloc_get_name(ptr); 2102 struct talloc_chunk *tc; 1748 2103 FILE *f = (FILE *)_f; 1749 2104 … … 1753 2108 } 1754 2109 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 1755 2120 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", 1757 2122 (max_depth < 0 ? "full " :""), name, 1758 2123 (unsigned long)talloc_total_size(ptr), … … 1761 2126 } 1762 2127 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", 1764 2129 depth*4, "", 1765 2130 name, … … 1900 2265 } 1901 2266 1902 /* 1903 talloc and zero memory. 2267 /* 2268 talloc and zero memory. 1904 2269 */ 1905 2270 _PUBLIC_ void *_talloc_zero(const void *ctx, size_t size, const char *name) … … 1915 2280 1916 2281 /* 1917 memdup with a talloc. 2282 memdup with a talloc. 1918 2283 */ 1919 2284 _PUBLIC_ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name) … … 2022 2387 { 2023 2388 if (unlikely(!s)) { 2024 return talloc_str dup(NULL, a);2389 return talloc_strndup(NULL, a, n); 2025 2390 } 2026 2391 … … 2041 2406 2042 2407 if (unlikely(!s)) { 2043 return talloc_str dup(NULL, a);2408 return talloc_strndup(NULL, a, n); 2044 2409 } 2045 2410 … … 2069 2434 char *ret; 2070 2435 va_list ap2; 2071 char c;2436 char buf[1024]; 2072 2437 2073 2438 /* this call looks strange, but it makes it work on older solaris boxes */ 2074 2439 va_copy(ap2, ap); 2075 len = vsnprintf( &c, 1, fmt, ap2);2440 len = vsnprintf(buf, sizeof(buf), fmt, ap2); 2076 2441 va_end(ap2); 2077 2442 if (unlikely(len < 0)) { … … 2082 2447 if (unlikely(!ret)) return NULL; 2083 2448 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 } 2087 2456 2088 2457 _talloc_set_name_const(ret, ret); … … 2330 2699 2331 2700 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)); 2333 2702 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))); 2335 2704 while (tc && tc->prev) tc = tc->prev; 2336 2705 if (tc) { … … 2353 2722 2354 2723 tc = talloc_chunk_from_ptr(context); 2355 while (tc && depth > 0) { 2724 while (tc) { 2725 if (depth <= 0) { 2726 return 0; 2727 } 2356 2728 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1; 2357 2729 while (tc && tc->prev) tc = tc->prev; … … 2371 2743 return _talloc_is_parent(context, ptr, TALLOC_MAX_DEPTH); 2372 2744 } 2745 2746 /* 2747 return the total size of memory used by this context and all children 2748 */ 2749 static 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 2757 static 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 */ 2775 static 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 */ 2822 static 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 */ 2840 static 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 1 1 #ifndef _TALLOC_H_ 2 2 #define _TALLOC_H_ 3 /* 3 /* 4 4 Unix SMB/CIFS implementation. 5 5 Samba temporary memory allocation functions … … 7 7 Copyright (C) Andrew Tridgell 2004-2005 8 8 Copyright (C) Stefan Metzmacher 2006 9 9 10 10 ** NOTE! The following LGPL license applies to the talloc 11 11 ** library. This does NOT imply that all of Samba is released 12 12 ** under the LGPL 13 13 14 14 This library is free software; you can redistribute it and/or 15 15 modify it under the terms of the GNU Lesser General Public … … 48 48 int talloc_version_major(void); 49 49 int talloc_version_minor(void); 50 /* This is mostly useful only for testing */ 51 int talloc_test_get_magic(void); 50 52 51 53 /** … … 194 196 * talloc_set_log_stderr() for more information on talloc logging 195 197 * 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. 196 203 * 197 204 * talloc_free() operates recursively on its children. … … 745 752 * 746 753 * This macro is used together with talloc(mem_ctx, struct foo). If you had to 747 * assi ngthe talloc chunk pointer to some void pointer variable,754 * assign the talloc chunk pointer to some void pointer variable, 748 755 * talloc_get_type_abort() is the recommended way to get the convert the void 749 756 * pointer back to a typed pointer. … … 757 764 void *talloc_get_type_abort(const void *ptr, #type); 758 765 #else 766 #ifdef TALLOC_GET_TYPE_ABORT_NOOP 767 #define talloc_get_type_abort(ptr, type) (type *)(ptr) 768 #else 759 769 #define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__) 770 #endif 760 771 void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location); 761 772 #endif … … 823 834 * grand-children, their memory is also taken from the talloc pool. 824 835 * 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 * 825 840 * If you talloc_free() children of a talloc pool, the memory is not given 826 841 * back to the system. Instead, free(3) is only called if the talloc_pool() … … 839 854 void *talloc_pool(const void *context, size_t size); 840 855 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 */ 876 void *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)) 886 void *_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 841 893 /** 842 894 * @brief Free a talloc chunk and NULL out the pointer. … … 848 900 * @param[in] ctx The chunk to be freed. 849 901 */ 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) 851 903 852 904 /* @} ******************************************************************/ … … 915 967 * @return The original pointer 'ptr', NULL if talloc ran out of 916 968 * 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. 917 973 * 918 974 * Example: … … 955 1011 * this function will fail and will return -1. Likewise, if ptr is NULL, 956 1012 * 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. 957 1017 * 958 1018 * Example: … … 1291 1351 1292 1352 /** 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. 1294 1366 * 1295 1367 * @param[in] s The destination to append to. … … 1297 1369 * @param[in] a The string you want to append. 1298 1370 * 1299 * @return The duplicated string, NULL on error.1371 * @return The concatenated strings, NULL on error. 1300 1372 * 1301 1373 * @see talloc_strdup() 1374 * @see talloc_strdup_append_buffer() 1302 1375 */ 1303 1376 char *talloc_strdup_append(char *s, const char *a); 1304 1377 1305 1378 /** 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. 1307 1401 * 1308 1402 * @param[in] s The destination buffer to append to. … … 1310 1404 * @param[in] a The string you want to append. 1311 1405 * 1312 * @return The duplicated string, NULL on error.1406 * @return The concatenated strings, NULL on error. 1313 1407 * 1314 1408 * @see talloc_strdup() 1409 * @see talloc_strdup_append() 1410 * @see talloc_array_length() 1315 1411 */ 1316 1412 char *talloc_strdup_append_buffer(char *s, const char *a); … … 1339 1435 1340 1436 /** 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. 1343 1450 * 1344 1451 * @param[in] s The destination string to append to. … … 1349 1456 * string. 1350 1457 * 1351 * @return The duplicated string, NULL on error.1458 * @return The concatenated strings, NULL on error. 1352 1459 * 1353 1460 * @see talloc_strndup() 1461 * @see talloc_strndup_append_buffer() 1354 1462 */ 1355 1463 char *talloc_strndup_append(char *s, const char *a, size_t n); 1356 1464 1357 1465 /** 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. 1360 1488 * 1361 1489 * @param[in] s The destination buffer to append to. … … 1366 1494 * string. 1367 1495 * 1368 * @return The duplicated string, NULL on error.1496 * @return The concatenated strings, NULL on error. 1369 1497 * 1370 1498 * @see talloc_strndup() 1499 * @see talloc_strndup_append() 1500 * @see talloc_array_length() 1371 1501 */ 1372 1502 char *talloc_strndup_append_buffer(char *s, const char *a, size_t n); … … 1463 1593 * @endcode 1464 1594 * 1595 * If <code>s == NULL</code> then new context is created. 1596 * 1465 1597 * @param[in] s The string to append to. 1466 1598 * … … 1476 1608 * @brief Append a formatted string to another string. 1477 1609 * 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 * 1478 1631 * @param[in] s The string to append to 1479 1632 * … … 1483 1636 * 1484 1637 * @return The formatted string, NULL on error. 1638 * 1639 * @see talloc_asprintf() 1640 * @see talloc_asprintf_append() 1485 1641 */ 1486 1642 char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); … … 1686 1842 void talloc_enable_leak_report_full(void); 1687 1843 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 */ 1875 void 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 */ 1885 void 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 */ 1893 void 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 */ 1912 int talloc_set_memlimit(const void *ctx, size_t max_size); 1913 1688 1914 /* @} ******************************************************************/ 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);1693 1915 1694 1916 #if TALLOC_DEPRECATED -
vendor/current/lib/talloc/talloc_guide.txt
r746 r988 70 70 parent context implicitly refers to a hidden "null context" global 71 71 variable, so this should not be used in a multi-threaded environment 72 without proper synchronization ; 72 without proper synchronization. In threaded code turn off null tracking using 73 talloc_disable_null_tracking(). ; 73 74 - the context returned by talloc_autofree_context() is also global so 74 75 shouldn't be used by several threads simultaneously without … … 195 196 196 197 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 197 int talloc_unlink(const void *context, constvoid *ptr);198 int talloc_unlink(const void *context, void *ptr); 198 199 199 200 The talloc_unlink() function removes a specific parent from ptr. The -
vendor/current/lib/talloc/testsuite.c
r746 r988 28 28 #include <talloc.h> 29 29 30 #ifdef HAVE_PTHREAD 31 #include <pthread.h> 32 #endif 33 34 #include <unistd.h> 35 #include <sys/wait.h> 36 30 37 #include "talloc_testsuite.h" 31 38 … … 57 64 return false; \ 58 65 } 59 60 #if _SAMBA_BUILD_==361 #ifdef malloc62 #undef malloc63 #endif64 #ifdef strdup65 #undef strdup66 #endif67 #endif68 66 69 67 #define CHECK_SIZE(test, ptr, tsize) do { \ … … 151 149 CHECK_BLOCKS("ref1", p1, 5); 152 150 CHECK_BLOCKS("ref1", p2, 1); 151 CHECK_BLOCKS("ref1", ref, 1); 153 152 CHECK_BLOCKS("ref1", r1, 2); 154 153 … … 259 258 CHECK_BLOCKS("ref3", p2, 2); 260 259 CHECK_BLOCKS("ref3", r1, 1); 260 CHECK_BLOCKS("ref3", ref, 1); 261 261 262 262 fprintf(stderr, "Freeing p1\n"); … … 301 301 CHECK_BLOCKS("ref4", p1, 5); 302 302 CHECK_BLOCKS("ref4", p2, 1); 303 CHECK_BLOCKS("ref4", ref, 1); 303 304 CHECK_BLOCKS("ref4", r1, 2); 304 305 … … 351 352 CHECK_BLOCKS("unlink", p1, 7); 352 353 CHECK_BLOCKS("unlink", p2, 1); 354 CHECK_BLOCKS("unlink", ref, 1); 353 355 CHECK_BLOCKS("unlink", r1, 2); 354 356 … … 419 421 torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo", 420 422 "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)"); 421 425 CHECK_BLOCKS("misc", p1, 2); 422 426 CHECK_BLOCKS("misc", root, 3); … … 627 631 el2 = talloc(el1->list2, struct el2); 628 632 el2 = talloc(el1->list3, struct el2); 633 (void)el2; 629 634 630 635 el1->list = talloc_realloc(el1, el1->list, struct el2 *, 100); … … 839 844 p2 = talloc_strdup(p1, "foo bar"); 840 845 p3 = talloc_size(p1, 300); 846 (void)p2; 847 (void)p3; 841 848 talloc_free(p1); 842 849 } … … 858 865 p2 = talloc_strdup(p1, "foo bar"); 859 866 p3 = talloc_size(p1, 300); 860 talloc_free_children(ctx); 867 (void)p2; 868 (void)p3; 869 talloc_free(p1); 861 870 } 862 871 count += 3 * loop; … … 980 989 } 981 990 991 struct new_parent { 992 void *new_parent; 993 char val[20]; 994 }; 995 996 static 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 1003 static 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 1033 static 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 982 1069 static bool test_talloc_ptrtype(void) 983 1070 { … … 1277 1364 } 1278 1365 1366 static 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 1390 struct pooled { 1391 char *s1; 1392 char *s2; 1393 char *s3; 1394 }; 1395 1396 static 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 1279 1424 static bool test_free_ref_null_context(void) 1280 1425 { … … 1325 1470 { 1326 1471 void *root; 1327 const char *p1, *p2, *name, *name2; 1472 char *p1, *p2; 1473 const char *name, *name2; 1328 1474 1329 1475 talloc_enable_null_tracking(); … … 1331 1477 p1 = talloc_strdup(root, "foo1"); 1332 1478 p2 = talloc_strdup(p1, "foo2"); 1479 (void)p2; 1333 1480 1334 1481 talloc_set_name(p1, "%s", "testname"); … … 1355 1502 /* but this does */ 1356 1503 talloc_free_children(p1); 1504 (void)name2; 1357 1505 torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname2") == 0, 1358 1506 "wrong name"); … … 1364 1512 } 1365 1513 1514 static 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. */ 1716 static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; 1717 static pthread_cond_t condvar = PTHREAD_COND_INITIALIZER; 1718 static void *intermediate_ptr; 1719 1720 /* Subthread. */ 1721 static 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. */ 1770 static 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 1858 static 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 1868 static 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 } 1366 1921 1367 1922 static void test_reset(void) … … 1380 1935 1381 1936 test_reset(); 1937 ret &= test_pooled_object(); 1938 test_reset(); 1939 ret &= test_pool_nest(); 1940 test_reset(); 1382 1941 ret &= test_ref1(); 1383 1942 test_reset(); … … 1412 1971 ret &= test_free_parent_deny_child(); 1413 1972 test_reset(); 1973 ret &= test_free_parent_reparent_child(); 1974 test_reset(); 1975 ret &= test_free_parent_reparent_child_in_pool(); 1976 test_reset(); 1414 1977 ret &= test_talloc_ptrtype(); 1415 1978 test_reset(); … … 1425 1988 test_reset(); 1426 1989 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 1427 1997 1428 1998 if (ret) { … … 1432 2002 test_reset(); 1433 2003 ret &= test_autofree(); 2004 test_reset(); 2005 ret &= test_magic_protection(); 1434 2006 1435 2007 test_reset(); -
vendor/current/lib/talloc/wscript
r740 r988 2 2 3 3 APPNAME = 'talloc' 4 VERSION = '2. 0.5'4 VERSION = '2.1.6' 5 5 6 6 … … 13 13 srcdir = '.' 14 14 while not os.path.exists(srcdir+'/buildtools') and len(srcdir.split('/')) < 5: 15 srcdir = '../' + srcdir15 srcdir = srcdir + '/..' 16 16 sys.path.insert(0, srcdir + '/buildtools/wafsamba') 17 17 … … 21 21 22 22 # setup what directories to put in a tarball 23 samba_dist.DIST_DIRS('lib/talloc:. lib/replace:lib/replace buildtools:buildtools') 23 samba_dist.DIST_DIRS("""lib/talloc:. lib/replace:lib/replace 24 buildtools:buildtools third_party/waf:third_party/waf""") 24 25 25 26 … … 28 29 opt.PRIVATE_EXTENSION_DEFAULT('talloc', noextension='talloc') 29 30 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)33 31 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) 34 35 opt.add_option('--disable-python', 35 36 help=("disable the pytalloc module"), … … 45 46 46 47 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, 48 49 implied_deps='replace'): 49 50 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, 51 52 implied_deps='talloc replace'): 52 53 conf.define('USING_SYSTEM_PYTALLOC_UTIL', 1) 53 54 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 55 58 56 59 conf.CHECK_XSLTPROC_MANPAGES() … … 58 61 if not conf.env.disable_python: 59 62 # 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)) 62 64 conf.SAMBA_CHECK_PYTHON_HEADERS(mandatory=False) 63 65 if not conf.env.HAVE_PYTHON_H: … … 65 67 conf.env.disable_python = True 66 68 69 conf.CHECK_HEADERS('sys/auxv.h') 70 conf.CHECK_FUNCS('getauxval') 71 67 72 conf.SAMBA_CONFIG_H() 73 74 conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS() 68 75 69 76 … … 74 81 bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' 75 82 bld.env.TALLOC_VERSION = VERSION 76 bld.PKG_CONFIG_FILES('talloc.pc', vnum=VERSION)77 83 private_library = False 78 84 … … 82 88 public_deps='talloc', 83 89 soname='libtalloc.so.1', 90 pc_files=[], 91 public_headers=[], 84 92 enabled=bld.env.TALLOC_COMPAT1) 85 93 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 88 107 else: 89 108 private_library = True … … 98 117 hide_symbols=True, 99 118 vnum=VERSION, 100 public_headers='talloc.h', 119 public_headers=('' if private_library else 'talloc.h'), 120 pc_files='talloc.pc', 101 121 public_headers_install=not private_library, 102 122 private_library=private_library, 103 manpages=' talloc.3')123 manpages='man/talloc.3') 104 124 105 125 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') 106 128 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') 120 146 121 if not getattr(bld.env, '_SAMBA_BUILD_', 0) == 4:122 # s4 already has the talloc testsuite builtin to smbtorture123 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) 127 153 128 154 … … 133 159 ret = samba_utils.RUN_COMMAND(cmd) 134 160 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) 136 170 137 171 def dist():
Note:
See TracChangeset
for help on using the changeset viewer.