A
Avijit Samal
Hi All,
We are faced with a very peculiar problem involving JNI as follows..
We have C function which closes stdout and stderr and then execs
/sbin/mkfs for a disk partition. This function ,when
executed from C ,is going through fine. But when executed from JNI, it
goes in an infinite loop while writing to stderr.
strace showed that write returns a 0 and it keeps retrying infinitely.
The Code :
========
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <ctype.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <jni.h>
#include "NodeTest.h"
JNIEXPORT void JNICALL Java_NodeTest_nodeTest
(JNIEnv *env, jclass clazz,jstring nodeName)
{
main();
}
int
closeStdOutErr(int *new_out, int *new_err)
{
#if 0
*new_out = dup(STDOUT_FILENO);
if (*new_out == -1) {
return (-1);
/* NOTREACHED */
}
#endif
*new_err = dup(STDERR_FILENO);
if (*new_err == -1) {
return (-1);
/* NOTREACHED
* */
}
close(STDOUT_FILENO);
close(STDERR_FILENO);
return (0);
/* NOTREACHED * */
}
int
reopenStdOutErr(int prev_out, int prev_err)
{
int std_out, std_err;
std_out = dup2(prev_out, STDOUT_FILENO);
if (std_out == -1) {
return (-1);
/* NOTREACHED */
}
std_err = dup2(prev_err, STDERR_FILENO);
if (std_err == -1) {
return (-1);
/* NOTREACHED */
}
return (0);
/* NOTREACHED */
}
main ()
{
int num;
int fd1, fd2;
int stdoutFD, stderrFD, status, result;
char *args[] = {"/sbin/mkfs", "-t", "ext3", "/dev/sdb6", NULL};
int pid;
pid = fork ();
if (pid < 0) { //fork error
//log error
return -errno;
}
if (pid == 0) { //child
/* Execute the given command */
closeStdOutErr(&stdoutFD, &stderrFD);
result = execv("/sbin/mkfs", args);
if (result < 0) {
//log error
reopenStdOutErr(stdoutFD, stderrFD);
printf ("Exec failed\n");
}
} else { //parent
/* wait for the exe to exit*/
result = waitpid(pid, &status, 0);
if (result < 0) {
printf ("Abnormal exit. Errno: %d\n", errno);
exit (1);
}
result = WIFEXITED(status);
if (result != 0) { //exe exited normally
/* return the exit status*/
result = WEXITSTATUS(status);
}
}
fprintf (stdout, "ret: %d\n", result);
}
////////////////////////////////////////
strace -p <pid>
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
..........
..........<continues infinitely>
We are faced with a very peculiar problem involving JNI as follows..
We have C function which closes stdout and stderr and then execs
/sbin/mkfs for a disk partition. This function ,when
executed from C ,is going through fine. But when executed from JNI, it
goes in an infinite loop while writing to stderr.
strace showed that write returns a 0 and it keeps retrying infinitely.
The Code :
========
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <ctype.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <jni.h>
#include "NodeTest.h"
JNIEXPORT void JNICALL Java_NodeTest_nodeTest
(JNIEnv *env, jclass clazz,jstring nodeName)
{
main();
}
int
closeStdOutErr(int *new_out, int *new_err)
{
#if 0
*new_out = dup(STDOUT_FILENO);
if (*new_out == -1) {
return (-1);
/* NOTREACHED */
}
#endif
*new_err = dup(STDERR_FILENO);
if (*new_err == -1) {
return (-1);
/* NOTREACHED
* */
}
close(STDOUT_FILENO);
close(STDERR_FILENO);
return (0);
/* NOTREACHED * */
}
int
reopenStdOutErr(int prev_out, int prev_err)
{
int std_out, std_err;
std_out = dup2(prev_out, STDOUT_FILENO);
if (std_out == -1) {
return (-1);
/* NOTREACHED */
}
std_err = dup2(prev_err, STDERR_FILENO);
if (std_err == -1) {
return (-1);
/* NOTREACHED */
}
return (0);
/* NOTREACHED */
}
main ()
{
int num;
int fd1, fd2;
int stdoutFD, stderrFD, status, result;
char *args[] = {"/sbin/mkfs", "-t", "ext3", "/dev/sdb6", NULL};
int pid;
pid = fork ();
if (pid < 0) { //fork error
//log error
return -errno;
}
if (pid == 0) { //child
/* Execute the given command */
closeStdOutErr(&stdoutFD, &stderrFD);
result = execv("/sbin/mkfs", args);
if (result < 0) {
//log error
reopenStdOutErr(stdoutFD, stderrFD);
printf ("Exec failed\n");
}
} else { //parent
/* wait for the exe to exit*/
result = waitpid(pid, &status, 0);
if (result < 0) {
printf ("Abnormal exit. Errno: %d\n", errno);
exit (1);
}
result = WIFEXITED(status);
if (result != 0) { //exe exited normally
/* return the exit status*/
result = WEXITSTATUS(status);
}
}
fprintf (stdout, "ret: %d\n", result);
}
////////////////////////////////////////
strace -p <pid>
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
write(2, "mke2fs 1.27 (8-Mar-2002)\n", 25) = 0
..........
..........<continues infinitely>