bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[patch]gnu tar 1.19 system.c - VMS stuff


From: John E. Malmberg
Subject: [patch]gnu tar 1.19 system.c - VMS stuff
Date: Tue, 01 Apr 2008 00:09:08 -0500
User-agent: Mozilla/5.0 (X11; U; OpenVMS AlphaServer_DS10_617_MHz; en-US; rv:1.7) Gecko/20040621

Just like on rtapelib, the vms vfork() does not really fork, it sets up a longjump, and the exec* command starts up the child.

VMS C library maps pipes to a device known as a mailbox, and unlike pipes, mailboxes are small, limited to 65535 bytes. So for the output pipe, in external module, a special routine that buffers the mailbox into virtual memory was added. It is in a separate module.

The file descriptor for that pipe is also stored in an external routine because special action to signal EOF is needed when it is closed. The routines that I implemented to allow open() and close() to work also signal that EOF.

Tar 1.19 is now working on VMS as well as I can test it.

In addition to the supplied files, I needed to add the following files.

The gnv$*.c_first and gnv$first_include.h files are pre-pended to the files of the same name before the compile is done. This allows me to make vms specific modifications, and also to manipulate compiler options.

Along with other things, these implement the fdopen() and dirfd() routine that gnulib wants to see.

The gnv$*.opt files specify additional modules and options to be linked in.

The setup_tar_build.com sets up VMS symbols for the subsequent build.

The vms_configure.sh is the parameters needed to get the configure script to run, and the gnv$conftest.c_first is modifications to the conftest.c files to get the configure tests to either pretend that VMS supports a required feature, or corrects the test to actually produce the correct results on VMS.

The make*.sh files set some VMS specific environment variables to make the GNV port of bash and CC/LD emulation work more like the UNIX build environment expects.

The [vms_common] modules are common to multiple projects, two modules are used for gnu tar, one is a pre-init module that runs before main() to put the VMS CRTL into a more UNIX like mode, and the other is a routine to make VMS mailboxes contain more data like a UNIX pipe. The vms_common.mms is makefile that is VMS specific.

So do you want to look over the gnv$* and such to integrate into the gnu tar source, or do you prefer to leave them separate?

I still have to write the script that puts the VMS gnu tar kit into a installable kit.

Directory LCL_ROOT:[tar-1^.19]

setup_tar_build.com;2


EAGLE> dir [...]gnv$*.*;

Directory LCL_ROOT:[tar-1^.19]

gnv$conftest.c_first;19

Total of 1 file.

Directory LCL_ROOT:[tar-1^.19.lib]

gnv$argmatch.c_first;3                  gnv$argp-fmtstream.c_first;4
gnv$argp-help.c_first;3 gnv$error.c_first;3 gnv$fchdir.c_first;69
gnv$getcwd.c_first;8                    gnv$getdate.c_first;3
gnv$rtapelib.c_first;6                  gnv$savedir.c_first;1
gnv$strtoimax.c_first;2                 gnv$strtoumax.c_first;1
gnv$xstrtoumax.c_first;3

Total of 12 files.

Directory LCL_ROOT:[tar-1^.19.lib.uniwidth]

gnv$first_include.h;1

Total of 1 file.

Directory LCL_ROOT:[tar-1^.19.src]

gnv$buffer.c_first;5                    gnv$compare.c_first;2
gnv$create.c_first;9                    gnv$extract.c_first;32
gnv$incremen.c_first;6 gnv$list.c_first;3 gnv$misc.c_first;7 gnv$names.c_first;9 gnv$sparse.c_first;3 gnv$system.c_first;9
gnv$tar.c_first;6   gnv$tar.opt;3       gnv$update.c_first;2
gnv$xheader.c_first;3

Total of 14 files.

Directory LCL_ROOT:[tar-1^.19.tests]

gnv$genfile.c_first;5                   gnv$genfile.opt;1

Total of 2 files.

EAGLE> dir [...]make_tar*.sh;,vms_configure.sh;

Directory LCL_ROOT:[tar-1^.19]

make_tar.sh;13      make_tar_debug.sh;6 make_tar_install.sh;1
vms_configure.sh;11

Directory LCL_ROOT:[vms_common]

vms_crtl_init.c;13  vms_vm_pipe.c;2     vms_common.mms;15

-John
address@hidden
Personal Opinion Only
--- /src_root/tar-1.19/src/system.c     Sun Aug 26 03:56:55 2007
+++ /lcl_root/tar-1.19/src/system.c     Mon Mar 31 23:06:53 2008
@@ -202,6 +202,10 @@
     }
 }
 
