How to make libxml2 not display connection errors? - c

Consider the following code:
#include <stdio.h>
#include <libxml/parser.h>
int main(void) {
xmlDocPtr doc;
xmlChar *s;
doc = xmlParseFile("http://localhost:8000/sitemap.xml");
s = xmlNodeGetContent((struct _xmlNode *)doc);
printf("%s\n", s);
return 0;
}
The output:
$ gcc -g3 -O0 $(xml2-config --cflags --libs) 1.c
$ ./a.out
error : Operation in progress
<result of xmlNodeGetContent>
That is, xmlParseFile produces undesired output. What happens here is libxml2 tries to translate localhost to IP address. What it gets is ::1 and 127.0.0.1. connect("[::1]:8000") results in EINPROGRESS (since libxml2 sets O_NONBLOCK on the descriptor). So libxml2 waits for it to finish, which results in POLLOUT | POLLERR | POLLHUP, and libxml2 reports an error.
Subsequent connect("127.0.0.1:8000") call succeeds, so all in all the program finishes successfully.
Is there a way to avoid this extra output?

As suggested by nwellnhof, connection errors can be circumvented by setting error handler. Particularly, structured error handler, whatever that means.
While the answer in the other question more or less answers my question, that other question is about parser errors. And the answer doesn't provide example code. So,
#include <stdio.h>
#include <libxml/parser.h>
void structuredErrorFunc(void *userData, xmlErrorPtr error) {
printf("xmlStructuredErrorFunc\n");
}
void genericErrorFunc(void *ctx, const char * msg, ...) {
printf("xmlGenericErrorFunc\n");
}
int main(void) {
xmlDocPtr doc;
xmlChar *s;
xmlSetGenericErrorFunc(NULL, genericErrorFunc);
xmlSetStructuredErrorFunc(NULL, structuredErrorFunc);
doc = xmlParseFile("http://localhost:8000/sitemap.xml");
s = xmlNodeGetContent((struct _xmlNode *)doc);
printf("%s\n", s);
return 0;
}
This one outputs,
xmlStructuredErrorFunc
<result of xmlNodeGetContent>

Related

How can I cause a "initscr" break with ncurses?

I know this is a weird question, but I want to get the "initscr" function error mentioned by the doc (getting invalid pointer and an error message on stderr) to test if a wrapper works properly.
But I don't find any information about that. I'm currently working with ncurses 6.2.
After few research, I have found that the invalid pointer is really a NULL, not just an empty one pointing on anywhere.
But I'm not able to break the function...
If someone know how to help me to break down this, feel free to leave a comment.
The following program:
#include <curses.h>
#include <malloc.h>
#include <stdlib.h>
bool my_malloc_disabled;
void *malloc(size_t size) {
if (my_malloc_disabled) {
return NULL;
}
void *__libc_malloc(size_t);
return __libc_malloc(size);
}
int main() {
my_malloc_disabled = 1;
initscr();
}
does:
$ gcc file.c -lcurses
$ ./a.out
Error opening allocating $TERM.

Linker error with intercepting function calls in GCC

I am using the standard __wrap_function and __real_function to intercept function calls with -Wl,--wrap=function. This works successfully for most functions like malloc, fopen, etc. However, I am unable to wrap these two functions:
int connect(int, const struct sockaddr*, socklen_t)
int stat(const char*, struct stat*)
With these functions, the linker complains with undefined reference to __real_connect and __real_stat.
Is there any particular reason for this? (Note: I can also wrap socket functions for example)
It is likely you forgot to add -Wl,--wrap=connect and -Wl,--wrap=stat to your link line.
This works for me:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <unistd.h>
int __wrap_connect (int s, const struct sockaddr *addr, socklen_t len)
{
puts(__func__);
return __real_connect(s, addr, len);
}
int __wrap_stat (const char *path, struct stat *buf)
{
puts(__func__);
return __real_stat(path, buf);
}
int main(void) {
connect(0, NULL, 0);
stat("/", 0);
return 0;
}
When compiled on my system.
$ uname -s -r
Linux 2.6.32-696.16.1.el6.x86_64
$ gcc --version | grep gcc
gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18)
$ gcc c.c -Wl,--wrap=connect -Wl,--wrap=stat
$
However, when leaving off -Wl,--wrap=stat, for example, I get:
$ gcc c.c -Wl,--wrap=connect
/tmp/cchVzvsE.o: In function `__wrap_stat':
c.c:(.text+0x65): undefined reference to `__real_stat'
collect2: ld returned 1 exit status
$
It seems like the error was caused due to cmake issues. Clearing the cmake cache and running cmake . followed by make all resolved it.

