chiark / gitweb /
fishdescriptor: debugging
authorIan Jackson <ian.jackson@eu.citrix.com>
Wed, 18 Oct 2017 15:58:55 +0000 (16:58 +0100)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Wed, 18 Oct 2017 15:58:55 +0000 (16:58 +0100)
Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
fishdescriptor/donate.c [deleted file]
fishdescriptor/fishdescriptor [new file with mode: 0755]
fishdescriptor/py/fishdescriptor/fish.py
fishdescriptor/py/fishdescriptor/indonor.py

diff --git a/fishdescriptor/donate.c b/fishdescriptor/donate.c
deleted file mode 100644 (file)
index 11c51db..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2009 Citrix Ltd.
- * Copyright (C) 2017 Citrix Ltd.
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-static int fishdescriptor_sendmsg_fds(int carrier,
-                                      int nfds, const int fds[]) {
-  /* return convention: like a syscall */
-  struct msghdr msg = { 0 };
-  struct cmsghdr *cmsg;
-  size_t spaceneeded = nfds * sizeof(fds[0]);
-  char control[CMSG_SPACE(spaceneeded)];
-  struct iovec iov;
-  int r;
-
-  iov.iov_base = &nfds;
-  iov.iov_len  = sizeof(nfds);
-
-  /* compose the message */
-  msg.msg_iov = &iov;
-  msg.msg_iovlen = 1;
-  msg.msg_control = control;
-  msg.msg_controllen = sizeof(control);
-
-  /* attach open fd */
-  cmsg = CMSG_FIRSTHDR(&msg);
-  cmsg->cmsg_level = SOL_SOCKET;
-  cmsg->cmsg_type = SCM_RIGHTS;
-  cmsg->cmsg_len = CMSG_LEN(spaceneeded);
-  memcpy(CMSG_DATA(cmsg), fds, spaceneeded);
-
-  msg.msg_controllen = cmsg->cmsg_len;
-    
-  r = sendmsg(carrier, &msg, 0);
-  if (r < 0) return -1;
-
-  return 0;
-}
-
-int fishdescriptor_donate(const char *path, const int *fds) {
-  /* return convention: returns errno value */
-  /* within function: r is like syscall return, errno value is in errno */
-  int r;
-  int esave = errno;
-  int carrier=-1;
-
-  carrier = socket(AF_UNIX, SOCK_STREAM, 0);
-  if (carrier < 0) { r=-1; goto out; }
-
-  struct sockaddr_un suna;
-  memset(&suna,0,sizeof(suna));
-  suna.sun_family = AF_UNIX;
-  if (strlen(path) >= sizeof(suna.sun_path)) { errno=E2BIG; r=-1; goto out; }
-  strcpy(suna.sun_path, path);
-
-  r = connect(carrier, (const struct sockaddr*)&suna, sizeof(suna));
-  if (r) goto out;
-
-  int nfds;
-  for (nfds=0; fds[nfds] > 0; nfds++);
-
-  r = fishdescriptor_sendmsg_fds(carrier, nfds, fds);
-  if (r) goto out;
-
-  r = 0;
- out:
-  if (carrier >= 0) close(carrier);
-  r = !r ? 0 : !errno ? EIO : errno;
-  errno = esave;
-  return r;
-}
diff --git a/fishdescriptor/fishdescriptor b/fishdescriptor/fishdescriptor
new file mode 100755 (executable)
index 0000000..4708401
--- /dev/null
@@ -0,0 +1,11 @@
+#!/usr/bin/python3
+
+import sys
+import fishdescriptor.fish
+
+pid = int(sys.argv[1])
+fds = map(int, sys.argv[2:])
+
+d = fishdescriptor.fish.Donor(pid)
+r = d.fish(fds)
+print(repr(r))
index 95694ff2eaceac3eb59c1b0d672eadf9405c0885..9c7fca839e44ae5c3c923952ee5019be1617d2f2 100644 (file)
@@ -6,18 +6,18 @@ import os
 import pwd
 
 def _shuffle_fd3():
 import pwd
 
 def _shuffle_fd3():
-    os.dup(1,3)
-    os.dup(2,1)
+    os.dup2(1,3)
+    os.dup2(2,1)
 
 class Donor():
     def __init__(d, pid):
         d._pid = pid
         d._sp = subprocess.Popen(
 
 class Donor():
     def __init__(d, pid):
         d._pid = pid
         d._sp = subprocess.Popen(
-            preexec_fn = _suffle_fd3,
+            preexec_fn = _shuffle_fd3,
             stdin = subprocess.PIPE,
             stdout = subprocess.PIPE,
             close_fds = False,
             stdin = subprocess.PIPE,
             stdout = subprocess.PIPE,
             close_fds = False,
-            args = ['gdb', '-p', pid, '-batch', '-ex'
+            args = ['gdb', '-p', str(pid), '-batch', '-ex',
                     'python import fishdescriptor.indonor as id;'+
                     ' id.DonorImplementation().eval_loop()'
                 ]
                     'python import fishdescriptor.indonor as id;'+
                     ' id.DonorImplementation().eval_loop()'
                 ]
index 046e6f5251f99464e920ccd115d454a8b5f05123..1f3c68994feabe4715f89b8de51dfc7ffe15cd14 100644 (file)
@@ -51,7 +51,7 @@ class DonorStructLayout():
         l._posns = { }
         for f in x.type.fields():
             l._posns[f.name] = len(l._template)
         l._posns = { }
         for f in x.type.fields():
             l._posns[f.name] = len(l._template)
-            try f.type.fields(): blank = '{ }'
+            try: f.type.fields(); blank = '{ }'
             except AttributeError: blank = '0'
             l._template.append(blank)
     def substitute(l, values):
             except AttributeError: blank = '0'
             l._template.append(blank)
     def substitute(l, values):
@@ -68,7 +68,7 @@ class DonorImplementation():
 
     # assembling structs
     # sigh, we have to record the order of the arguments!
 
     # assembling structs
     # sigh, we have to record the order of the arguments!
-    def di._find_fields(typename):
+    def _find_fields(typename):
         try:
             fields = di._structs[typename]
         except AttributeError:
         try:
             fields = di._structs[typename]
         except AttributeError:
@@ -76,7 +76,7 @@ class DonorImplementation():
             di._structs[typename] = fields
         return fields
 
             di._structs[typename] = fields
         return fields
 
-    def di._make(typename, values):
+    def _make(typename, values):
         fields = di._find_fields(typename)
         return fields.substitute(values)
 
         fields = di._find_fields(typename)
         return fields.substitute(values)
 
@@ -133,7 +133,7 @@ class DonorImplementation():
             'int (*)(int, const struct sockaddr*, socklen_t)',
             'connect',
             '(%d, (const struct sockaddr*)%s, sizeof(struct sockaddr_un))'
             'int (*)(int, const struct sockaddr*, socklen_t)',
             'connect',
             '(%d, (const struct sockaddr*)%s, sizeof(struct sockaddr_un))'
-            % (fd, _lit_addressof(addr)
+            % (fd, _lit_addressof(addr))
         )
 
     def _close(di, fd):
         )
 
     def _close(di, fd):
@@ -160,7 +160,7 @@ class DonorImplementation():
         to_restore = di._saved_errno
         di._saved_errno = None
         if to_restore is not None:
         to_restore = di._saved_errno
         di._saved_errno = None
         if to_restore is not None:
-            gdb.parse_and_eval('errno = %d' % to_restore))
+            gdb.parse_and_eval('errno = %d' % to_restore)
 
     # main entrypoints
 
 
     # main entrypoints