+#ifdef __VMS
+#define xfork vfork
+#endif
+
 void
 sys_spawn_shell (void)
 {
@@ -313,6 +317,7 @@
   pid_t child_pid;
   int wait_status;
 
+#ifndef __VMS
   xpipe (parent_pipe);
   child_pid = xfork ();
 
@@ -331,6 +336,7 @@
 
   xdup2 (parent_pipe[PREAD], STDIN_FILENO);
   xclose (parent_pipe[PWRITE]);
+#endif
 
   /* Check if we need a grandchild tar.  This happens only if either:
      a) the file is to be accessed by rmt: compressor doesn't know how;
@@ -356,12 +362,47 @@
              errno = saved_errno;
              open_fatal (archive_name_array[0]);
            }
+#ifdef __VMS
+        {
+         int save_stdout;
+
+         /* VMS is always in the Parent process on both returns on vfork() */
+         /* So need to save what ever the STDOUT fileno is using and restore */
+         save_stdout = dup(STDOUT_FILENO);
+
+         /* VMS pipes too small, so create a better one */
+         vms_fifo_write_pipe(parent_pipe);
+
+         child_pid = vfork ();
+         if (child_pid > 0)
+           {
+             /* The parent tar is still here!  Just clean up.  */
+
+             archive = parent_pipe[PWRITE];
+
+             /* Need to handle the close special */
+             vms_save_fd_info(archive, NULL, NULL, 1, 0);
+
+             xclose (parent_pipe[PREAD]);
+             xdup2(save_stdout, STDOUT_FILENO);
+             return child_pid;
+           }
+         decc$set_child_standard_streams(parent_pipe[PREAD], -1, -1);
+        }
+#endif
          xdup2 (archive, STDOUT_FILENO);
        }
       execlp (use_compress_program_option, use_compress_program_option, NULL);
       exec_fatal (use_compress_program_option);
     }
 
+#ifdef __VMS
+    /* VMS does not have a true fork, so no possiblity of grandchildren */
+    /* Getting here means we did not fork or open the archive */
+    archive = -1;
+    return -1;
+#else
+
   /* We do need a grandchild tar.  */
 
   xpipe (child_pipe);
@@ -462,6 +503,7 @@
     exit_status = WEXITSTATUS (wait_status);
 
   exit (exit_status);
+#endif
 }
 
 /* Set ARCHIVE for uncompressing, then reading an archive.  */
@@ -474,6 +516,7 @@
   pid_t child_pid;
   int wait_status;
 
+#ifndef __VMS
   xpipe (parent_pipe);
   child_pid = xfork ();
 
@@ -492,6 +535,7 @@
 
   xdup2 (parent_pipe[PWRITE], STDOUT_FILENO);
   xclose (parent_pipe[PREAD]);
+#endif
 
   /* Check if we need a grandchild tar.  This happens only if either:
      a) we're reading stdin: to force unblocking;
@@ -508,6 +552,27 @@
       archive = open (archive_name_array[0], O_RDONLY | O_BINARY, MODE_RW);
       if (archive < 0)
        open_fatal (archive_name_array[0]);
+
+#ifdef __VMS
+      {
+       int save_stdin;
+
+       save_stdin = dup(STDIN_FILENO);
+       xpipe (parent_pipe);
+       decc$set_child_standard_streams(-1, parent_pipe[PWRITE], -1);
+       child_pid = vfork();
+       /* VMS is aways the parent on return  */
+
+       if (child_pid > 0)
+         {
+           /* The parent tar is still here!  Just clean up.  */
+           archive = parent_pipe[PREAD];
+           xclose (parent_pipe[PWRITE]);
+           xdup2(save_stdin, STDIN_FILENO);
+           return child_pid;
+         }
+      }
+#endif
       xdup2 (archive, STDIN_FILENO);
       execlp (use_compress_program_option, use_compress_program_option,
              "-d", (char *) 0);
@@ -516,6 +581,13 @@
 
   /* We do need a grandchild tar.  */
 
+#ifdef __VMS
+    /* VMS does not have a real fork() so no possibility of a grandchild */
+    /* Getting here means we did not vfork(). or open the archive */
+    archive = -1;
+    return -1;
+#else
+
   xpipe (child_pipe);
   grandchild_pid = xfork ();
 
@@ -600,6 +672,7 @@
     exit_status = WEXITSTATUS (wait_status);
 
   exit (exit_status);
+#endif
 }
 
 


reply via email to

[Prev in Thread] Current Thread [Next in Thread]