OCaml shared lib for another shared lib

I am exploring some adventurous ideas.
TL:DR; gnumake is able to use loadable modules, I am trying to use that C barrier to use OCaml but have trouble with the OCaml runtime initializing.
I have this OCaml code:
(* This is speak_ocaml.ml *)
let do_speak () =
print_endline "This called from OCaml!!";
flush stdout;
"Some return value from OCaml"
let () =
Callback.register "speak" do_speak
and I also have this C code: (Yes, needs to use extra CAML macros but not relevant here)
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <gnumake.h>
#include <caml/mlvalues.h>
#include <caml/callback.h>
#include <caml/memory.h>
#include <caml/alloc.h>
int plugin_is_GPL_compatible;
char *ocaml_speaker(const char *func_name, int argc, char **argv)
{
char *answer =
String_val(caml_callback(*caml_named_value("speak"), Val_unit));
printf("Speaking and got: %s\n", answer);
char *buf = gmk_alloc(strlen(answer) + 1);
strcpy(buf, answer);
/* receive_arg */
return buf;
}
int do_speak_gmk_setup()
{
printf("Getting Called by Make\n");
// This is pretty critical, will explain below
char **argv = {"/home/Edgar/foo", NULL};
caml_startup(argv);
printf("Called caml_startup\n");
gmk_add_function("speak", ocaml_speaker, 1, (unsigned int)1, 1);
return 1;
}
and I'm compiling it with this Makefile
all:
ocamlopt -c speak_ocaml.ml
ocamlopt -output-obj -o caml_code.o speak_ocaml.cmx
clang -I`ocamlc -where` -c do_speak.c -o do_speak.o
clang -shared -undefined dynamic_lookup -fPIC -L`ocamlc -where` -ldl \
-lasmrun do_speak.o caml_code.o -o do_speak.so
show_off:
echo "Speaker?"
${speak 123}
clean:
#rm -rf *.{cmi,cmt,cmi,cmx,o,cmo,so}
And my problem is that only printf("Getting Called by Make\n"); is going off when I add the appropriate load do_speak.so in the Makefile, caml_startup is not going off correctly. Now I am calling caml_startup because if I don't then I get an error of
Makefile:9: dlopen(do_speak.so, 9): Symbol not found: _caml_atom_table
Referenced from: do_speak.so
Expected in: flat namespace
in do_speak.so
Makefile:9: *** do_speak.so: failed to load. Stop.
And this is because of the way that clang on OS X does linking, see here for more details: http://psellos.com/2014/10/2014.10.atom-table-undef.html
I am kind of out of ideas... I need to create a C shared library out of OCaml code which then needs to be part of another C shared library from which I obviously don't have the original argv pointers that caml_startup wants. As my code sample show, I've tried faking it out, and also used caml_startup(NULL) and char **argv = {NULL}; caml_startup(argv) with similar lack of success. I don't know how else to initialize the runtime correctly.
I actually can't tell very well what you're asking. However, here's a comment on this part of your question:
I've tried faking it out, and also used caml_startup(NULL) and char **argv = {NULL}; caml_startup(argv) with similar lack of success. I don't know how else to initialize the runtime correctly.
As far as I know, the only reason for the argv argument of caml_startup is to establish the command-line arguments (for Sys.argv). If you don't need command-line arguments it should be OK to call like this:
char *arg = NULL;
caml_startup(&arg);
Technically argv is supposed to contain at least one string (the name of the program). So maybe it would be better to call like this:
char *argv[] = { "program", NULL };
caml_startup(argv);

