Is the JSON C library thread-safe? - c

Am using the C JSON library under Ubuntu (json-c/json.h). I need to parse JSON strings on multiple POSIX threads. Am currently using the json_tokener_parse() method - is this multi-thread safe or do I need to use something else?
thnx

I looked through the code: https://github.com/json-c/json-c/blob/master/json_tokener.c
It appears to be thread-safe with one exception:
#ifdef HAVE_SETLOCALE
char *oldlocale=NULL, *tmplocale;
tmplocale = setlocale(LC_NUMERIC, NULL);
if (tmplocale) oldlocale = strdup(tmplocale);
setlocale(LC_NUMERIC, "C");
#endif
So if HAVE_SETLOCALE is defined (and it probably will be), setlocale() will be called and it will set the process-wide LC_NUMERIC to "C". And of course it undoes this at the end. This will cause problems if your LC_NUMERIC is not "C" or a compatible locale at the beginning, because one thread will "restore" your locale while another one may still be parsing and expecting the "C" locale to be in effect.
Fortunately it is guaranteed that the locale will be "C" on program start, so you just need to make sure that neither you nor any other library you're using sets LC_NUMERIC (or LC_ALL of course) to a locale incompatible with "C". You could then rebuild the library with HAVE_SETLOCALE undefined if you want, but this probably doesn't matter, as its calls to setlocale() will have no real effect.

Related

Is environ available on Windows?

Is environ variable (as of POSIX) available (at least for reading) in major Windows C compilers?
I know that execve is available on Windows: https://en.wikipedia.org/wiki/Exec_(system_call)
But I am unsure if environ is available, too.
environ should be available, but is deprecated and you should use the more secure methods.
The execXX() calls are available, but fork() isn't, so effectively the exec functions are rendered useless.
You can use CreateProcessA for similar effect, and have the ability to set up environments and pipes cleanly.
Just to acknowledge #eryksun 's concerns: You do need to consider which character set you are using before using any Microsoft "A" file (and other O/S) APIs. It is simplest if you can do all your code using 16bit unicode, as that is the underlying type for NT, Windows 7, Windows 10. On unix and mac, you can make assumptions that utf-8 is the 8-bit character set of choice, but that has yet to happen for windows, and of course "backward compatibility". If you are using any of the "unix-like" M/S API, you should already be making the same design decisions, though, so should already have an answer.
The following program will print the environment variables.
#include <stdio.h>
int main(int argc, char *argv[], char *env[]){
int e = 0;
while (env[e] != NULL) {
printf("%s\n", env[e++]);
}
}
EDIT: I was wrong; looks like the MSVC runtime library does include support for environ (though deprecated) after all. I will leave my previous answer below if anyone is interested in alternative methods.
Not that I'm aware of, but, if you want to access the environment-variables on Windows, you have some options:
Declare main or wmain with the following signature:
int (w)main(int argc, char/wchar_t *argv[], char/wchar_t *envp[])
This is defined in the C Standard as a pointer to the environment block, if applicable:
§ J.5.1:
In a hosted environment, the main function receives a third argument, char *envp[],
that points to a null-terminated array of pointers to char, each of which points to a string
that provides information about the environment for this execution of the program
(5.1.2.2.1).
Use the Windows API function GetEnvironmentVariable(A|W) to get an individual environment variable, or GetEnvironmentStrings to get the entire environment array.
The standard C function getenv.

Make gzprintf ignore locale LC_NUMERIC

How can I make gzprintf (or printf in general) to use "." as decimal separator, effectively ignoring LC_NUMERIC or using "LC_NUMERIC = C".
Background: My program which uses gettext , does setlocale (LC_ALL, ....) to change it's locale. But at one point I need to write to a measurement file which should have a fixed "." as decimal separator. Of course I can do something like
const char *old = setlocale (LC_NUMERIC, NULL);
... make copy
setlocale (LC_NUMERIC, "C");
... use gzprintf
setlocale (LC_NUMERIC, old_copy);
but I fear runtime problems because I have to write samples with 2kHz to the file but haven't benchmarked it yet.
Not only is wrapping each call with setlocale like that potentially slow. It's completely thread-unsafe and thus unsafe to use in general/library code.
Assuming you're on a POSIX or POSIX-like system, what you want is newlocale/uselocale. Perform the following (which may be slow) once and save the result:
locale_t safe_locale = newlocale(LC_NUMERIC_MASK, "C", duplocale(LC_GLOBAL_LOCALE));
Then, whenever you want to use it:
locale_t old = uselocale(safe_locale);
/* Do stuff with it. */
uselocale(old);
You need not switch back and forth around each operation, only before returning to a caller that might expect its locale to be undisturbed, but it should not be slow to switch back and forth like this anyway.
Alternatively, just don't honor LC_NUMERIC in your application at all. After calling setlocale(LC_ALL, "") to setup the locale according to the user's settings, call setlocale(LC_NUMERIC, "C") and leave it that way. This is not valid/acceptable in library code, but if you're writing library code, you can punt and let the caller take responsibility for doing whichever approach it finds appropriate (never honoring LC_NUMERIC at all, or using newlocale/uselocale to switch). You can either just write this requirement in the documentation of its contract, and treat failure to honor the contract as undefined, or you can actively test for non-'.' radix point by asserting that localeconv()->decimal_point points to a string "." (and returning an error or aborting if that fails to hold).

Initializing custom output stream before main

