1  /*
2   * OS specific functions
3   * Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
4   *
5   * This software may be distributed under the terms of the BSD license.
6   * See README for more details.
7   */
8  
9  #ifndef OS_H
10  #define OS_H
11  
12  typedef long os_time_t;
13  
14  /**
15   * os_sleep - Sleep (sec, usec)
16   * @sec: Number of seconds to sleep
17   * @usec: Number of microseconds to sleep
18   */
19  void os_sleep(os_time_t sec, os_time_t usec);
20  
21  struct os_time {
22  	os_time_t sec;
23  	os_time_t usec;
24  };
25  
26  struct os_reltime {
27  	os_time_t sec;
28  	os_time_t usec;
29  };
30  
31  /**
32   * os_get_time - Get current time (sec, usec)
33   * @t: Pointer to buffer for the time
34   * Returns: 0 on success, -1 on failure
35   */
36  int os_get_time(struct os_time *t);
37  
38  /**
39   * os_get_reltime - Get relative time (sec, usec)
40   * @t: Pointer to buffer for the time
41   * Returns: 0 on success, -1 on failure
42   */
43  int os_get_reltime(struct os_reltime *t);
44  
45  
46  /* Helpers for handling struct os_time */
47  
os_time_before(struct os_time * a,struct os_time * b)48  static inline int os_time_before(struct os_time *a, struct os_time *b)
49  {
50  	return (a->sec < b->sec) ||
51  	       (a->sec == b->sec && a->usec < b->usec);
52  }
53  
54  
os_time_sub(struct os_time * a,struct os_time * b,struct os_time * res)55  static inline void os_time_sub(struct os_time *a, struct os_time *b,
56  			       struct os_time *res)
57  {
58  	res->sec = a->sec - b->sec;
59  	res->usec = a->usec - b->usec;
60  	if (res->usec < 0) {
61  		res->sec--;
62  		res->usec += 1000000;
63  	}
64  }
65  
66  
67  /* Helpers for handling struct os_reltime */
68  
os_reltime_before(struct os_reltime * a,struct os_reltime * b)69  static inline int os_reltime_before(struct os_reltime *a,
70  				    struct os_reltime *b)
71  {
72  	return (a->sec < b->sec) ||
73  	       (a->sec == b->sec && a->usec < b->usec);
74  }
75  
76  
os_reltime_sub(struct os_reltime * a,struct os_reltime * b,struct os_reltime * res)77  static inline void os_reltime_sub(struct os_reltime *a, struct os_reltime *b,
78  				  struct os_reltime *res)
79  {
80  	res->sec = a->sec - b->sec;
81  	res->usec = a->usec - b->usec;
82  	if (res->usec < 0) {
83  		res->sec--;
84  		res->usec += 1000000;
85  	}
86  }
87  
88  
os_reltime_age(struct os_reltime * start,struct os_reltime * age)89  static inline void os_reltime_age(struct os_reltime *start,
90  				  struct os_reltime *age)
91  {
92  	struct os_reltime now;
93  
94  	os_get_reltime(&now);
95  	os_reltime_sub(&now, start, age);
96  }
97  
98  
os_reltime_expired(struct os_reltime * now,struct os_reltime * ts,os_time_t timeout_secs)99  static inline int os_reltime_expired(struct os_reltime *now,
100  				     struct os_reltime *ts,
101  				     os_time_t timeout_secs)
102  {
103  	struct os_reltime age;
104  
105  	os_reltime_sub(now, ts, &age);
106  	return (age.sec > timeout_secs) ||
107  	       (age.sec == timeout_secs && age.usec > 0);
108  }
109  
110  
os_reltime_add_ms(struct os_reltime * ts,int ms)111  static inline void os_reltime_add_ms(struct os_reltime *ts, int ms)
112  {
113  	ts->usec += ms * 1000;
114  	while (ts->usec >= 1000000) {
115  		ts->sec++;
116  		ts->usec -= 1000000;
117  	}
118  	while (ts->usec < 0) {
119  		ts->sec--;
120  		ts->usec += 1000000;
121  	}
122  }
123  
124  
os_reltime_in_ms(struct os_reltime * ts)125  static inline int os_reltime_in_ms(struct os_reltime *ts)
126  {
127  	return ts->sec * 1000 + ts->usec / 1000;
128  }
129  
130  
os_reltime_initialized(struct os_reltime * t)131  static inline int os_reltime_initialized(struct os_reltime *t)
132  {
133  	return t->sec != 0 || t->usec != 0;
134  }
135  
136  
137  /**
138   * os_mktime - Convert broken-down time into seconds since 1970-01-01
139   * @year: Four digit year
140   * @month: Month (1 .. 12)
141   * @day: Day of month (1 .. 31)
142   * @hour: Hour (0 .. 23)
143   * @min: Minute (0 .. 59)
144   * @sec: Second (0 .. 60)
145   * @t: Buffer for returning calendar time representation (seconds since
146   * 1970-01-01 00:00:00)
147   * Returns: 0 on success, -1 on failure
148   *
149   * Note: The result is in seconds from Epoch, i.e., in UTC, not in local time
150   * which is used by POSIX mktime().
151   */
152  int os_mktime(int year, int month, int day, int hour, int min, int sec,
153  	      os_time_t *t);
154  
155  struct os_tm {
156  	int sec; /* 0..59 or 60 for leap seconds */
157  	int min; /* 0..59 */
158  	int hour; /* 0..23 */
159  	int day; /* 1..31 */
160  	int month; /* 1..12 */
161  	int year; /* Four digit year */
162  };
163  
164  int os_gmtime(os_time_t t, struct os_tm *tm);
165  
166  /**
167   * os_daemonize - Run in the background (detach from the controlling terminal)
168   * @pid_file: File name to write the process ID to or %NULL to skip this
169   * Returns: 0 on success, -1 on failure
170   */
171  int os_daemonize(const char *pid_file);
172  
173  /**
174   * os_daemonize_terminate - Stop running in the background (remove pid file)
175   * @pid_file: File name to write the process ID to or %NULL to skip this
176   */
177  void os_daemonize_terminate(const char *pid_file);
178  
179  /**
180   * os_get_random - Get cryptographically strong pseudo random data
181   * @buf: Buffer for pseudo random data
182   * @len: Length of the buffer
183   * Returns: 0 on success, -1 on failure
184   */
185  int os_get_random(unsigned char *buf, size_t len);
186  
187  /**
188   * os_random - Get pseudo random value (not necessarily very strong)
189   * Returns: Pseudo random value
190   */
191  unsigned long os_random(void);
192  
193  /**
194   * os_rel2abs_path - Get an absolute path for a file
195   * @rel_path: Relative path to a file
196   * Returns: Absolute path for the file or %NULL on failure
197   *
198   * This function tries to convert a relative path of a file to an absolute path
199   * in order for the file to be found even if current working directory has
200   * changed. The returned value is allocated and caller is responsible for
201   * freeing it. It is acceptable to just return the same path in an allocated
202   * buffer, e.g., return strdup(rel_path). This function is only used to find
203   * configuration files when os_daemonize() may have changed the current working
204   * directory and relative path would be pointing to a different location.
205   */
206  char * os_rel2abs_path(const char *rel_path);
207  
208  /**
209   * os_program_init - Program initialization (called at start)
210   * Returns: 0 on success, -1 on failure
211   *
212   * This function is called when a programs starts. If there are any OS specific
213   * processing that is needed, it can be placed here. It is also acceptable to
214   * just return 0 if not special processing is needed.
215   */
216  int os_program_init(void);
217  
218  /**
219   * os_program_deinit - Program deinitialization (called just before exit)
220   *
221   * This function is called just before a program exists. If there are any OS
222   * specific processing, e.g., freeing resourced allocated in os_program_init(),
223   * it should be done here. It is also acceptable for this function to do
224   * nothing.
225   */
226  void os_program_deinit(void);
227  
228  /**
229   * os_setenv - Set environment variable
230   * @name: Name of the variable
231   * @value: Value to set to the variable
232   * @overwrite: Whether existing variable should be overwritten
233   * Returns: 0 on success, -1 on error
234   *
235   * This function is only used for wpa_cli action scripts. OS wrapper does not
236   * need to implement this if such functionality is not needed.
237   */
238  int os_setenv(const char *name, const char *value, int overwrite);
239  
240  /**
241   * os_unsetenv - Delete environent variable
242   * @name: Name of the variable
243   * Returns: 0 on success, -1 on error
244   *
245   * This function is only used for wpa_cli action scripts. OS wrapper does not
246   * need to implement this if such functionality is not needed.
247   */
248  int os_unsetenv(const char *name);
249  
250  /**
251   * os_readfile - Read a file to an allocated memory buffer
252   * @name: Name of the file to read
253   * @len: For returning the length of the allocated buffer
254   * Returns: Pointer to the allocated buffer or %NULL on failure
255   *
256   * This function allocates memory and reads the given file to this buffer. Both
257   * binary and text files can be read with this function. The caller is
258   * responsible for freeing the returned buffer with os_free().
259   */
260  char * os_readfile(const char *name, size_t *len);
261  
262  /**
263   * os_file_exists - Check whether the specified file exists
264   * @fname: Path and name of the file
265   * Returns: 1 if the file exists or 0 if not
266   */
267  int os_file_exists(const char *fname);
268  
269  /**
270   * os_fdatasync - Sync a file's (for a given stream) state with storage device
271   * @stream: the stream to be flushed
272   * Returns: 0 if the operation succeeded or -1 on failure
273   */
274  int os_fdatasync(FILE *stream);
275  
276  /**
277   * os_zalloc - Allocate and zero memory
278   * @size: Number of bytes to allocate
279   * Returns: Pointer to allocated and zeroed memory or %NULL on failure
280   *
281   * Caller is responsible for freeing the returned buffer with os_free().
282   */
283  void * os_zalloc(size_t size);
284  
285  /**
286   * os_calloc - Allocate and zero memory for an array
287   * @nmemb: Number of members in the array
288   * @size: Number of bytes in each member
289   * Returns: Pointer to allocated and zeroed memory or %NULL on failure
290   *
291   * This function can be used as a wrapper for os_zalloc(nmemb * size) when an
292   * allocation is used for an array. The main benefit over os_zalloc() is in
293   * having an extra check to catch integer overflows in multiplication.
294   *
295   * Caller is responsible for freeing the returned buffer with os_free().
296   */
os_calloc(size_t nmemb,size_t size)297  static inline void * os_calloc(size_t nmemb, size_t size)
298  {
299  	if (size && nmemb > (~(size_t) 0) / size)
300  		return NULL;
301  	return os_zalloc(nmemb * size);
302  }
303  
304  
305  /*
306   * The following functions are wrapper for standard ANSI C or POSIX functions.
307   * By default, they are just defined to use the standard function name and no
308   * os_*.c implementation is needed for them. This avoids extra function calls
309   * by allowing the C pre-processor take care of the function name mapping.
310   *
311   * If the target system uses a C library that does not provide these functions,
312   * build_config.h can be used to define the wrappers to use a different
313   * function name. This can be done on function-by-function basis since the
314   * defines here are only used if build_config.h does not define the os_* name.
315   * If needed, os_*.c file can be used to implement the functions that are not
316   * included in the C library on the target system. Alternatively,
317   * OS_NO_C_LIB_DEFINES can be defined to skip all defines here in which case
318   * these functions need to be implemented in os_*.c file for the target system.
319   */
320  
321  #ifdef OS_NO_C_LIB_DEFINES
322  
323  /**
324   * os_malloc - Allocate dynamic memory
325   * @size: Size of the buffer to allocate
326   * Returns: Allocated buffer or %NULL on failure
327   *
328   * Caller is responsible for freeing the returned buffer with os_free().
329   */
330  void * os_malloc(size_t size);
331  
332  /**
333   * os_realloc - Re-allocate dynamic memory
334   * @ptr: Old buffer from os_malloc() or os_realloc()
335   * @size: Size of the new buffer
336   * Returns: Allocated buffer or %NULL on failure
337   *
338   * Caller is responsible for freeing the returned buffer with os_free().
339   * If re-allocation fails, %NULL is returned and the original buffer (ptr) is
340   * not freed and caller is still responsible for freeing it.
341   */
342  void * os_realloc(void *ptr, size_t size);
343  
344  /**
345   * os_free - Free dynamic memory
346   * @ptr: Old buffer from os_malloc() or os_realloc(); can be %NULL
347   */
348  void os_free(void *ptr);
349  
350  /**
351   * os_memcpy - Copy memory area
352   * @dest: Destination
353   * @src: Source
354   * @n: Number of bytes to copy
355   * Returns: dest
356   *
357   * The memory areas src and dst must not overlap. os_memmove() can be used with
358   * overlapping memory.
359   */
360  void * os_memcpy(void *dest, const void *src, size_t n);
361  
362  /**
363   * os_memmove - Copy memory area
364   * @dest: Destination
365   * @src: Source
366   * @n: Number of bytes to copy
367   * Returns: dest
368   *
369   * The memory areas src and dst may overlap.
370   */
371  void * os_memmove(void *dest, const void *src, size_t n);
372  
373  /**
374   * os_memset - Fill memory with a constant byte
375   * @s: Memory area to be filled
376   * @c: Constant byte
377   * @n: Number of bytes started from s to fill with c
378   * Returns: s
379   */
380  void * os_memset(void *s, int c, size_t n);
381  
382  /**
383   * os_memcmp - Compare memory areas
384   * @s1: First buffer
385   * @s2: Second buffer
386   * @n: Maximum numbers of octets to compare
387   * Returns: An integer less than, equal to, or greater than zero if s1 is
388   * found to be less than, to match, or be greater than s2. Only first n
389   * characters will be compared.
390   */
391  int os_memcmp(const void *s1, const void *s2, size_t n);
392  
393  /**
394   * os_strdup - Duplicate a string
395   * @s: Source string
396   * Returns: Allocated buffer with the string copied into it or %NULL on failure
397   *
398   * Caller is responsible for freeing the returned buffer with os_free().
399   */
400  char * os_strdup(const char *s);
401  
402  /**
403   * os_strlen - Calculate the length of a string
404   * @s: '\0' terminated string
405   * Returns: Number of characters in s (not counting the '\0' terminator)
406   */
407  size_t os_strlen(const char *s);
408  
409  /**
410   * os_strcasecmp - Compare two strings ignoring case
411   * @s1: First string
412   * @s2: Second string
413   * Returns: An integer less than, equal to, or greater than zero if s1 is
414   * found to be less than, to match, or be greatred than s2
415   */
416  int os_strcasecmp(const char *s1, const char *s2);
417  
418  /**
419   * os_strncasecmp - Compare two strings ignoring case
420   * @s1: First string
421   * @s2: Second string
422   * @n: Maximum numbers of characters to compare
423   * Returns: An integer less than, equal to, or greater than zero if s1 is
424   * found to be less than, to match, or be greater than s2. Only first n
425   * characters will be compared.
426   */
427  int os_strncasecmp(const char *s1, const char *s2, size_t n);
428  
429  /**
430   * os_strchr - Locate the first occurrence of a character in string
431   * @s: String
432   * @c: Character to search for
433   * Returns: Pointer to the matched character or %NULL if not found
434   */
435  char * os_strchr(const char *s, int c);
436  
437  /**
438   * os_strrchr - Locate the last occurrence of a character in string
439   * @s: String
440   * @c: Character to search for
441   * Returns: Pointer to the matched character or %NULL if not found
442   */
443  char * os_strrchr(const char *s, int c);
444  
445  /**
446   * os_strcmp - Compare two strings
447   * @s1: First string
448   * @s2: Second string
449   * Returns: An integer less than, equal to, or greater than zero if s1 is
450   * found to be less than, to match, or be greatred than s2
451   */
452  int os_strcmp(const char *s1, const char *s2);
453  
454  /**
455   * os_strncmp - Compare two strings
456   * @s1: First string
457   * @s2: Second string
458   * @n: Maximum numbers of characters to compare
459   * Returns: An integer less than, equal to, or greater than zero if s1 is
460   * found to be less than, to match, or be greater than s2. Only first n
461   * characters will be compared.
462   */
463  int os_strncmp(const char *s1, const char *s2, size_t n);
464  
465  /**
466   * os_strstr - Locate a substring
467   * @haystack: String (haystack) to search from
468   * @needle: Needle to search from haystack
469   * Returns: Pointer to the beginning of the substring or %NULL if not found
470   */
471  char * os_strstr(const char *haystack, const char *needle);
472  
473  /**
474   * os_snprintf - Print to a memory buffer
475   * @str: Memory buffer to print into
476   * @size: Maximum length of the str buffer
477   * @format: printf format
478   * Returns: Number of characters printed (not including trailing '\0').
479   *
480   * If the output buffer is truncated, number of characters which would have
481   * been written is returned. Since some C libraries return -1 in such a case,
482   * the caller must be prepared on that value, too, to indicate truncation.
483   *
484   * Note: Some C library implementations of snprintf() may not guarantee null
485   * termination in case the output is truncated. The OS wrapper function of
486   * os_snprintf() should provide this guarantee, i.e., to null terminate the
487   * output buffer if a C library version of the function is used and if that
488   * function does not guarantee null termination.
489   *
490   * If the target system does not include snprintf(), see, e.g.,
491   * http://www.ijs.si/software/snprintf/ for an example of a portable
492   * implementation of snprintf.
493   */
494  int os_snprintf(char *str, size_t size, const char *format, ...);
495  
496  #else /* OS_NO_C_LIB_DEFINES */
497  
498  #ifdef WPA_TRACE
499  void * os_malloc(size_t size);
500  void * os_realloc(void *ptr, size_t size);
501  void os_free(void *ptr);
502  char * os_strdup(const char *s);
503  #else /* WPA_TRACE */
504  #ifndef os_malloc
505  #define os_malloc(s) malloc((s))
506  #endif
507  #ifndef os_realloc
508  #define os_realloc(p, s) realloc((p), (s))
509  #endif
510  #ifndef os_free
511  #define os_free(p) free((p))
512  #endif
513  #ifndef os_strdup
514  #ifdef _MSC_VER
515  #define os_strdup(s) _strdup(s)
516  #else
517  #define os_strdup(s) strdup(s)
518  #endif
519  #endif
520  #endif /* WPA_TRACE */
521  
522  #ifndef os_memcpy
523  #define os_memcpy(d, s, n) memcpy((d), (s), (n))
524  #endif
525  #ifndef os_memmove
526  #define os_memmove(d, s, n) memmove((d), (s), (n))
527  #endif
528  #ifndef os_memset
529  #define os_memset(s, c, n) memset(s, c, n)
530  #endif
531  #ifndef os_memcmp
532  #define os_memcmp(s1, s2, n) memcmp((s1), (s2), (n))
533  #endif
534  
535  #ifndef os_strlen
536  #define os_strlen(s) strlen(s)
537  #endif
538  #ifndef os_strcasecmp
539  #ifdef _MSC_VER
540  #define os_strcasecmp(s1, s2) _stricmp((s1), (s2))
541  #else
542  #define os_strcasecmp(s1, s2) strcasecmp((s1), (s2))
543  #endif
544  #endif
545  #ifndef os_strncasecmp
546  #ifdef _MSC_VER
547  #define os_strncasecmp(s1, s2, n) _strnicmp((s1), (s2), (n))
548  #else
549  #define os_strncasecmp(s1, s2, n) strncasecmp((s1), (s2), (n))
550  #endif
551  #endif
552  #ifndef os_strchr
553  #define os_strchr(s, c) strchr((s), (c))
554  #endif
555  #ifndef os_strcmp
556  #define os_strcmp(s1, s2) strcmp((s1), (s2))
557  #endif
558  #ifndef os_strncmp
559  #define os_strncmp(s1, s2, n) strncmp((s1), (s2), (n))
560  #endif
561  #ifndef os_strrchr
562  #define os_strrchr(s, c) strrchr((s), (c))
563  #endif
564  #ifndef os_strstr
565  #define os_strstr(h, n) strstr((h), (n))
566  #endif
567  
568  #ifndef os_snprintf
569  #ifdef _MSC_VER
570  #define os_snprintf _snprintf
571  #else
572  #define os_snprintf snprintf
573  #endif
574  #endif
575  
576  #endif /* OS_NO_C_LIB_DEFINES */
577  
578  
os_snprintf_error(size_t size,int res)579  static inline int os_snprintf_error(size_t size, int res)
580  {
581  	return res < 0 || (unsigned int) res >= size;
582  }
583  
584  
os_realloc_array(void * ptr,size_t nmemb,size_t size)585  static inline void * os_realloc_array(void *ptr, size_t nmemb, size_t size)
586  {
587  	if (size && nmemb > (~(size_t) 0) / size)
588  		return NULL;
589  	return os_realloc(ptr, nmemb * size);
590  }
591  
592  /**
593   * os_remove_in_array - Remove a member from an array by index
594   * @ptr: Pointer to the array
595   * @nmemb: Current member count of the array
596   * @size: The size per member of the array
597   * @idx: Index of the member to be removed
598   */
os_remove_in_array(void * ptr,size_t nmemb,size_t size,size_t idx)599  static inline void os_remove_in_array(void *ptr, size_t nmemb, size_t size,
600  				      size_t idx)
601  {
602  	if (idx < nmemb - 1)
603  		os_memmove(((unsigned char *) ptr) + idx * size,
604  			   ((unsigned char *) ptr) + (idx + 1) * size,
605  			   (nmemb - idx - 1) * size);
606  }
607  
608  /**
609   * os_strlcpy - Copy a string with size bound and NUL-termination
610   * @dest: Destination
611   * @src: Source
612   * @siz: Size of the target buffer
613   * Returns: Total length of the target string (length of src) (not including
614   * NUL-termination)
615   *
616   * This function matches in behavior with the strlcpy(3) function in OpenBSD.
617   */
618  size_t os_strlcpy(char *dest, const char *src, size_t siz);
619  
620  /**
621   * os_memcmp_const - Constant time memory comparison
622   * @a: First buffer to compare
623   * @b: Second buffer to compare
624   * @len: Number of octets to compare
625   * Returns: 0 if buffers are equal, non-zero if not
626   *
627   * This function is meant for comparing passwords or hash values where
628   * difference in execution time could provide external observer information
629   * about the location of the difference in the memory buffers. The return value
630   * does not behave like os_memcmp(), i.e., os_memcmp_const() cannot be used to
631   * sort items into a defined order. Unlike os_memcmp(), execution time of
632   * os_memcmp_const() does not depend on the contents of the compared memory
633   * buffers, but only on the total compared length.
634   */
635  int os_memcmp_const(const void *a, const void *b, size_t len);
636  
637  
638  /**
639   * os_memdup - Allocate duplicate of passed memory chunk
640   * @src: Source buffer to duplicate
641   * @len: Length of source buffer
642   * Returns: %NULL if allocation failed, copy of src buffer otherwise
643   *
644   * This function allocates a memory block like os_malloc() would, and
645   * copies the given source buffer into it.
646   */
647  void * os_memdup(const void *src, size_t len);
648  
649  /**
650   * os_exec - Execute an external program
651   * @program: Path to the program
652   * @arg: Command line argument string
653   * @wait_completion: Whether to wait until the program execution completes
654   * Returns: 0 on success, -1 on error
655   */
656  int os_exec(const char *program, const char *arg, int wait_completion);
657  
658  
659  #ifdef OS_REJECT_C_LIB_FUNCTIONS
660  #define malloc OS_DO_NOT_USE_malloc
661  #define realloc OS_DO_NOT_USE_realloc
662  #define free OS_DO_NOT_USE_free
663  #define memcpy OS_DO_NOT_USE_memcpy
664  #define memmove OS_DO_NOT_USE_memmove
665  #define memset OS_DO_NOT_USE_memset
666  #define memcmp OS_DO_NOT_USE_memcmp
667  #undef strdup
668  #define strdup OS_DO_NOT_USE_strdup
669  #define strlen OS_DO_NOT_USE_strlen
670  #define strcasecmp OS_DO_NOT_USE_strcasecmp
671  #define strncasecmp OS_DO_NOT_USE_strncasecmp
672  #undef strchr
673  #define strchr OS_DO_NOT_USE_strchr
674  #undef strcmp
675  #define strcmp OS_DO_NOT_USE_strcmp
676  #undef strncmp
677  #define strncmp OS_DO_NOT_USE_strncmp
678  #undef strncpy
679  #define strncpy OS_DO_NOT_USE_strncpy
680  #define strrchr OS_DO_NOT_USE_strrchr
681  #define strstr OS_DO_NOT_USE_strstr
682  #undef snprintf
683  #define snprintf OS_DO_NOT_USE_snprintf
684  
685  #define strcpy OS_DO_NOT_USE_strcpy
686  #endif /* OS_REJECT_C_LIB_FUNCTIONS */
687  
688  
689  #if defined(WPA_TRACE_BFD) && defined(CONFIG_TESTING_OPTIONS)
690  #define TEST_FAIL() testing_test_fail(NULL, false)
691  #define TEST_FAIL_TAG(tag) testing_test_fail(tag, false)
692  int testing_test_fail(const char *tag, bool is_alloc);
693  int testing_set_fail_pattern(bool is_alloc, char *patterns);
694  int testing_get_fail_pattern(bool is_alloc, char *buf, size_t buflen);
695  #else
696  #define TEST_FAIL() 0
697  #define TEST_FAIL_TAG(tag) 0
testing_set_fail_pattern(bool is_alloc,char * patterns)698  static inline int testing_set_fail_pattern(bool is_alloc, char *patterns)
699  {
700  	return -1;
701  }
702  
testing_get_fail_pattern(bool is_alloc,char * buf,size_t buflen)703  static inline int testing_get_fail_pattern(bool is_alloc, char *buf,
704  					   size_t buflen)
705  {
706  	return -1;
707  }
708  #endif
709  
710  #endif /* OS_H */
711