How to print wide character using JNI

On a 32-bit Ubuntu machine, from JDK 1.7.0, I'm unable to print wide characters.
Here is my code:
JNIFoo.java
public class JNIFoo {
public native void nativeFoo();
static {
System.loadLibrary("foo");
}
public void print () {
nativeFoo();
System.out.println("The end");
}
public static void main(String[] args) {
(new JNIFoo()).print();
return;
}
}
foo.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <jni.h>
#include "JNIFoo.h"
JNIEXPORT void JNICALL Java_JNIFoo_nativeFoo (JNIEnv *env, jobject obj)
{
fwprintf(stdout, L"using fWprintf\n");
fflush(stdout);
}
Then I'm executing the following commands:
javac JNIFoo.java
javah -jni JNIFoo
gcc -shared -fpic -o libfoo.so -I/path/to/jdk/include -I/path/to/jdk/include/linux foo.c
Here is the result depending of the JDK used to execute the program:
jdk1.6.0_45/bin/java -Djava.library.path=/path/to/jni_test JNIFoo
using fWprintf
The end
jdk1.7.0/bin/java -Djava.library.path=/path/to/jni_test JNIFoo
The end
jdk1.8.0_25/bin/java -Djava.library.path=/path/to/jni_test JNIFoo
The end
As you can see, with JDK 1.7 and JDK 1.8, the fwprintf has no effect!
So my question is what am I missing to be able to use wide chars using JDK 1.7 (and 1.8) ?
Note: if I call fprintf instead of fwprintf, then there is no problem, everything is print out correctly.
Edit
Based on the comment of James, I created a main.c file:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <wchar.h>
#include "JNIFoo.h"
int main(int argc, char* argv[])
{
fwprintf(stdout, L"In the main\n");
Java_JNIFoo_nativeFoo(NULL, NULL);
return 0;
}
Then I compile it like that:
gcc -Wall -L/path/to/jni_test -I/path/to/jdk1.8.0_25/include -I/pat/to/jdk1.8.0_25/include/linux main.c -o main -lfoo
And set LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/path/to/jni_test
And it is working correctly:
In the main
using fWprintf
So the problem may not come from C.
Note: it's working correctly on a 64-bit machine.
I have similar problem using linux Mint 32-bit.
You must not mix printing of narrow and wide characters to the same stream. C99 introduced the concept of stream orientation whereby an I/O stream can be wide-oriented or byte-oriented (prior to C99, wide characters did not exist in the C language standard). From C99 §7.19.2/4–5:
4) Each stream has an orientation. After a stream is associated with an external file, but before any operations are performed on it, the stream is without orientation. Once a wide character input/output function has been applied to a stream without orientation, the stream becomes a wide-oriented stream. Similarly, once a byte input/output function has been applied to a stream without orientation, the stream becomes a byte-oriented stream. Only a call to the freopen function or the fwide function can otherwise alter the orientation of a stream. (A successful call to freopen removes any orientation.)233)
5) Byte input/output functions shall not be applied to a wide-oriented stream and wide character input/output functions shall not be applied to a byte-oriented stream. [...]
233) The three predefined streams stdin, stdout, and stderr are unoriented at program startup.
The C99 standard leaves mixing narrow- and wide-character functions as Undefined Behavior. In practice, the GNU C library says "There are no diagnostics issued. The application behavior will simply be strange or the application will simply crash. The fwide function can help avoiding this. " (source)
Since the JRE is in charge of program startup, it's in charge of the stdin, stdout, and stderr streams and therefore also their orientations. Your JNI code is a guest in its house, don't go changing its carpets. In practice, this means you have to deal with whatever stream orientation you're given, which you can detect with the fwide(3) function. If you want to print wide characters to a byte-oriented stream, too bad. You'll need to work around that by convincing the JRE to use wide-oriented streams, or convert your wide characters to UTF-8, or something else.
For example, this code should work in all cases:
JNIEXPORT void JNICALL Java_JNIFoo_nativeFoo (JNIEnv *env, jobject obj)
{
if (fwide(stdout, 0) >= 0) {
// The stream is wide-oriented or unoriented, so it's safe to print wide
// characters
fwprintf(stdout, L"using fWprintf\n");
} else {
// The stream is narrow oriented. Convert to UTF-8 (and hopefully the
// terminal (or wherever stdout is going) can handle that)
char *utf8_string = convert_to_utf8(L"my wide string");
printf("%s", utf8_string);
}
fflush(stdout);
}
#dalf,
The problem is outside JDK. It's in 32 bit version of GLIBC.
Please try to reproduce it on your machine:
I) create 3 files:
---foo.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
void foo() {
fwprintf(stdout, L"using fWprintf\n");
fflush(stdout);
}
----main.c:
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main(int argc, char **argv) {
void *handle;
void (*foo)();
char *error;
handle = dlopen("libfoo.so", RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
dlerror();
*(void **) (&foo) = dlsym(handle, "foo");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
exit(EXIT_FAILURE);
}
(*foo)();
dlclose(handle);
exit(EXIT_SUCCESS);
}
----mapfile:
SomethingPrivate {
local:
*;
};
II) run commands:
$ gcc -m32 -shared -fpic -o libfoo.so foo.c
$ gcc -m32 -Xlinker -version-script=mapfile -o main main.c -ldl
$ export LD_LIBRARY_PATH="."
$ ./main
and see what does it print to output

