1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | /*++ |
6 | |
7 | |
8 | |
9 | Module Name: |
10 | |
11 | stringtls.cpp |
12 | |
13 | Abstract: |
14 | |
15 | Implementation of the string functions in the C runtime library that |
16 | are Windows specific and depend on per-thread data |
17 | |
18 | |
19 | |
20 | --*/ |
21 | |
22 | #include "pal/thread.hpp" |
23 | #include "pal/dbgmsg.h" |
24 | |
25 | #include <string.h> |
26 | #include <ctype.h> |
27 | #include <pthread.h> |
28 | #include <limits.h> |
29 | #include <unistd.h> |
30 | |
31 | using namespace CorUnix; |
32 | |
33 | SET_DEFAULT_DEBUG_CHANNEL(CRT); |
34 | |
35 | /*++ |
36 | Function: |
37 | PAL_strtok |
38 | |
39 | Finds the next token in a string. |
40 | |
41 | Return value: |
42 | |
43 | A pointer to the next token found in strToken. Returns NULL when no more |
44 | tokens are found. Each call modifies strToken by substituting a NULL |
45 | character for each delimiter that is encountered. |
46 | |
47 | Parameters: |
48 | strToken String cotaining token(s) |
49 | strDelimit Set of delimiter characters |
50 | |
51 | Remarks: |
52 | In FreeBSD, strtok is not re-entrant, strtok_r is. It manages re-entrancy |
53 | by using a passed-in context pointer (which will be stored in thread local |
54 | storage) According to the strtok MSDN documentation, "Calling these functions |
55 | simultaneously from multiple threads does not have undesirable effects", so |
56 | we need to use strtok_r. |
57 | --*/ |
58 | char * |
59 | __cdecl |
60 | PAL_strtok(char *strToken, const char *strDelimit) |
61 | { |
62 | CPalThread *pThread = NULL; |
63 | char *retval=NULL; |
64 | |
65 | PERF_ENTRY(strtok); |
66 | ENTRY("strtok (strToken=%p (%s), strDelimit=%p (%s))\n" , |
67 | strToken?strToken:"NULL" , |
68 | strToken?strToken:"NULL" , strDelimit?strDelimit:"NULL" , strDelimit?strDelimit:"NULL" ); |
69 | |
70 | pThread = InternalGetCurrentThread(); |
71 | |
72 | retval = strtok_r(strToken, strDelimit, &pThread->crtInfo.strtokContext); |
73 | |
74 | LOGEXIT("strtok returns %p (%s)\n" , retval?retval:"NULL" , retval?retval:"NULL" ); |
75 | PERF_EXIT(strtok); |
76 | |
77 | return retval; |
78 | } |
79 | |