Say I want to write an API (for C/Linux) that offers a customized output stream, like stdout but mine should be called not_stdout. So I could demand that people using my API always begin their main program by calling a function init_the_stream() that initializes extern FILE* not_stdout.
But what I'd really like is for my stream to be initialized prior to main(), so that it works just like stdout.
I would guess that this is somewhat hard to do in a portable way, since the C standard wants prior-to-main initialized variables to be constants or string literals, and that stdout gets special compiler treatment. But I'm not sure, so I want to ask:
Is it possible to write a C library such that stuff like extern FILE* not_stdout is initialized before the first line of main() whenever the library is included?
On gcc and clang, you can use __attribute__((constructor)) (not standard C).
Example:
#include <stdio.h>
__attribute__((constructor))
static void not_stdout__init(void)
{
puts("initializing not_stdout");
}
int main()
{
puts("main");
}
It works well with dynamically linked (.so) or loaded (dlopen) ELF libraries – if a library provides such hooks, they will get invoked when the library gets linked in.
If you want to be portable, you could leave the initializer externally visible (no static) and conditionally add the constructor attribute only if it's supported. That way, your users could invoke the initializer from main manually if no mechanism exists to make their platform do it for them.

C: What is the portable/safe(thread aware) way to convert a number to a string w/o locale settings?

What is the safe/portable way to convert a number to a string (and the other way around) ?
I'm on Linux and my settings locale is so that when I use sprintf numbers have a "," instead of a "." as a separator.
Sometimes I want them that way, Sometimes not :)
I saw some solutions that imply playing with users settings. Clearly that's something one should not do. Somebody suggested using uselocale
snprintf : simple way to force . as radix?
can someone elaborate a bit (looks like it's buggy on some glibc (<2.12)) and if possible provide some sample code (eg a macro SNPRINTF_POSIX).
I tried myself but my C skills are very limited.
[edit]
I find this code by [GO]Skywalker13 on Swisslinux.org after writing my question.
Any thoughts about it ? What about memory usage ? (I need to make numerous calls to this func)
#define _GNU_SOURCE
#include <locale.h>
#include <stdlib.h>
double
my_atof (const char *nptr)
{
double res;
locale_t new_locale;
new_locale = newlocale (LC_NUMERIC_MASK, "C", NULL);
res = strtod_l (nptr, NULL, new_locale);
freelocale (new_locale);
return res;
}
With POSIX 2008, you can use the newlocale and uselocale functions to temporarily change the locale in the current thread without affecting other threads. This is really the only solution, aside from never setting the LC_NUMERIC locale category to begin with. On the other hand, I prefer banning use of LC_NUMERIC in software I write, at least for the global locale. Then you can use newlocale and uselocale locally at the point where you want numeric formatting that matches your user's cultural conventions, and on systems that lack POSIX 2008 uselocale, simply leave out localized numeric printing.

Is main() a pre-defined function in C? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
main() in C, C++, Java, C#
I'm new to programming in general, and C in particular. Every example I've looked at has a "main" function - is this pre-defined in some way, such that the name takes on a special meaning to the compiler or runtime... or is it merely a common idiom among C programmers (like using "foo" and "bar" for arbitrary variable names).
No, you need to define main in your program. Since it's called from the run-time, however, the interface your main must provide is pre-defined (must return an int, must take either zero arguments or two, the first an int, and the second a char ** or, equivalently, char *[]). The C and C++ standards do specify that a function with external linkage named main acts as the entry point for a program1.
At least as the term is normally used, a predefined function would be one such as sin or printf that's in the standard library so you can use it without having to write it yourself.
1If you want to get technical, that's only true for a "hosted" implementation -- i.e., the kind most of us use most of the time that produces programs that run on an operating system. A "free-standing" implementation (one produces program that run directly on the "bare metal" with no operating system under it) is free to define the entry point(s) as it sees fit. A free-standing implementation can also leave out most of the normal run-time library, providing only a handful of headers (e.g., <stddef.h>) and virtually no standard library functions.
Yes, main is a predefined function in the general sense of the the word "defined". In other words, the C language standard specifies that the function called at program startup shall be named main. It is not merely a convention used by programmers as we have with foo or bar.
The fine print: from the perspective of the technical meaning of the word "defined" in the context of C programming, no the main function is not "predefined" -- the compiler or C library do not supply a predefined function named main. You need to define your own implementation of the main function (and, obviously, you should name it main).
There is typically a piece of code that normal C programs are linked to which does:
extern int main(int argc, char * argv[], char * envp[]);
FILE * stdin;
FILE * stdout;
FILE * stderr;
/* ** setup argv ** */
...
/* ** setup envp ** */
...
/* ** setup stdio ** */
stdin = fdopen(0, "r");
stdout = fdopen(1, "w");
stderr = fdopen(2, "w");
int rc;
rc = main(argc, argv, envp); // envp may not be present here with some systems
exit(rc);
Note that this code is C, not C++, so it expects main to be a C function.
Also note that my code does no error checking and leaves out a lot of other system dependent stuff that probably happens. It also ignores some things that happen with C++, objective C, and various other languages that may be linked to it (notably constructor and destructor calling, and possibly having main be within a C++ try/catch block).
Anyway, this code knows that main is a function and takes arguments. If your main looks like:
int main(void) {
Then it still gets passed arguments, but they are ignored.
This code specially linked so that it is called when the program starts up.
You are completely free to write your own version of this code on many architectures, but it relies on intimate knowledge of how the operating system starts a new program as well as the C (and C++ and possibly Objective C) run time. It is likely to require some assembly programming and or use of compiler extensions to properly build.
The C compiler driver (the command you usually call when you call the compiler) passes the object file containing all of this (often called crt0.0, for C Run Time ...) along with the rest of your program to the linker, unless told not to.
When building an operating system kernel or an embedded program you often do not want to use the standard crt*.o file. You also may not want to use it if you are building a normal application in another programming language, or have some other non-standard requirements.
No, or you couldn't define one.
It's not predefined, but its meaning as an entry point, if it is present, is defined.

Resources