Wrapper routine for write() with unistd.h included results in error

I am writing a wrapper routine for write() to override the original system function and within it i need to execute another program through execve(); for which I include the header file unistd.h. I get the error conflicting types for 'write' /usr/include/unistd.h:363:16: note: previous declaration of 'write'was here. I would be very gratefull if someone could help me out as I need to call another program from inside the wrapper and also send arguments to it from inside the wrapper routine.
The GNU linker has a --wrap <symbol> option which allows you to do this sort of thing.
If you link with --wrap write, references to write will redirect to __wrap_write (which you implement), and references to __real_write will redirect to the original write (so you can call it from within your wrapper implementation).
Here's a sophisticated test application using write() - I'm doing the compilation and linking steps separately because I'll want to use hello.o again in a minute:
$ cat hello.c
#include <unistd.h>
int main(void)
{
write(0, "Hello, world!\n", 14);
return 0;
}
$ gcc -Wall -c hello.c
$ gcc -o test1 hello.o
$ ./test1
Hello, world!
$
Here's an implementation of __wrap_write(), which calls __real_write(). (Note that we want a prototype for __real_write to match the original. I've added a matching prototype explicitly, but another possible option is to #define write __real_write before #include <unistd.h>.)
$ cat wrapper.c
#include <unistd.h>
extern ssize_t __real_write(int fd, const void *buf, size_t n);
ssize_t __wrap_write(int fd, const void *buf, size_t n)
{
__real_write(fd, "[wrapped] ", 10);
return __real_write(fd, buf, n);
}
$ gcc -Wall -c wrapper.c
$
Now, link the hello.o we made earlier with wrapper.o, passing the appropriate flags to the linker. (We can pass arbitrary options through gcc to the linker using the slightly odd -Wl,option syntax.)
$ gcc -o test2 -Wl,--wrap -Wl,write hello.o wrapper.o
$ ./test2
[wrapped] Hello, world!
$
An alternative to using the GNU liner --wrap symbol option as suggested by Matthew Slattery would be to use dlsym() to obtain the address of the execve() symbol at runtime in order to avoid the compile-time issues with including unistd.h.
I suggest reading Jay Conrod's blog post entitled Tutorial: Function Interposition in Linux for additional information on replacing calls to functions in dynamic libraries with calls to your own wrapper functions.
The following example provides a write() wrapper function that calls the original write() before calling execve() and does not include unistd.h. It is important to note that you cannot directly call the original write() from the wrapper because it will be interpreted as a recursive call to the wrapper itself.
Code:
#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>
size_t write(int fd, const void *buf, size_t count)
{
static size_t (*write_func)(int, const void *, size_t) = NULL;
static int (*execve_func)(const char *, char *const[], char *const[]) = NULL;
/* arguments for execve() */
char *path = "/bin/echo";
char *argv[] = { path, "hello world", NULL };
char *envp[] = { NULL };
if (!write_func)
{
/* get reference to original (libc provided) write */
write_func = (size_t(*)(int, const void *, size_t)) dlsym(RTLD_NEXT, "write");
}
if (!execve_func)
{
/* get reference to execve */
execve_func = (int(*)(const char *, char *const[], char *const[])) dlsym(RTLD_NEXT, "execve");
}
/* call original write() */
write_func(fd, buf, count);
/* call execve() */
return execve_func(path, argv, envp);
}
int main(int argc, char *argv[])
{
int filedes = 1;
char buf[] = "write() called\n";
size_t nbyte = sizeof buf / sizeof buf[0];
write(filedes, buf, nbyte);
return 0;
}
Output:
$ gcc -Wall -Werror -ldl test.c -o test
$ ./test
write() called
hello world
$
Note: This code is provided as an example of what is possible. I would recommend following Jonathan Leffler's advice on code segregation in constructing the final implementation.
It is an utterly bad idea to try wrapping write() and use POSIX functions. If you chose to work in standard C, then you could wrap write() because it is not a name reserved to the standard. However, once you start using POSIX functions - and execve() is a POSIX function - then you are running into conflicts; POSIX reserves the name write().
If you want to try, you may get away with it if you segregate the code carefully. You have your write() wrapper in one source file which does not include <unistd.h> or use any functions not defined in the C standard for the headers you do include. You have your code that does the execve() in a second file that does include <unistd.h>. And you link those parts together with appropriate function calls.
If you are lucky, it will work as intended. If you aren't lucky, all hell will break loose. And note that your luck status might change on different machines depending on factors outside your control such as o/s updates (bug fixes) or upgrades. It is a very fragile design decision to wrap write().
Just making an illustration for Muggen's attention call (therefore community wiki):
You want to redefine write and call write from inside your redefinition. Something like
void write(int a) {
/* code code code */
write(42); /* ??? what `write`?
??? recursive `write`?
??? the other `write`? */
/* code code code */
}
Better think better about it :)
If you segregate your code appropriately as suggested by Jonathan Leffler, you should be able to avoid compile-time issues related to including unistd.h. The following code is provided as an example of such segregation.
Note that you cannot interpose internal library function calls, since these are resolved before runtime. For instance, if some function in libc calls write(), it will never call your wrapper function.
Code:
exec.c
#include <unistd.h>
inline int execve_func(const char *path, char *const argv[], char *const envp[])
{
return execve(path, argv, envp);
}
test.c
#include <stdio.h>
extern int execve_func(const char *, char *const[], char *const[]);
size_t write(int fd, const void *buf, size_t count)
{
/* arguments for execve() */
char *path = "/bin/echo";
char *argv[] = { path, "hello world", NULL };
char *envp[] = { NULL };
return execve_func(path, argv, envp);
}
int main(int argc, char *argv[])
{
int filedes = 1;
char buf[] = "dummy";
size_t nbyte = sizeof buf / sizeof buf[0];
write(filedes, buf, nbyte);
return 0;
}
Output:
$ gcc -Wall -Werror test.c exec.c -o test
$ ./test
hello world
$

Resources