6 messages in net.java.dev.jna.usersRe: [jna-users] Mac OS X: Jna problem...
FromSent OnAttachments
rzoJan 7, 2009 10:20 am 
rzoJan 7, 2009 11:11 am 
Timothy WallJan 7, 2009 12:36 pm 
rzoJan 8, 2009 12:25 pm 
Daniel KaufmannJan 8, 2009 3:24 pm 
rzoJan 10, 2009 1:35 am 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:Re: [jna-users] Mac OS X: Jna problem or Java bug ?Actions...
From:Timothy Wall (twal@dev.java.net)
Date:Jan 7, 2009 12:36:42 pm
List:net.java.dev.jna.users

Take a look at some of the recent discussion of forking a VM. When you do a successful fork, do you get a clone of the entire VM or only the forking thread?

https://jna.dev.java.net/servlets/SearchList?list=users&searchText=fork&defaultField=body&Search=Search

On Jan 7, 2009, at 1:21 PM, rzo wrote:

Hello,

attached is a test program. When I run it as is, everything is fine. However whenever I change code parts, even if they are not required, such as remove unused methods (for example pipe()) in the interface CLibrary, or if I call System.getProperties().list(System.out) The program fails (the fork starts a process which crashes).

Any help or hints are welcome.

The program has been tested with : Mac Os X 10.5.5, JDK 1.5.0_16, 32 bit.

- Ron package test.mac;

import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.logging.ConsoleHandler; import java.util.logging.Logger;

import org.rzo.yajsw.os.posix.UnixProcess.CLibrary; import org.rzo.yajsw.os.posix.UnixProcess.CLibrary.dirent64;

import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.ptr.IntByReference;

public class ForkTest { protected static final Executor executor = Executors.newCachedThreadPool(); int pid; Logger _appLogger;

public interface CLibrary extends Library {

CLibrary INSTANCE = (CLibrary) Native .loadLibrary((System.getProperty("os.name").startsWith("Windows") ? "msvcrt" : "c"), CLibrary.class);

int fork();

void exit(int status);

/* * int execv (const charfilename, charconst argv[]) */ int execvp(String filename, String[] argv);

/* * int pipe (int filedes[2]) */ int pipe(int filedes[]);

/* * int close(int fd) */ int close(Pointer fd);

int close(int fd);

/* * mode_t umask (mode_t mask) */ void umask(int mask);

int setsid();

/* * FILE freopen ( const char filename, const char mode, FILE stream ); */ Pointer freopen(String filename, String mode, int stream);

/* * int kill (pid_t pid, int signum) */ int kill(int pid, int signum);

static final int SIGTERM = 15; static final int SIGKILL = 9;

/* * pid_t waitpid(pid_t pid, intstat_loc, int options); */ int waitpid(int pid, IntByReference stat_loc, int options);

static final int ESRCH = 3;

/* * int chdir(const charpath); */ int chdir(String path);

static final int WNOHANG = 1; /* don't hang in wait */ static final int WUNTRACED = 2; /* * tell about stopped, untraced * children */

/* * int fputc (int c, FILEstream) */ int fputc(int c, Pointer stream);

/* * FILEfdopen(int fildes, const chartype); */ Pointer fdopen(Pointer fildes, String type);

/* * int fileno(FILEstream); */ int fileno(int stream);

/* * struct dirent64 { __u64 d_ino; __s64 d_off; unsigned short d_reclen; * unsigned char d_type; char d_name[256]; }; */ class dirent64 extends Structure { public long d_ino; public long d_off; public short d_reclen; public char d_type; public char[] d_name = new char[256];

public String getName() { return getPointer().getString(8 + 8 + 2 + 1, false); } };

/* * struct dirent { long d_ino; off_t d_off; unsigned short d_reclen; * char d_name[NAME_MAX+1]; }; */ class dirent extends Structure { public int d_ino; public int d_off; public short d_reclen; public String d_name; };

/* * DIR opendir (const chardirname) */ Pointer opendir(String dirname);

/* * struct dirent64 readdir64 (DIRdirstream) */ dirent64 readdir64(Pointer dirstream);

/* * int closedir (DIRdirstream) */ int closedir(Pointer dirstream);

/* * int nice (int increment) */ int nice(int increment);

/* * int sched_setaffinity (pid_t pid, size_t cpusetsize, const cpu_set_t * cpuset) */ int sched_setaffinity(int pid, int cpusetsize, IntByReference cpuset);

/* * pid_t getpid(void); */ int getpid();

/* * int symlink (const char *oldname, const char *newname) */ int symlink (String oldname, String newname);

/* * struct passwd

The passwd data structure is used to hold information about entries in the system user data base. It has at least the following members:

char *pw_name The user's login name. char *pw_passwd. The encrypted password string. uid_t pw_uid The user ID number. gid_t pw_gid The user's default group ID number. char *pw_gecos A string typically containing the user's real name, and possibly other information such as a phone number. char *pw_dir The user's home directory, or initial working directory. This might be a null pointer, in which case the interpretation is system- dependent. char *pw_shell The user's default shell, or the initial program run when the user logs in. This might be a null pointer, indicating that the system default should be used. */

public static class passwd extends Structure { public passwd(Pointer p) { super(); if (p != null) { this.useMemory(p); this.read(); } }

public String pw_name; public String pw_passwd; public int pw_uid; public int pw_gid; public String pw_gecos; public String pw_dir; public String pw_shell;

String getName() { return pw_name; }

int getUid() { return pw_uid; } }

/* * struct passwd * getpwnam (const char *name) * This function returns a pointer to a statically-allocated structure containing information about the user whose user name is name. This structure may be overwritten on subsequent calls to getpwnam.

A null pointer return indicates there is no user named name. */ Pointer getpwnam (String name);

/* * uid_t geteuid (void)

The geteuid function returns the effective user ID of the process. */ int geteuid ();

/* * struct passwd * getpwuid (uid_t uid)

This function returns a pointer to a statically-allocated structure containing information about the user whose user ID is uid. This structure may be overwritten on subsequent calls to getpwuid.

A null pointer value indicates there is no user in the data base with user ID uid. */

Pointer getpwuid (int uid);

/* * int setreuid (uid_t ruid, uid_t euid) */ int setreuid (int ruid, int euid);

/* * int chmod (const char *filename, mode_t mode) */ int chmod (String filename, int mode);

}

public boolean start() {

final IntByReference status = new IntByReference();

if ((pid = CLibrary.INSTANCE.fork()) == 0) { try { String[] cmd = new String[]{"ping", "localhost"}; int i = CLibrary.INSTANCE.execvp(cmd[0], cmd); //System.out.println("forked"); //System.exit(0); } catch (Exception ex) { ex.printStackTrace(); } //System.exit(0); // CLibrary.INSTANCE.exit(-1); } // child code else if (pid > 0) { System.out.println("started process " + pid);

executor.execute(new Runnable() {

public void run() { System.out.println("waiting"); int r = CLibrary.INSTANCE.waitpid(pid, status, 0); if (r == pid) setExitCode(status.getValue()); } });

return true; } // parent process else if (pid < 0) { System.out.println("failed to fork: " + pid); return false; } return false;

}

void kill() { CLibrary.INSTANCE.kill(pid, 9); }

void setExitCode(int code) { System.out.println("exit code "+code); }

public static void main(String[] args) { ForkTest t = new ForkTest(); //System.getProperties().list(System.out); t.start(); try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } t.kill();