* Syscall.cs: Make all fork(2) and exec(2) functions `private`. It
authorJonathan Pryor <jpryor@novell.com>
Wed, 20 Apr 2005 11:29:20 +0000 (11:29 -0000)
committerJonathan Pryor <jpryor@novell.com>
Wed, 20 Apr 2005 11:29:20 +0000 (11:29 -0000)
  currently isn't safe to call these under *any* circumstances.

svn path=/trunk/mcs/; revision=43324

mcs/class/Mono.Posix/Mono.Unix/ChangeLog
mcs/class/Mono.Posix/Mono.Unix/Syscall.cs

index 4bf01251932af9d01816aa7ea3551d6f5b48ae04..c4b5d2502c9f1e84e8f857b6cac6dcaa826eea08 100644 (file)
@@ -1,3 +1,31 @@
+2005-04-20  Jonathan Pryor <jonpryor@vt.edu>
+
+       * Syscall.cs: Make all fork(2) and exec(2) functions `private`.  It
+         currently isn't safe to call these under *any* circumstances.  See also
+         68141, and this pertinent quote from Butenhof's 
+         "Programming with POSIX Threads", p197, s6.1:
+         
+             "When a threaded process calls fork to create a child process,
+             Pthreads specifies that only the thread calling fork exists in the
+             child. ... Pthreads does not 'terminate' the other threads in a forked
+             process...They simply cease to exist.  ... This is not a problem if
+             the child process is about to call exec to run a new program, but if
+             you use fork to clone a threaded program, beware that you may lose
+             access to memory, especially heap memory stored only as
+             thread-specific data values."
+         
+         Since P/Invoke currently requires using thread local storage, once you
+         fork(2) you won't be able to invoke exec(2) from managed code (since that
+         would require a P/Invoke transition to call exec(2), which would require
+         TLS, which doesn't exist in the new process).
+        
+         This can only be fixed by removing the TLS dependency on P/Invoke, which
+         isn't a priority (and may not be possible).
+        
+         The workaround is to create a C function which does your fork(2)/exec(2)
+         (and any other functions such as daemon(3)) on your behalf, and P/Invoke
+         to call this C function.
+
 2005-04-18  Jonathan Pryor <jonpryor@vt.edu>
 
        * Syscall.cs: Update comment specifying which functions belong in Syscall.
index ef17f2239aa144205e81ba75b9385a535ee06633..bc5317eaeb7a30204b05857486642ad4ae366dc1 100644 (file)
@@ -2329,17 +2329,17 @@ namespace Mono.Unix {
 
                // TODO: does Mono marshal arrays properly?
                [DllImport (LIBC, SetLastError=true)]
-               public static extern int execve (string path, string[] argv, string[] envp);
+               private static extern int execve (string path, string[] argv, string[] envp);
 
                [DllImport (LIBC, SetLastError=true)]
-               public static extern int fexecve (int fd, string[] argv, string[] envp);
+               private static extern int fexecve (int fd, string[] argv, string[] envp);
 
                [DllImport (LIBC, SetLastError=true)]
-               public static extern int execv (string path, string[] argv);
+               private static extern int execv (string path, string[] argv);
 
                // TODO: execle, execl, execlp
                [DllImport (LIBC, SetLastError=true)]
-               public static extern int execvp (string path, string[] argv);
+               private static extern int execvp (string path, string[] argv);
 
                [DllImport (LIBC, SetLastError=true)]
                public static extern int nice (int inc);
@@ -2488,14 +2488,14 @@ namespace Mono.Unix {
                [DllImport (LIBC, SetLastError=true)]
                [Obsolete ("DO NOT directly call fork(2); it bypasses essential " + 
                                "shutdown code.\nUse System.Diagnostics.Process instead")]
-               public static extern int fork ();
+               private static extern int fork ();
 
                // vfork(2)
                //    pid_t vfork(void);
                [DllImport (LIBC, SetLastError=true)]
                [Obsolete ("DO NOT directly call vfork(2); it bypasses essential " + 
                                "shutdown code.\nUse System.Diagnostics.Process instead")]
-               public static extern int vfork ();
+               private static extern int vfork ();
 
                [DllImport (LIBC, SetLastError=true, EntryPoint="ttyname")]
                private static extern IntPtr sys_ttyname (int fd);