There are a huge list of functions in POSIX which are not safe to use from multiple threads currently. I generated the list by looking at all libc symbol exports for variants which have a parallel _r symbol. nm -D --defined-only /lib/libc.so.6 \ | grep '_r$' \ | awk '{print $3}' \ | grep -v __ \ | grep -v qsort \ | grep -v readdir \ | sort \ | uniq \ | sed -e 's/_r//' The qsort one is a red herring, since you only need qsort_r if you need to pass a extra 'void * opaque' data blob to your sort function - we don't, so don't need qsort_r. The readdir one is also unneccessary, since reading from a single DIR* is safe from a single thread. readdir_r is also horrific http://womble.decadentplace.org.uk/readdir_r-advisory.html This patch adds a 'make sc_prohibit_nonrentrant' rule to the 'syntax-check' for these forbidden functions. .x-sc_prohibit_nonreentrant | 8 ++++ Makefile.am | 2 + Makefile.maint | 11 +++++ Makefile.nonreentrant | 85 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+) Daniel diff --git a/.x-sc_prohibit_nonreentrant b/.x-sc_prohibit_nonreentrant new file mode 100644 --- /dev/null +++ b/.x-sc_prohibit_nonreentrant @@ -0,0 +1,8 @@ +^gnulib/ +^po/ +ChangeLog +^Makefile* +^docs/ +^tests/ +^src/virsh.c +^build-aux/ diff --git a/Makefile.am b/Makefile.am --- a/Makefile.am +++ b/Makefile.am @@ -17,6 +17,8 @@ EXTRA_DIST = \ .x-sc_require_config_h_first \ .x-sc_prohibit_strcmp \ .x-sc_require_config_h \ + .x-sc_prohibit_nonreentrant \ + Makefile.nonreentrant \ autogen.sh man_MANS = virsh.1 diff --git a/Makefile.maint b/Makefile.maint --- a/Makefile.maint +++ b/Makefile.maint @@ -12,6 +12,8 @@ VC_LIST = $(srcdir)/build-aux/vc-list-fi VC_LIST_EXCEPT = \ $(VC_LIST) | if test -f .x-$@; then grep -vEf .x-$@; else grep -v ChangeLog; fi + +include Makefile.nonreentrant # Prevent programs like 'sort' from considering distinct strings to be equal. # Doing it here saves us from having to set LC_ALL elsewhere in this file. @@ -110,6 +112,15 @@ sc_prohibit_asprintf: sc_prohibit_asprintf: @grep -nE '\<[a]sprintf\>' $$($(VC_LIST_EXCEPT)) && \ { echo '$(ME): use virAsprintf, not a'sprintf 1>&2; exit 1; } || : + +sc_prohibit_nonreentrant: + @fail=0 ; \ + for i in $(NON_REENTRANT) ; \ + do \ + grep -nE "\<$$i\>[:space:]*\(" $$($(VC_LIST_EXCEPT)) && \ + fail=1 && echo "$(ME): use $${i}_r, not $${i}" || : ; \ + done ; \ + exit $$fail # Using EXIT_SUCCESS as the first argument to error is misleading, # since when that parameter is 0, error does not exit. Use `0' instead. diff --git a/Makefile.nonreentrant b/Makefile.nonreentrant new file mode 100644 --- /dev/null +++ b/Makefile.nonreentrant @@ -0,0 +1,85 @@ + +# +# Generated by running the following on Fedora 9: +# +# nm -D --defined-only /lib/libc.so.6 \ +# | grep '_r$' \ +# | awk '{print $3}' \ +# | grep -v __ \ +# | grep -v qsort \ # Red herring since we don't need to pass extra args to qsort comparator +# | grep -v readdir \ # This is safe as long as each DIR * instance is only used by one thread +# | sort \ +# | uniq \ +# | sed -e 's/_r//' +# + +NON_REENTRANT = +NON_REENTRANT += asctime +NON_REENTRANT += ctime +NON_REENTRANT += drand48 +NON_REENTRANT += ecvt +NON_REENTRANT += erand48 +NON_REENTRANT += ether_aton +NON_REENTRANT += ether_ntoa +NON_REENTRANT += fcvt +NON_REENTRANT += fgetgrent +NON_REENTRANT += fgetpwent +NON_REENTRANT += fgetspent +NON_REENTRANT += getaliasbyname +NON_REENTRANT += getaliasent +NON_REENTRANT += getdate +NON_REENTRANT += getgrent +NON_REENTRANT += getgrgid +NON_REENTRANT += getgrnam +NON_REENTRANT += gethostbyaddr +NON_REENTRANT += gethostbyname2 +NON_REENTRANT += gethostbyname +NON_REENTRANT += gethostent +NON_REENTRANT += getlogin +NON_REENTRANT += getmntent +NON_REENTRANT += getnetbyaddr +NON_REENTRANT += getnetbyname +NON_REENTRANT += getnetent +NON_REENTRANT += getnetgrent +NON_REENTRANT += getprotobyname +NON_REENTRANT += getprotobynumber +NON_REENTRANT += getprotoent +NON_REENTRANT += getpwent +NON_REENTRANT += getpwnam +NON_REENTRANT += getpwuid +NON_REENTRANT += getrpcbyname +NON_REENTRANT += getrpcbynumber +NON_REENTRANT += getrpcent +NON_REENTRANT += getservbyname +NON_REENTRANT += getservbyport +NON_REENTRANT += getservent +NON_REENTRANT += getspent +NON_REENTRANT += getspnam +NON_REENTRANT += getutent +NON_REENTRANT += getutid +NON_REENTRANT += getutline +NON_REENTRANT += gmtime +NON_REENTRANT += hcreate +NON_REENTRANT += hdestroy +NON_REENTRANT += hsearch +NON_REENTRANT += initstate +NON_REENTRANT += jrand48 +NON_REENTRANT += lcong48 +NON_REENTRANT += localtime +NON_REENTRANT += lrand48 +NON_REENTRANT += mrand48 +NON_REENTRANT += nrand48 +NON_REENTRANT += ptsname +NON_REENTRANT += qecvt +NON_REENTRANT += qfcvt +NON_REENTRANT += random +NON_REENTRANT += rand +NON_REENTRANT += seed48 +NON_REENTRANT += setstate +NON_REENTRANT += sgetspent +NON_REENTRANT += srand48 +NON_REENTRANT += srandom +NON_REENTRANT += strerror +NON_REENTRANT += strtok +NON_REENTRANT += tmpnam +NON_REENTRANT += ttyname -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list