home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / gnu / make3_60.lzh / MAKE3_60 / REMOTE-C.C < prev    next >
C/C++ Source or Header  |  1993-07-30  |  6KB  |  201 lines

  1. /* Copyright (C) 1988, 1989 Free Software Foundation, Inc.
  2. This file is part of GNU Make.
  3.  
  4. GNU Make is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 1, or (at your option)
  7. any later version.
  8.  
  9. GNU Make is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with GNU Make; see the file COPYING.  If not, write to
  16. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #include "make.h"
  19. #include "commands.h"
  20. #include "customs.h"
  21. #include <sys/time.h>
  22.  
  23.  
  24. char *remote_description = "Customs";
  25.  
  26.  
  27. /* ExportPermit gotten by start_remote_job_p, and used by start_remote_job.  */
  28. static ExportPermit permit;
  29.  
  30. /* Return nonzero if the next job should be done remotely.  */
  31.  
  32. int
  33. start_remote_job_p ()
  34. {
  35.   if (Customs_Host (EXPORT_SAME, &permit) != RPC_SUCCESS)
  36.     return 0;
  37.  
  38.   return !CUSTOMS_FAIL (&permit.addr);
  39. }
  40.  
  41. /* Start a remote job running the command in ARGV.
  42.    It gets standard input from STDIN_FD.  On failure,
  43.    return nonzero.  On success, return zero, and set
  44.    *USED_STDIN to nonzero if it will actually use STDIN_FD,
  45.    zero if not, set *ID_PTR to a unique identification, and
  46.    set *IS_REMOTE to zero if the job is local, nonzero if it
  47.    is remote (meaning *ID_PTR is a process ID).  */
  48.  
  49. int
  50. start_remote_job (argv, stdin_fd, is_remote, id_ptr, used_stdin)
  51.      char **argv;
  52.      int stdin_fd;
  53.      int *is_remote;
  54.      int *id_ptr;
  55.      int *used_stdin;
  56. {
  57.   extern char **environ;
  58.   extern int vfork (), execve ();
  59.   char cwd[MAXPATHLEN];
  60.   char waybill[MAX_DATA_SIZE], msg[128];
  61.   struct timeval timeout;
  62.   struct sockaddr_in sin;
  63.   int len;
  64.   int retsock, retport, sock;
  65.   Rpc_Stat status;
  66.   int pid;
  67.  
  68.   /* Find the current directory.  */
  69.   if (getwd (cwd) == 0)
  70.     {
  71.       error ("exporting: getwd: %s", cwd);
  72.       return 1;
  73.     }
  74.  
  75.   /* Create the return socket.  */
  76.   retsock = Rpc_UdpCreate (True, 0);
  77.   if (retsock < 0)
  78.     {
  79.       error ("exporting: Couldn't create return socket.");
  80.       return 1;
  81.     }
  82.  
  83.   /* Get the return socket's port number.  */
  84.   len = sizeof(sin);
  85.   if (getsockname (retsock, (struct sockaddr *) &sin, &len) < 0)
  86.     {
  87.       (void) close (retsock);
  88.       perror_with_name ("exporting: ", "getsockname");
  89.       return 1;
  90.     }
  91.   retport = sin.sin_port;
  92.  
  93.   /* Create the TCP socket for talking to the remote child.  */
  94.   sock = Rpc_TcpCreate (False, 0);
  95.  
  96.   /* Create a WayBill to give to the server.  */
  97.   len = Customs_MakeWayBill (&permit, cwd, argv[0], argv,
  98.                  environ, retport, waybill);
  99.  
  100.   /* Send the request to the server, timing out in 20 seconds.  */
  101.   timeout.tv_usec = 0;
  102.   timeout.tv_sec = 20;
  103.   sin.sin_family = AF_INET;
  104.   sin.sin_port = htons (Customs_Port ());
  105.   sin.sin_addr = permit.addr;
  106.   status = Rpc_Call (sock, &sin, (Rpc_Proc) CUSTOMS_IMPORT,
  107.              len, (Rpc_Opaque) waybill,
  108.              sizeof(msg), (Rpc_Opaque) msg,
  109.              1, &timeout);
  110.   if (status != RPC_SUCCESS)
  111.     {
  112.       (void) close (retsock);
  113.       (void) close (sock);
  114.       error ("exporting: %s", Rpc_ErrorMessage (status));
  115.       return 1;
  116.     }
  117.   else if (msg[0] != 'O' || msg[1] != 'k' || msg[2] != '\0')
  118.     {
  119.       (void) close (retsock);
  120.       (void) close (sock);
  121.       error ("CUSTOMS_IMPORT: %s", msg);
  122.       return 1;
  123.     }
  124.  
  125.   fflush (stdout);
  126.   fflush (stderr);
  127.  
  128.   pid = vfork ();
  129.   if (pid < 0)
  130.     {
  131.       /* The fork failed!  */
  132.       perror_with_name ("vfork", "");
  133.       return 1;
  134.     }
  135.   else if (pid == 0)
  136.     {
  137.       /* Child side.  Run `export' to handle the connection.  */
  138.       static char sock_buf[20], retsock_buf[20], id_buf[20];
  139.       static char *new_argv[6] =
  140.     { "export", "-id", sock_buf, retsock_buf, id_buf, 0 };
  141.  
  142.       /* Set up the arguments.  */
  143.       (void) sprintf (sock_buf, "%d", sock);
  144.       (void) sprintf (retsock_buf, "%d", retsock);
  145.       (void) sprintf (id_buf, "%x", permit.id);
  146.  
  147.       /* Run the command.  */
  148.       (void) execvp (new_argv[0], new_argv);
  149.       perror_with_name ("execvp: ", new_argv[0]);
  150.       _exit (127);
  151.     }
  152.  
  153.   /* Parent side.  Return the `export' process's ID.  */
  154.   (void) close (retsock);
  155.   (void) close (sock);
  156.   *is_remote = 0;
  157.   *id_ptr = pid;
  158.   return 0;
  159. }
  160.  
  161. /* Get the status of a dead remote child.  Block waiting for one to die
  162.    if BLOCK is nonzero.  Set *EXIT_CODE_PTR to the exit status, *SIGNAL_PTR
  163.    to the termination signal or zero if it exited normally, and *COREDUMP_PTR
  164.    nonzero if it dumped core.  Return the ID of the child that died,
  165.    0 if we would have to block and !BLOCK, or < 0 if there were none.  */
  166.  
  167. int
  168. remote_status (exit_code_ptr, signal_ptr, coredump_ptr, block)
  169.      int *exit_code_ptr, *signal_ptr, *coredump_ptr;
  170.      int block;
  171. {
  172.   return -1;
  173. }
  174.  
  175. /* Block asynchronous notification of remote child death.
  176.    If this notification is done by raising the child termination
  177.    signal, do not block that signal.  */
  178. void
  179. block_remote_children ()
  180. {
  181.   return;
  182. }
  183.  
  184. /* Restore asynchronous notification of remote child death.
  185.    If this is done by raising the child termination signal,
  186.    do not unblock that signal.  */
  187. void
  188. unblock_remote_children ()
  189. {
  190.   return;
  191. }
  192.  
  193. /* Send signal SIG to child ID.  Return 0 if successful, -1 if not.  */
  194. int
  195. remote_kill (id, sig)
  196.      int id;
  197.      int sig;
  198. {
  199.   return -1;
  200. }
  201.