unix/SysUtilities.cpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2010 Rexx Language Association. All rights reserved. */
5 /* */
6 /* This program and the accompanying materials are made available under */
7 /* the terms of the Common Public License v1.0 which accompanies this */
8 /* distribution. A copy is also available at the following address: */
9 /* http://www.oorexx.org/license.html */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 /****************************************************************************/
39 /* REXX Kernel */
40 /* */
41 /* Utility Functions */
42 /* */
43 /****************************************************************************/
44 
45 #include <stdio.h>
46 #include "Utilities.hpp"
47 
48 /**
49  * Encapsulation of vsnprintf Unix implementation.
50  * The goal is to have the same behavior on all platforms.
51  *
52  * @param buffer Buffer receiving the formated output.
53  * @param size Size of buffer.
54  * @param format Format string.
55  * @param args Pointer to optional arguments
56  *
57  * @return Upon successful completion, return the number of bytes stored in buffer, not counting the terminating null character
58  * or a negative value if an error was encountered.
59  */
60 int Utilities::vsnprintf(char *buffer, size_t count, const char *format, va_list args)
61 {
62  /*
63  http://linux.die.net/man/3/snprintf
64 
65  Return value
66  Upon successful return, return the number of characters printed (not including the trailing '\0' used to end output to strings).
67  The functions snprintf() do not write more than size bytes (including the trailing '\0').
68  If the output was truncated due to this limit then the return value is the number of characters (not including the trailing '\0') which would have been written to the final string if enough space had been available.
69  Thus, a return value of size or more means that the output was truncated. (See also below under NOTES.)
70  If an output error is encountered, a negative value is returned.
71 
72  Conforming To
73  The snprintf() function conform to C99.
74  Concerning the return value of snprintf(), SUSv2 and C99 contradict each other:
75  when snprintf() is called with size=0 then SUSv2 stipulates an unspecified return value less than 1,
76  while C99 allows str to be NULL in this case, and gives the return value (as always) as the number of characters that would have been written in case the output string has been large enough.
77 
78  Notes
79  The glibc implementation of the functions snprintf() conforms to the C99 standard, i.e., behaves as described above, since glibc version 2.1.
80  Until glibc 2.0.6 they would return -1 when the output was truncated.
81  */
82 
83  /*
84  vsnprintf behavior, assuming the buffer is 4 bytes :
85  0 1 2 3
86  "x" x \0 return value = 1
87  "xx" x x \0 return value = 2
88  "xxx" x x x \0 return value = 3
89  "xxxx" x x x \0 return value = 4 <-- different from Windows
90  "xxxxx" x x x \0 return value = 5 <-- different from Windows
91  */
92 
93  if (buffer == NULL || count == 0 || format == NULL) return -1;
94  int n = ::vsnprintf(buffer, count, format, args);
95  buffer[count-1] = '\0'; // Normally not needed, but...
96  if (n >= count) n = -1; // The output has been truncated, return -1 to have a common behavior with Windows platform
97  return n;
98 }
99 
100 
101 /**
102  * Encapsulation of snprintf Unix implementation.
103  * The goal is to have the same behavior on all platforms.
104  *
105  * @param buffer Buffer receiving the formated output.
106  * @param size Size of buffer.
107  * @param format Format string.
108  * @param ... Optional arguments
109  *
110  * @return Upon successful completion, return the number of bytes stored in buffer, not counting the terminating null character
111  * or a negative value if an error was encountered.
112  */
113 int Utilities::snprintf(char *buffer, size_t count, const char *format, ...)
114 {
115  va_list args;
116  va_start(args, format);
117  int n = Utilities::vsnprintf(buffer, count, format, args);
118  va_end(args);
119  return n;
120 }
121 
122 
123 // Could be in SysThread.cpp, but for the moment, it's here...
125 {
126  return (wholenumber_t)pthread_self();
127 }
128 
129 
130 // This indicator is used to control the display of additional informations in the trace output for concurrency.
131 static bool TRACE_CONCURRENCY = false;
132 
134 {
135  TRACE_CONCURRENCY = trace;
136 }
137 
138 
140 {
141  // I don't put this part of code in SystemInterpreter::setupProgram
142  // where RXTRACE is managed, because would be initialized too late :
143  // Some mutexes/semaphores have been already used before calling setupProgram.
144  static bool firstcall = true;
145  if (firstcall)
146  {
147  firstcall = false;
148  const char *rxTraceBuf = getenv("RXTRACE_CONCURRENCY");
149  if (rxTraceBuf != NULL)
150  {
151  if (!Utilities::strCaselessCompare(rxTraceBuf, "ON")) /* request to turn on? */
152  {
153  /* turn on tracing */
155  }
156  }
157  }
158  return TRACE_CONCURRENCY;
159 }
160 
161 
162 // This indicator is used to control the display of additional informations in the trace output while parsing.
163 static bool TRACE_PARSING = false;
164 
165 void Utilities::traceParsing(bool trace)
166 {
167  TRACE_PARSING = trace;
168 }
169 
170 
172 {
173  static bool firstcall = true;
174  if (firstcall)
175  {
176  firstcall = false;
177  const char *rxTraceBuf = getenv("RXTRACE_PARSING");
178  if (rxTraceBuf != NULL)
179  {
180  if (!Utilities::strCaselessCompare(rxTraceBuf, "ON")) /* request to turn on? */
181  {
182  /* turn on tracing */
184  }
185  }
186  }
187  return TRACE_PARSING;
188 }
189 
static wholenumber_t currentThreadId()
static bool traceConcurrency()
static bool traceParsing()
static int strCaselessCompare(const char *opt1, const char *opt2)
Definition: Utilities.cpp:82
static int vsnprintf(char *buffer, size_t count, const char *format, va_list args)
static int snprintf(char *buffer, size_t count, const char *format,...)
ssize_t wholenumber_t
Definition: rexx.h:230
static bool TRACE_PARSING
static bool TRACE_CONCURRENCY