hawq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r...@apache.org
Subject [18/28] incubator-hawq git commit: HAWQ-837. Add python modules into HAWQ code
Date Tue, 21 Jun 2016 02:41:34 GMT
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/sunos_process.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/sunos_process.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/sunos_process.c
new file mode 100644
index 0000000..596341c
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/sunos_process.c
@@ -0,0 +1,1021 @@
+/* The MIT License
+ *
+ * Copyright (C) 2008-2009 Floris Bruynooghe
+ *
+ * Copyright (C) 2008-2009 Abilisoft Ltd.
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* SunOS implementation of the Process classes */
+
+
+#include <Python.h>
+
+
+/* We do not want to use the large file compilation environment as <procfs.h>
+ * doesn't play nice with that on ILP32 (32-bit machines), but <Python.h>, via
+ * pyconfig.h, sets the environment up for this so we need to reverse that.
+ * The transitional large file compilation environment (where the function
+ * sources are xxx64() instead and no mapping of the xxx symbols to xxx64
+ * symbols happens) is fine, so we leave _LARGEFILE64_SOURCE set.  See the
+ * lfcompile(5) and lfcompile64(5) manpages for notes on mixing objects from
+ * different compilation environments: basically just don't share global
+ * variables across them. */
+#undef _FILE_OFFSET_BITS
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <procfs.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/proc.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+#if SUNOS5_MINOR >= 10
+#include <zone.h>
+#endif
+
+#include "psi.h"
+#include "process.h"
+#include "procfs_utils.h"
+#include "posix_utils.h"
+
+
+/***** Local declarations *****/
+static int parse_psinfo(struct psi_process *proci,
+                        const pid_t pid,
+                        psinfo_t **psinfop);
+static int parse_as(struct psi_process *proci,
+                    const pid_t pid,
+                    psinfo_t *psinfo);
+static int parse_usage(struct psi_process *proci, const pid_t pid);
+static double calc_pcpu(ushort_t pr_pctcpu);
+#if SUNOS5_MINOR >= 10
+static int set_cwd(struct psi_process *proci, const pid_t pid);
+static char *get_terminal(dev_t ttydev);
+static char *get_zonename(zoneid_t zoneid);
+#endif
+
+static int set_args_from_as(struct psi_process *proci,
+                            const struct psinfo *psinfo,
+                            const int asfd);
+static int set_args_from_argv(struct psi_process *proci,
+                              const off_t *argv,
+                              const psinfo_t *psinfo,
+                              const int asfd);
+static int set_env_from_as(struct psi_process *proci,
+                           const struct psinfo *psinfo,
+                           const int asfd);
+static int set_envv_from_envp(struct psi_process *proci,
+                              const int envc,
+                              const off_t *envp,
+                              const psinfo_t *psinfo,
+                              const int asfd);
+static int set_exe(struct psi_process *proci,
+                   const pid_t pid,
+                   const psinfo_t *psinfo);
+static int set_args_env_from_fork(struct psi_process *proci,
+                                  const psinfo_t *psinfo);
+static char *find_sargs64(void);
+static int read_sargs64_pipe(struct psi_process *proci,
+                             const psinfo_t *psinfo,
+                             const int pipe);
+
+
+/***** Public interfaces from process.h. *****/
+
+
+/* The process status flags. */
+#define addflag(CONST) {"PROC_STATUS_"#CONST, CONST}
+struct psi_flag psi_arch_proc_status_flags[] = {
+    addflag(SIDL),
+    addflag(SRUN),
+    addflag(SSLEEP),
+    addflag(SSTOP),
+    addflag(SZOMB),
+#ifdef SONPROC
+    addflag(SONPROC),
+#endif
+#ifdef SWAIT
+    addflag(SWAIT),
+#endif
+    {NULL, 0}
+};
+
+
+/** Collect all information about a process
+ *
+ * The psinfo variable is so that /proc/<pid>/psinfo only needs to be read
+ * once.
+ */
+struct psi_process *
+psi_arch_process(const pid_t pid)
+{
+    struct psi_process *proci;
+    psinfo_t *psinfo;
+
+    if (procfs_check_pid(pid) < 0)
+        return NULL;
+    proci = psi_calloc(sizeof(struct psi_process));
+    if (proci == NULL)
+        return NULL;
+    if (parse_psinfo(proci, pid, &psinfo) < 0) {
+        psi_FREE(psinfo);
+        return psi_free_process(proci);
+    }
+    if (set_exe(proci, pid, psinfo) < 0) {
+        psi_free(psinfo);
+        return psi_free_process(proci);
+    }
+    if (parse_as(proci, pid, psinfo) < 0) {
+        psi_free(psinfo);
+        return psi_free_process(proci);
+    }
+    psi_free(psinfo);
+    if (parse_usage(proci, pid) < 0)
+        return psi_free_process(proci);
+#if SUNOS5_MINOR >= 10
+    if (set_cwd(proci, pid) < 0)
+        return psi_free_process(proci);
+#endif
+    return proci;
+}
+
+
+/***** Local functions *****/
+
+
+/** Parse information from /proc/<pid>/psinfo
+ *
+ * The `psinfop' argument will point to the `psinfo_t' structure or NULL.  The
+ * caller *has* to call psi_free on it if it is non NULL.  This means when an
+ * error arises in this function this function itself *should not* free the
+ * `psinfo' structure.
+ */
+static int
+parse_psinfo(struct psi_process *proci, const pid_t pid, psinfo_t **psinfop)
+{
+    psinfo_t *psinfo;
+    int bufsize;
+
+    bufsize = procfs_read_procfile((char**)&psinfo, pid, "psinfo");
+    *psinfop = psinfo;
+    if (bufsize == -1)
+        return -1;
+    if (bufsize == -2) {
+        proci->name_status = PSI_STATUS_PRIVS;
+        proci->argc_status = PSI_STATUS_PRIVS;
+        proci->command_status = PSI_STATUS_PRIVS;
+        proci->nthreads_status = PSI_STATUS_PRIVS;
+        proci->ppid_status = PSI_STATUS_PRIVS;
+        proci->pgrp_status = PSI_STATUS_PRIVS;
+        proci->sid_status = PSI_STATUS_PRIVS;
+        proci->ruid_status = PSI_STATUS_PRIVS;
+        proci->euid_status = PSI_STATUS_PRIVS;
+        proci->rgid_status = PSI_STATUS_PRIVS;
+        proci->egid_status = PSI_STATUS_PRIVS;
+        proci->euser_status = PSI_STATUS_PRIVS;
+        proci->ruser_status = PSI_STATUS_PRIVS;
+        proci->egroup_status = PSI_STATUS_PRIVS;
+        proci->rgroup_status = PSI_STATUS_PRIVS;
+        proci->vsz_status = PSI_STATUS_PRIVS;
+        proci->rss_status = PSI_STATUS_PRIVS;
+        proci->terminal_status = PSI_STATUS_PRIVS;
+        proci->pcpu_status = PSI_STATUS_PRIVS;
+        proci->start_time_status = PSI_STATUS_PRIVS;
+        proci->cputime_status = PSI_STATUS_PRIVS;
+        proci->exe_status = PSI_STATUS_PRIVS;
+        proci->status_status = PSI_STATUS_PRIVS;
+        proci->nice_status = PSI_STATUS_PRIVS;
+        proci->priority_status = PSI_STATUS_PRIVS;
+        proci->zoneid_status = PSI_STATUS_PRIVS;
+        proci->zonename_status = PSI_STATUS_PRIVS;
+        return 0;
+    }
+    if (bufsize != sizeof(psinfo_t)) {
+        PyErr_Format(PyExc_OSError,
+                     "Unexpected psinfo file size: %d instead of %d",
+                     bufsize, sizeof(psinfo_t));
+        return -1;
+    }
+    proci->name = (char *)psi_malloc(PRFNSZ); /* XXX or strlen()? */
+    if (proci->name == NULL)
+        return -1;
+    strcpy(proci->name, psinfo->pr_fname);
+    proci->name_status = PSI_STATUS_OK;
+    proci->argc = psinfo->pr_argc;
+    proci->argc_status = PSI_STATUS_OK;
+    proci->command = psi_strdup(psinfo->pr_psargs);
+    if (proci->command == NULL)
+        return -1;
+    proci->command_status = PSI_STATUS_OK;
+#if SUNOS5_MINOR >= 10
+    proci->nthreads = psinfo->pr_nlwp + psinfo->pr_nzomb;
+#else
+    proci->nthreads = psinfo->pr_nlwp;
+#endif
+    proci->nthreads_status = PSI_STATUS_OK;
+    proci->ppid = psinfo->pr_ppid;
+    proci->ppid_status = PSI_STATUS_OK;
+    proci->pgrp = psinfo->pr_pgid;
+    proci->pgrp_status = PSI_STATUS_OK;
+    proci->sid = psinfo->pr_sid;
+    proci->sid_status = PSI_STATUS_OK;
+    proci->ruid = psinfo->pr_uid;
+    proci->ruid_status = PSI_STATUS_OK;
+    proci->euid = psinfo->pr_euid;
+    proci->euid_status = PSI_STATUS_OK;
+    proci->rgid = psinfo->pr_gid;
+    proci->rgid_status = PSI_STATUS_OK;
+    proci->egid = psinfo->pr_egid;
+    proci->egid_status = PSI_STATUS_OK;
+    /* XXX rss & vsz are size_t on SunOS! */
+    proci->vsz = psinfo->pr_size * 1024;
+    proci->vsz_status = PSI_STATUS_OK;
+    proci->rss = (psinfo->pr_rssize) * 1024;
+    proci->rss_status = PSI_STATUS_OK;
+#if SUNOS5_MINOR >= 10
+    proci->terminal = get_terminal(psinfo->pr_ttydev);
+    if (proci->terminal == NULL && PyErr_Occurred() != NULL)
+        return -1;
+    proci->terminal_status = PSI_STATUS_OK;
+#endif
+    proci->pcpu = calc_pcpu(psinfo->pr_pctcpu);
+    proci->pcpu_status = PSI_STATUS_OK;
+    proci->start_time.tv_sec = psinfo->pr_start.tv_sec;
+    proci->start_time.tv_nsec = psinfo->pr_start.tv_nsec;
+    proci->start_time_status = PSI_STATUS_OK;
+    proci->cputime.tv_sec = psinfo->pr_time.tv_sec;
+    proci->cputime.tv_nsec = psinfo->pr_time.tv_nsec;
+    proci->cputime_status = PSI_STATUS_OK;
+    proci->status = psinfo->pr_lwp.pr_state;
+    proci->status_status = PSI_STATUS_OK;
+    proci->nice = psinfo->pr_lwp.pr_nice;
+    proci->nice_status = PSI_STATUS_OK;
+    proci->priority = psinfo->pr_lwp.pr_pri;
+    proci->priority_status = PSI_STATUS_OK;
+#if SUNOS5_MINOR >= 10
+    proci->zoneid = psinfo->pr_zoneid;
+    proci->zoneid_status = PSI_STATUS_OK;
+    proci->zonename = get_zonename(proci->zoneid);
+    if (proci->zonename == NULL)
+        return -1;
+    proci->zonename_status = PSI_STATUS_OK;
+#endif
+    *psinfop = psinfo;
+    return 0;
+}
+
+
+/** Parse the process address space: /proc/<pid>/as
+ *
+ * The argv, envc and envv slots are filled in from this.
+ *
+ * Care should be taken here as this is the address space image of the process
+ * it is not coverted to the data model of us (normally ILP32) like the rest
+ * of /proc, so it could be either ILP32 or LP64.
+ */
+static int
+parse_as(struct psi_process *proci, const pid_t pid, psinfo_t *psinfo)
+{
+    char *path;
+    int r;
+    int asfd;
+
+    if (psinfo->pr_dmodel != PR_MODEL_ILP32 &&
+        psinfo->pr_dmodel != PR_MODEL_LP64) {
+        /* Kernel threads/processes/LWPs. */
+        proci->argv_status = PSI_STATUS_NA;
+        proci->envc_status = PSI_STATUS_NA;
+        proci->envv_status = PSI_STATUS_NA;
+        return 0;
+    }
+#ifdef _ILP32
+    if (psinfo->pr_dmodel == PR_MODEL_LP64)
+        return set_args_env_from_fork(proci, psinfo);
+#endif
+    r = psi_asprintf(&path, "/proc/%d/as", pid);
+    if (r < 0)
+        return -1;
+    asfd = open(path, O_RDONLY);
+    if (asfd < 0) {
+        if (errno == EACCES || errno == EPERM) {
+            psi_free(path);
+            proci->argv_status = PSI_STATUS_PRIVS;
+            proci->envc_status = PSI_STATUS_PRIVS;
+            proci->envv_status = PSI_STATUS_PRIVS;
+            return 0;
+        } else if (errno == ENOENT) {
+            PyErr_SetFromErrnoWithFilename(PsiExc_NoSuchProcessError, path);
+            psi_free(path);
+            return -1;
+        } else {
+            PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
+            psi_free(path);
+            return -1;
+        }
+    }
+    psi_free(path);
+    if (set_args_from_as(proci, psinfo, asfd) < 0) {
+        close(asfd);
+        return -1;
+    }
+    if (set_env_from_as(proci, psinfo, asfd) < 0) {
+        close(asfd);
+        return -1;
+    }
+    close(asfd);
+    return 0;
+}
+
+
+static int
+parse_usage(struct psi_process *proci, const pid_t pid)
+{
+    prusage_t *prusage;
+    int bufsize;
+
+    bufsize = procfs_read_procfile((char**)&prusage, pid, "usage");
+    if (bufsize == -1)
+        return -1;
+    if (bufsize == -2) {
+        proci->utime_status = PSI_STATUS_PRIVS;
+        proci->stime_status = PSI_STATUS_PRIVS;
+        PyErr_Clear();
+        return 0;
+    }
+    if (bufsize != sizeof(prusage_t)) {
+        PyErr_Format(PyExc_OSError,
+                     "Unexpected status file size: %d instead of %d",
+                     bufsize, sizeof(prusage_t));
+        psi_free(prusage);
+        return -1;
+    }
+    proci->utime.tv_sec = prusage->pr_utime.tv_sec;
+    proci->utime.tv_nsec = prusage->pr_utime.tv_nsec;
+    proci->utime_status = PSI_STATUS_OK;
+    proci->stime.tv_sec = prusage->pr_stime.tv_sec;
+    proci->stime.tv_nsec = prusage->pr_stime.tv_nsec;
+    proci->stime_status = PSI_STATUS_OK;
+    psi_free(prusage);
+    return 0;
+}
+
+
+#if SUNOS5_MINOR >= 10
+static int
+set_cwd(struct psi_process *proci, const pid_t pid)
+{
+    char *path;
+    char *link;
+    int r;
+
+    r = psi_asprintf(&path, "/proc/%d/path/cwd", pid);
+    if (r == -1)
+        return -1;
+    r = psi_readlink(&link, path);
+    psi_free(path);
+    if (r == -2) {
+        PyErr_Clear();
+        proci->cwd_status = PSI_STATUS_PRIVS;
+    } else if (r < 0) {
+        procfs_check_pid(pid); /* OSError -> NoSuchProcessError if required */
+        return -1;
+    } else {
+        proci->cwd = psi_strdup(link);
+        psi_free(link);
+        proci->cwd_status = PSI_STATUS_OK;
+    }
+    return 0;
+}
+#endif
+
+
+#if SUNOS5_MINOR >= 10
+/* XXX For other solaris versions consider searching though /dev until the
+ *     device is found like is done on AIX. */
+/** Find the terminal associated with ttydev
+ *
+ * This is derrived from solaris ps:
+ * http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/ps/ps.c
+ * Unfortunately this only seems to work for SUNOS 5.10 and higher.  Also
+ * _ttyname_dev() is probably an internal function, it appears in the symbol
+ * table of libc.so.1 however.
+ *
+ * The name of the terminal is returned or NULL.  NULL is not always an error,
+ * it can just be there is no terminal (in which case python will see `None'
+ * so check with PyErr_Occurred().
+ */
+extern char *_ttyname_dev(dev_t, char *, size_t);
+
+static char *
+get_terminal(dev_t ttydev)
+{
+    char devname[TTYNAME_MAX];
+    char *rv;
+    int l;
+
+    if (ttydev == PRNODEV)
+        return NULL;
+    rv = _ttyname_dev(ttydev, devname, sizeof(devname));
+    if (rv == NULL)
+        return NULL;
+    l = strlen(devname);
+    rv = (char *)psi_malloc(l+1);
+    if (rv == NULL)
+        return NULL;
+    return strncpy(rv, devname, l+1);
+}
+#endif
+
+static double
+calc_pcpu(ushort_t pr_pctcpu)
+{
+    uint_t value = pr_pctcpu;
+
+    value = ((value*1000) + 0x7000) >> 15;
+    if (value >= 1000)
+        value  = 999;
+    return (double)value/10.0;
+}
+
+
+#if SUNOS5_MINOR >= 10
+static char *
+get_zonename(zoneid_t zoneid)
+{
+    char zonename[ZONENAME_MAX];
+    char *name;
+    size_t reqsize;
+
+    reqsize = getzonenamebyid(zoneid, zonename, ZONENAME_MAX);
+    if (reqsize < 0)
+        return (char*)PyErr_SetFromErrno(PyExc_OSError);
+    name = psi_malloc(reqsize);
+    if (name == NULL)
+        return NULL;
+    strncpy(name, zonename, reqsize);
+    return name;
+}
+#endif
+
+
+/** Read bits in the process address space to extract `argv'
+ *
+ * This depends on the internal representation of the argv array: the base
+ * address of the entire array is pointed too by psinfo.pr_argv and this can't
+ * change, meaning that psinfo.pr_argc denotes the number of elements in the
+ * array.  From this it is possible to create our own version of argv in the
+ * psi_process structure.
+ *
+ * Note that this function will never be called if we're a 32-bit Python
+ * looking at a 64-bit process so no need to detect this.  This means off_t is
+ * always a valid way of pointing to an address in the address space.
+ */
+static int
+set_args_from_as(struct psi_process *proci,
+                 const struct psinfo *psinfo,
+                 const int asfd)
+{
+    off_t argvoff = (off_t)psinfo->pr_argv;
+    off_t *argv;                /* not caddr_t due to casting issues */
+    caddr32_t *argv32;
+    ssize_t r;
+    int i;
+
+    /* First read in the array of pointers, this depends on the data model. */
+    if (psinfo->pr_dmodel == PR_MODEL_ILP32) {
+        argv32 = (caddr32_t*)psi_malloc(psinfo->pr_argc*sizeof(caddr32_t));
+        if (argv32 == NULL)
+            return -1;
+        r = pread(asfd, argv32, psinfo->pr_argc*sizeof(caddr32_t), argvoff);
+        if (r < 0) {
+            PyErr_SetFromErrno(PyExc_OSError);
+            psi_free(argv32);
+            return -1;
+        }
+        argv = (off_t*)psi_malloc(psinfo->pr_argc*sizeof(off_t));
+        if (argv == NULL) {
+            psi_free(argv32);
+            return -1;
+        }
+        for (i = 0; i < psinfo->pr_argc; i++)
+            argv[i] = (off_t)argv32[i];
+        psi_free(argv32);
+    } else {                    /* LP64 */
+        argv = (off_t*)psi_malloc(psinfo->pr_argc*sizeof(off_t));
+        if (argv == NULL)
+            return -1;
+        r = pread(asfd, argv, psinfo->pr_argc*sizeof(off_t), argvoff);
+        if (r < 0) {
+            PyErr_SetFromErrno(PyExc_OSError);
+            psi_free(argv);
+            return -1;
+        }
+    }
+
+    /* Now read each arg from the address space and place it into proci. */
+    i = set_args_from_argv(proci, argv, psinfo, asfd);
+    psi_free(argv);
+    if (i < 0)
+        return -1;
+    return 0;
+}
+
+
+/** Read the arguments from the address space pointed to by argv
+ *
+ * The pointers of where to read from in the address space (pointed to by the
+ * `asfd' file descriptor) are read from `argv' (which is of lenght
+ * `psinfo->pr_argc').  The result is stored in `proci->argv'.
+ *
+ * Note that proci->argv will get freed by psi_arch_process() in case of
+ * failure, so as soon as we assign an arch to it we don't have to worry about
+ * freeing it anymore in case of an error.
+ */
+static int
+set_args_from_argv(struct psi_process *proci,
+                   const off_t *argv,
+                   const psinfo_t *psinfo,
+                   const int asfd)
+{
+    off_t argoff;
+    char *arg;
+    char *ptr;
+    int argsize;
+    ssize_t r;
+    int i;
+
+    proci->argv = (char**)psi_calloc(psinfo->pr_argc*sizeof(char*));
+    if (proci->argv == NULL)
+        return -1;
+    for (i = 0; i  < psinfo->pr_argc; i++) {
+        argoff = argv[i];
+        argsize = 50;
+        arg = (char*)psi_malloc(argsize);
+        if (arg == NULL)
+            return -1;
+        ptr = arg;
+        *ptr = 'a';
+        while (*ptr != '\0') {  /* read and grow buffer if required */
+            proci->argv[i] = arg;
+            r = pread(asfd, arg, argsize, argoff);
+            if (r < 0) {
+                PyErr_SetFromErrno(PyExc_OSError);
+                return -1;
+            }
+            for (ptr = arg; ptr-arg < argsize-1; ptr++)
+                if (*ptr == '\0')
+                    break;
+            if (*ptr != '\0') {
+                argsize += 50;
+                ptr = (char*)psi_realloc(arg, argsize);
+                if (ptr == NULL)
+                    return -1;
+                arg = ptr;
+            }
+        }
+    }
+    proci->argv_status = PSI_STATUS_OK;
+    return 0;
+}
+
+
+
+/** Read bits in the process address space to extract `envp'
+ *
+ * This depends on the internal representation of the envp array: the base
+ * address of the entire array is pointed too by psinfo.pr_envp and POSIX
+ * defines that it is NULL terminated.
+ *
+ * Note that this function will never be called if we're a 32-bit Python
+ * looking at a 64-bit process so no need to detect this.  This means off_t is
+ * always a valid way of pointing to an address in the address space.
+ *
+ * XXX This is too much code for one function.
+ */
+static int
+set_env_from_as(struct psi_process *proci,
+                const struct psinfo *psinfo,
+                const int asfd)
+{
+    off_t envpoff = (off_t)psinfo->pr_envp;
+    off_t *envp;
+    off_t *ptr;
+    caddr32_t *envp32;
+    caddr32_t *ptr32;
+    ssize_t r;
+    int array_size = 50;
+    int envc = 0;
+    int i;
+
+
+    /* First read in the array of pointers, this depends on the data model. */
+    if (psinfo->pr_dmodel == PR_MODEL_ILP32) {
+        envp32 = (caddr32_t*)psi_malloc(array_size*sizeof(caddr32_t));
+        if (envp32 == NULL)
+            return -1;
+        do {
+            r = pread(asfd, envp32, array_size*sizeof(caddr32_t), envpoff);
+            if (r < 0) {
+                PyErr_SetFromErrno(PyExc_OSError);
+                psi_free(envp32);
+                return -1;
+            }
+            ptr32 = envp32;
+            for (i = 0; i < array_size; i++) {
+                ptr32++;
+                if (*ptr32 == (caddr32_t)NULL) {
+                    envc = i + 1;
+                    break;
+                }
+            }
+            if (*ptr32 != (caddr32_t)NULL) { /* array was too small */
+                array_size += 50;
+                ptr32 = (caddr32_t*)psi_realloc(envp32,
+                                                array_size*sizeof(caddr32_t));
+                if (ptr32 == NULL) {
+                    psi_free(envp32);
+                    return -1;
+                }
+                envp32 = ptr32;
+            }
+        } while (*ptr32 != (caddr32_t)NULL);
+        envp = (off_t*)psi_malloc(envc*sizeof(off_t));
+        if (envp == NULL) {
+            psi_free(envp32);
+            return -1;
+        }
+        for (i = 0; i < envc; i++)
+            envp[i] = (off_t)envp32[i];
+        psi_free(envp32);
+    } else {                    /* LP64 */
+        envp = (off_t*)psi_malloc(array_size*sizeof(off_t));
+        if (envp == NULL)
+            return -1;
+        do {
+            r = pread(asfd, envp, array_size*sizeof(off_t), envpoff);
+            if (r < 0) {
+                PyErr_SetFromErrno(PyExc_OSError);
+                psi_free(envp);
+                return -1;
+            }
+            ptr = envp;
+            for (i = 0; i < array_size; i++) {
+                ptr++;
+                if (*ptr == (off_t)NULL) {
+                    envc = i + 1;
+                    break;
+                }
+            }
+            if (*ptr != (off_t)NULL) { /* array was too small */
+                array_size += 50;
+                ptr = (off_t*)psi_realloc(envp, array_size*sizeof(off_t));
+                if (ptr == NULL) {
+                    psi_free(envp);
+                    return -1;
+                }
+                envp = ptr;
+            }
+        } while (*ptr != (off_t)NULL);
+    }
+
+    /* Now we copy the environment vector into the psi_process structure. */
+    i = set_envv_from_envp(proci, envc, envp, psinfo, asfd);
+    psi_free(envp);
+    if (i < 0)
+        return -1;
+    proci->envc = envc;
+    proci->envc_status = PSI_STATUS_OK;
+    return 0;
+}
+
+
+static int
+set_envv_from_envp(struct psi_process *proci,
+                    const int envc,
+                    const off_t *envp,
+                    const psinfo_t *psinfo,
+                    const int asfd)
+{
+    off_t envoff;
+    char *env;
+    char *ptr;
+    ssize_t r;
+    int envsize;
+    int i;
+
+    proci->envv = (char**)psi_calloc(envc*sizeof(char*));
+    if (proci->envv == NULL)
+        return -1;
+    for (i = 0; i  < envc; i++) {
+        envoff = envp[i];
+        envsize = 50;
+        env = (char*)psi_malloc(envsize);
+        if (env == NULL)
+            return -1;
+        ptr = env;
+        *ptr = 'a';
+        while (*ptr != '\0') {  /* read and grow buffer if required */
+            proci->envv[i] = env;
+            r = pread(asfd, env, envsize, envoff);
+            if (r < 0) {
+                PyErr_SetFromErrno(PyExc_OSError);
+                return -1;
+            }
+            for (ptr = env; ptr-env < envsize; ptr++)
+                if (*ptr == '\0')
+                    break;
+            if (*ptr != '\0') {
+                envsize += 50;
+                ptr = (char*)psi_realloc(env, envsize);
+                if (ptr == NULL)
+                    return -1;
+                env = ptr;
+            }
+        }
+    }
+    proci->envv_status = PSI_STATUS_OK;
+    return 0;
+}
+
+
+/** Set the exe and exe_status fields of the psi_process structure
+ *
+ * Returns -1 on failure, 0 on success.
+ */
+static int
+set_exe(struct psi_process *proci, const pid_t pid, const psinfo_t *psinfo)
+{
+#if SUNOS5_MINOR >= 10
+    char *fname;
+    char *link;
+    int r;
+
+    r = psi_asprintf(&fname, "/proc/%d/path/a.out", pid);
+    if (r == -1)
+        return -1;
+    r = psi_readlink(&link, fname);
+    psi_free(fname);
+    if (r < 0) {
+	PyErr_Clear();
+#endif
+        proci->exe = (char *)psi_malloc(PRFNSZ); /* XXX or strlen()? */
+        if (proci->exe == NULL)
+            return -1;
+        strcpy(proci->exe, psinfo->pr_fname);
+        proci->exe_status = PSI_STATUS_OK;
+#if SUNOS5_MINOR >= 10
+    } else {
+        proci->exe = link;
+        proci->exe_status = PSI_STATUS_OK;
+    }
+#endif
+    return 0;
+}
+
+
+/** Set argv, envc and envv by forking to 64-bit application
+ *
+ * This function gets called when we're a 32-bit Python trying to read the
+ * arguments and environment arrays from a 64-bit application.  We can't do
+ * that ourself so we have to call sargs64.so which is a 64-bit helper
+ * program.
+ *
+ * sargs64.so must get the PID of the process as an argument and will write
+ * the results on it's standard output.  The data format of result is:
+ * "arg0\0arg1\0...\0\0env0\0env1\0...\0\0".  So you get a NULL-terminated
+ * array for the argument list, followed by a NULL terminated array of the
+ * environment.  Once all information is sent sargs64.so will close the
+ * filedescriptor.  Unless sargs64.so return 0 the output should not be
+ * trusted.  If sargs64.so returns 2 then there was a permissions problem.
+ *
+ * Implementation notes
+ *
+ * The pipes[0] is read from in this process, pipes[1] gets written to in
+ * sargs64.so.
+ *
+ * We use fork1() (Solaris specific, not POSIX) since Solaris < 10 is not
+ * POSIX compliant and fork() there is an alias for forkall() which copies all
+ * the threads.  And we don't want any threads in the child.
+ *
+ * XXX This function is too large.
+ */
+static int
+set_args_env_from_fork(struct psi_process *proci, const psinfo_t *psinfo)
+{
+    char *pid_str;
+    char *sargs64;
+    int pipes[2];
+    int child_stat;
+    pid_t child_pid;
+    int rv;
+
+    sargs64 = find_sargs64();
+    if (sargs64 == NULL)
+        return -1;
+    if (psi_asprintf(&pid_str, "%ld", (long)psinfo->pr_pid) < 0) {
+        psi_free(sargs64);
+        return -1;
+    }
+    if (pipe(pipes) == -1) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        psi_free(sargs64);
+        psi_free(pid_str);
+        return -1;
+    }
+    child_pid = fork1();
+    if (child_pid == -1) {               /* error */
+        PyErr_SetFromErrno(PyExc_OSError);
+        psi_free(sargs64);
+        psi_free(pid_str);
+        return -1;
+    } else if (child_pid == 0) {        /* child */
+        if (close(pipes[0]) == -1)
+            exit(1);
+        if (dup2(pipes[1], 1) == -1)
+            exit(1);
+        if (close(pipes[1]) == -1)
+            exit(1);
+        execl(sargs64, "sargs64.so", pid_str, NULL);
+        exit(1);
+    } else {                    /* parent */
+        psi_free(sargs64);
+        psi_free(pid_str);
+        if (close(pipes[1]) == -1) {
+            PyErr_SetFromErrno(PyExc_OSError);
+            close(pipes[0]);
+            return -1;
+        }
+        rv = read_sargs64_pipe(proci, psinfo, pipes[0]);
+        if (close(pipes[0]) == -1) {
+            PyErr_SetFromErrno(PyExc_OSError);
+            return -1;
+        }
+        if (waitpid(child_pid, &child_stat, 0) == -1) {
+            PyErr_SetFromErrno(PyExc_OSError);
+            return -1;
+        }
+        if (!WIFEXITED(child_stat)) {
+            /* Someone changed the status of our child, clean it up. */
+            while (!WIFSIGNALED(child_stat) || !WIFEXITED(child_stat)) {
+                if (kill(child_pid, SIGTERM) == -1) {
+                    PyErr_SetFromErrno(PyExc_OSError);
+                    return -1;
+                }
+                if (WIFSTOPPED(child_stat)) {
+                    if (kill(child_pid, SIGCONT) == -1) {
+                        PyErr_SetFromErrno(PyExc_OSError);
+                        return -1;
+                    }
+                }
+                if (waitpid(child_pid, &child_stat, 0) == -1) {
+                    PyErr_SetFromErrno(PyExc_OSError);
+                    return -1;
+                }
+            }
+            PyErr_SetString(PyExc_OSError, "sargs64.so did not exit normally");
+            return -1;
+        }
+        if (WEXITSTATUS(child_stat) == 2) {
+            proci->argv_status = PSI_STATUS_PRIVS;
+            proci->envc_status = PSI_STATUS_PRIVS;
+            proci->envv_status = PSI_STATUS_PRIVS;
+            return 0;
+        } else if (WEXITSTATUS(child_stat) != 0) {
+            PyErr_SetString(PyExc_OSError, "sargs64.so failed");
+            procfs_check_pid(psinfo->pr_pid == 0);
+            return -1;
+        } else
+            return rv;
+    }
+}
+
+
+/** Return the path of sargs64.so
+ *
+ * On success the path of the sargs64.so executable is returned.  Returns NULL
+ * on failure.  The returned value must be freed using psi_free().
+ */
+static char *
+find_sargs64(void)
+{
+    PyObject *mod;
+    char *sargs64;
+    char *file;
+    char *p;
+    int l;
+
+    mod = PyImport_ImportModuleNoBlock("psi.process");
+    if (mod == NULL)
+        return NULL;
+    file = PyModule_GetFilename(mod);
+    Py_DECREF(mod);
+    if (file == NULL)
+        return NULL;
+    l = strlen(file);
+    sargs64 = (char *)psi_malloc(l + 11);
+    strncpy(sargs64, file, l+1);
+    p = strrchr(sargs64, '/') + 1;
+    strcpy(p, "sargs64.so");
+    p += 10;
+    *p = '\0';
+    return sargs64;
+}
+
+
+/** Read the data from sargs64.so via the pipe
+ *
+ * The format is described above in the set_args_env_from_fork() function.
+ * This sets the argv, argv_status, envv and envv_status slots in the procinfo
+ * structure if successful.  If incomplete data is read an exception is set
+ * and -1 is returned.
+ */
+static int
+read_sargs64_pipe(struct psi_process *proci,
+                  const psinfo_t *psinfo,
+                  const int pipe)
+{
+    char *buf, *ptr, *envbuf;
+    ssize_t bytes;
+    int bufsize = 100;
+
+    /* Read buffer from pipe. */
+    buf = (char*)psi_malloc(bufsize + 2);
+    if (buf == NULL)
+        return -1;
+    ptr = buf;
+    while ((bytes = read(pipe, ptr, 100)))
+        if (bytes == 100) {
+            bufsize += 100;
+            ptr = psi_realloc(buf, bufsize + 2);
+            if (ptr == NULL) {
+                psi_free(buf);
+                return -1;
+            }
+            buf = ptr;
+            ptr = buf + bufsize - 100;
+        }
+    buf[bufsize-1] = '\0';        /* Ensure buffer ends in '\0\0' */
+    buf[bufsize] = '\0';
+
+    /* Parse argv. */
+    ptr = strchr(buf, '\0');
+    while (*(ptr+1) != '\0') {
+        ptr = strchr(ptr+1, '\0');
+        if (ptr == NULL) {
+            psi_free(buf);
+            PyErr_SetString(PyExc_OSError, "Invalid data from sargs64.so");
+            return -1;
+        }
+    }
+    proci->argc = psi_strings_count(buf, ptr-buf+1);
+    proci->argv = psi_strings_to_array(buf, proci->argc);
+    proci->argc_status = PSI_STATUS_OK;
+    proci->argv_status = PSI_STATUS_OK;
+
+    /* Parse envv. */
+    envbuf = ptr + 2;
+    if (envbuf-buf > bufsize-2) {
+        psi_free(buf);
+        PyErr_SetString(PyExc_OSError, "Invalid data from sargs64.so");
+        return -1;
+    }
+    ptr = strchr(envbuf, '\0');
+    while (*(ptr+1) != '\0') {
+        ptr = strchr(ptr+1, '\0');
+        if (ptr == NULL) {
+            psi_free(buf);
+            PyErr_SetString(PyExc_OSError, "Invalid data from sargs64.so");
+            return -1;
+        }
+    }
+    proci->envc = psi_strings_count(envbuf, ptr-envbuf+1);
+    proci->envv = psi_strings_to_array(envbuf, proci->envc);
+    proci->envc_status = PSI_STATUS_OK;
+    proci->envv_status = PSI_STATUS_OK;
+    psi_free(buf);
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/sunos_psi.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/sunos_psi.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/sunos_psi.c
new file mode 100644
index 0000000..e59dafb
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/sunos_psi.c
@@ -0,0 +1,66 @@
+/* The MIT License
+ *
+ * Copyright (C) 2009 Floris Bruynooghe
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* SunOS implementations of the _psi non-POSIX functions */
+
+
+#include <Python.h>
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#include <utmpx.h>
+
+#include "psifuncs.h"
+#include "posix_utils.h"
+
+
+/***** Public functions *****/
+
+
+int
+arch_boottime(struct timespec *boottime)
+{
+    return posix_utmpx_boottime(boottime);
+}
+
+
+int
+arch_uptime(struct timespec *uptime)
+{
+    struct timespec utbt;
+    struct timespec now;
+    struct timeval tvnow;
+
+    if (posix_utmpx_boottime(&utbt) < 0)
+        return -1;
+    if (gettimeofday(&tvnow, NULL) < 0) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        return -1;
+    }
+    now.tv_sec = tvnow.tv_sec;
+    now.tv_nsec = tvnow.tv_usec * 1000;
+    *uptime = posix_timespec_subtract(&now, &utbt);
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/archmodule.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/archmodule.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/archmodule.c
new file mode 100644
index 0000000..38b6934
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/archmodule.c
@@ -0,0 +1,210 @@
+/* The MIT License
+ *
+ * Copyright (C) 2008-2009 Floris Bruynooghe
+ *
+ * Copyright (C) 2008-2009 Abilisoft Ltd.
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* The psi.arch module  */
+
+
+#include <Python.h>
+
+#include "psi.h"
+#include "arch.h"
+
+
+/* Declarations (we need these since we use -Wmissing-declarations) */
+#ifdef PY3K
+PyMODINIT_FUNC PyInit_arch(void);
+#else
+PyMODINIT_FUNC initarch(void);
+#endif
+
+
+/* Re-declare these as non-extern since we're providing the symbols */
+PyObject *PsiExc_AttrNotAvailableError = NULL;
+PyObject *PsiExc_AttrInsufficientPrivsError = NULL;
+PyObject *PsiExc_AttrNotImplementedError = NULL;
+
+
+/* More constants */
+static char MODULE_NAME[] = "psi.arch";
+PyDoc_STRVAR(MODULE_DOC, "Module for system architecture information");
+
+
+/* The psi.arch.arch_type() function */
+static PyObject *
+psi_arch_type(PyObject *self, PyObject *args)
+{
+    return PsiArch_New();
+}
+
+
+/** Finalise the types
+ *
+ * Calls PyType_Ready() and does anything else required.
+ */
+static int
+prepare_types(void)
+{
+    if (PyType_Ready(&PsiArchBase_Type) < 0)
+        return -1;
+    if (PyType_Ready(&PsiArchLinux_Type) < 0)
+        return -1;
+    if (PyType_Ready(&PsiArchSunOS_Type) < 0)
+        return -1;
+    if (PyType_Ready(&PsiArchDarwin_Type) < 0)
+        return -1;
+    if (PyType_Ready(&PsiArchAIX_Type) < 0)
+        return -1;
+    Py_INCREF(&PsiArchBase_Type);
+    Py_INCREF(&PsiArchLinux_Type);
+    Py_INCREF(&PsiArchSunOS_Type);
+    Py_INCREF(&PsiArchDarwin_Type);
+    Py_INCREF(&PsiArchAIX_Type);
+    return 0;
+}
+
+
+/** Initialise the global exceptions
+ *
+ * If this function fails the modinit function will Py_XDECREF the exceptions,
+ * so no need to do that here.
+ */
+static int
+init_exceptions(void)
+{
+    PyObject *_psimod;
+
+    _psimod = PyImport_ImportModule("psi._psi");
+    if (_psimod == NULL)
+        return -1;
+    PsiExc_AttrNotAvailableError = PyObject_GetAttrString(
+        _psimod, "AttrNotAvailableError");
+    if (PsiExc_AttrNotAvailableError == NULL)
+        goto error;
+    PsiExc_AttrInsufficientPrivsError = PyObject_GetAttrString(
+        _psimod, "AttrInsufficientPrivsError");
+    if (PsiExc_AttrInsufficientPrivsError == NULL)
+        goto error;
+    PsiExc_AttrNotImplementedError = PyObject_GetAttrString(
+        _psimod, "AttrNotImplementedError");
+    if (PsiExc_AttrNotImplementedError == NULL)
+        goto error;
+    Py_DECREF(_psimod);
+    return 0;
+
+  error:
+    Py_DECREF(_psimod);
+    return -1;
+}
+
+
+/* Add all the objects to the module */
+static int
+add_module_objects(PyObject *mod)
+{
+    if (PyModule_AddObject(mod, "ArchBase",
+                           (PyObject *)&PsiArchBase_Type) < 0)
+        return -1;
+    if (PyModule_AddObject(mod, "ArchLinux",
+                           (PyObject *)&PsiArchLinux_Type) < 0)
+        return -1;
+    if (PyModule_AddObject(mod, "ArchSunOS",
+                           (PyObject *)&PsiArchSunOS_Type) < 0)
+        return -1;
+    if (PyModule_AddObject(mod, "ArchDarwin",
+                           (PyObject *)&PsiArchDarwin_Type) < 0)
+        return -1;
+    if (PyModule_AddObject(mod, "ArchAIX",
+                           (PyObject *)&PsiArchAIX_Type) < 0)
+        return -1;
+    return 0;
+}
+
+
+static PyMethodDef arch_methods[] = {
+    {"arch_type", psi_arch_type, METH_NOARGS,
+     PyDoc_STR("Return an object representing the current architecture type")},
+    {NULL, NULL, 0, NULL}        /* Sentinel */
+};
+
+
+#ifdef PY3K
+static struct PyModuleDef moduledef = {
+        PyModuleDef_HEAD_INIT,  /* m_base */
+        MODULE_NAME,            /* m_name */
+        MODULE_DOC,             /* m_doc */
+        -1,                     /* m_size */
+        arch_methods,           /* m_methods */
+        NULL,                   /* m_reload */
+        NULL,                   /* m_traverse */
+        NULL,                   /* m_clear */
+        NULL                    /* m_free */
+};
+#endif
+
+
+/* Some defines to make the module init function readable */
+#ifdef PY3K
+#define MODFUNC PyInit_arch
+#define RETURN(VAR) return VAR
+#else
+#define MODFUNC initarch
+#define RETURN(VAR) return
+#endif
+
+
+/* Returns the psi.arch module */
+PyMODINIT_FUNC
+MODFUNC(void)
+{
+    PyObject *mod = NULL;
+
+    if (prepare_types() < 0)
+        RETURN(NULL);
+    if (init_exceptions() < 0)
+        goto error;
+#ifdef PY3K
+    mod = PyModule_Create(&moduledef);
+#else
+    mod = Py_InitModule3(MODULE_NAME, arch_methods, MODULE_DOC);
+#endif
+    if (mod == NULL)
+        goto error;
+    if (add_module_objects(mod) < 0)
+        goto error;
+    RETURN(mod);
+
+  error:
+    Py_XDECREF(mod);
+    Py_XDECREF(PsiExc_AttrNotAvailableError);
+    Py_XDECREF(PsiExc_AttrInsufficientPrivsError);
+    Py_XDECREF(PsiExc_AttrNotImplementedError);
+    Py_DECREF(&PsiArchBase_Type);
+    Py_DECREF(&PsiArchLinux_Type);
+    Py_DECREF(&PsiArchSunOS_Type);
+    Py_DECREF(&PsiArchDarwin_Type);
+    Py_DECREF(&PsiArchAIX_Type);
+    RETURN(NULL);
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/mount.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/mount.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/mount.c
new file mode 100644
index 0000000..422c313
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/mount.c
@@ -0,0 +1,502 @@
+/* The MIT License
+ *
+ * Copyright (C) 2009 Erick Tryzelaar
+ *
+ * Copyright (C) 2009 Floris Bruynooghe
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/** psi.mount.Mount* classes
+ *
+ * This file contains the common support for the psi.mount.Mount classes and
+ * factory functions.
+ */
+
+
+#include <Python.h>
+
+#include "psi.h"
+#include "mount.h"
+#include "posix_utils.h"
+
+
+/* The Python MountBase object */
+typedef struct {
+    PyObject_HEAD
+    psi_mountinfo_t *mounti;
+} PsiMountBaseObject;
+
+
+/* Helper functions */
+
+
+/* Always returns NULL */
+void *
+psi_free_mountinfo(psi_mountinfo_t *mounti)
+{
+    psi_FREE(mounti->mount_type);
+    psi_FREE(mounti->mount_options);
+    psi_FREE(mounti->mount_path);
+    psi_FREE(mounti->filesystem_host);
+    psi_FREE(mounti->filesystem_path);
+    psi_free(mounti);
+    return NULL;
+}
+
+
+/* Always returns NULL */
+void *
+psi_free_mountlist(psi_mountlist_t *mountlist)
+{
+    int i;
+
+    for (i = 0; i < mountlist->count; ++i) {
+        if (mountlist->mounts[i] != NULL) {
+            psi_free_mountinfo(mountlist->mounts[i]);
+        }
+    }
+    psi_free(mountlist->mounts);
+    psi_free(mountlist);
+    return NULL;
+}
+
+
+/* MountBase methods */
+
+
+static void
+MountBase_dealloc(PsiMountBaseObject *self)
+{
+    if (self->mounti != NULL) {
+        psi_free_mountinfo(self->mounti);
+    }
+    Py_TYPE(self)->tp_free((PyObject*)self);
+}
+
+
+static PyObject *
+MountBase_repr(PsiMountBaseObject *self)
+{
+    return PyStr_FromFormat("%s()", Py_TYPE(self)->tp_name);
+}
+
+
+/** Check if object is initialised */
+static int
+check_init(PsiMountBaseObject *obj)
+{
+    if (obj->mounti == NULL) {
+        PyErr_SetString(PyExc_RuntimeError,
+                        "Instance has not been initialised properly");
+        return -1;
+    }
+    return 0;
+}
+
+
+static PyObject *
+MountBase_get_fstype(PsiMountBaseObject *self)
+{
+    if (check_init(self) == -1)
+        return NULL;
+    if (psi_checkattr("Mount.fstype", self->mounti->mount_type_status) < 0)
+        return NULL;
+    return PyStr_FromString(self->mounti->mount_type);
+}
+
+
+static PyObject *
+MountBase_get_options(PsiMountBaseObject *self)
+{
+    if (check_init(self) == -1)
+        return NULL;
+    if (psi_checkattr("Mount.options",
+                      self->mounti->mount_options_status) < 0)
+        return NULL;
+    return PyStr_FromString(self->mounti->mount_options);
+}
+
+
+static PyObject *
+MountBase_get_mountpoint(PsiMountBaseObject *self)
+{
+    if (check_init(self) == -1)
+        return NULL;
+    if (psi_checkattr("Mount.mountpoint", self->mounti->mount_path_status) < 0)
+        return NULL;
+    return PyStr_FromString(self->mounti->mount_path);
+}
+
+
+static PyObject *
+MountBase_get_device(PsiMountBaseObject *self)
+{
+    if (check_init(self) == -1)
+        return NULL;
+    if (psi_checkattr("Mount.device", self->mounti->filesystem_path_status) < 0)
+        return NULL;
+    return PyStr_FromString(self->mounti->filesystem_path);
+}
+
+
+static PyObject *
+MountBase_get_total(PsiMountBaseObject *self, void *closure)
+{
+    PyObject *fr = NULL;
+    PyObject *tot = NULL;
+    PyObject *r = NULL;
+
+    if (check_init(self) < 0)
+        return NULL;
+    if (psi_checkattr("Mount.total", self->mounti->frsize_status) < 0 ||
+        psi_checkattr("Mount.total", self->mounti->total_status) < 0)
+        return NULL;
+    fr = PyLong_FromUnsignedLong(self->mounti->frsize);
+    if (fr == NULL)
+        goto end;
+    tot = PyLong_FromUnsignedLong(self->mounti->total);
+    if (tot == NULL)
+        goto end;
+    r = PyNumber_Multiply(fr, tot);
+
+  end:
+    Py_XDECREF(fr);
+    Py_XDECREF(tot);
+    return r;
+}
+
+
+static PyObject *
+MountBase_get_free(PsiMountBaseObject *self, void *closure)
+{
+    PyObject *fr = NULL;
+    PyObject *free = NULL;
+    PyObject *r = NULL;
+
+    if (check_init(self) < 0)
+        return NULL;
+    if (psi_checkattr("Mount.free", self->mounti->frsize_status) < 0 ||
+        psi_checkattr("Mount.free", self->mounti->ffree_status) < 0)
+        return NULL;
+    fr = PyLong_FromUnsignedLong(self->mounti->frsize);
+    if (fr == NULL)
+        goto end;
+    free = PyLong_FromUnsignedLong(self->mounti->ffree);
+    if (free == NULL)
+        goto end;
+    r = PyNumber_Multiply(fr, free);
+
+  end:
+    Py_XDECREF(fr);
+    Py_XDECREF(free);
+    return r;
+}
+
+
+static PyObject *
+MountBase_get_avail(PsiMountBaseObject *self, void *closure)
+{
+    PyObject *fr = NULL;
+    PyObject *avail = NULL;
+    PyObject *r = NULL;
+
+    if (check_init(self) < 0)
+        return NULL;
+    if (psi_checkattr("Mount.available", self->mounti->frsize_status) < 0 ||
+        psi_checkattr("Mount.available", self->mounti->favail_status) < 0)
+        return NULL;
+    fr = PyLong_FromUnsignedLong(self->mounti->frsize);
+    if (fr == NULL)
+        goto end;
+    avail = PyLong_FromUnsignedLong(self->mounti->favail);
+    if (avail == NULL)
+        goto end;
+    r = PyNumber_Multiply(fr, avail);
+
+  end:
+    Py_XDECREF(fr);
+    Py_XDECREF(avail);
+    return r;
+}
+
+
+static PyObject *
+MountBase_get_inodes(PsiMountBaseObject *self, void *closure)
+{
+    if (check_init(self) < 0)
+        return NULL;
+    if (psi_checkattr("Mount.inodes", self->mounti->files_status) < 0)
+        return NULL;
+    return PyLong_FromUnsignedLong(self->mounti->files);
+}
+
+
+static PyObject *
+MountBase_get_free_inodes(PsiMountBaseObject *self, void *closure)
+{
+    if (check_init(self) < 0)
+        return NULL;
+    if (psi_checkattr("Mount.free_inodes", self->mounti->ffree_status) < 0)
+        return NULL;
+    return PyLong_FromUnsignedLong(self->mounti->ffree);
+}
+
+
+static PyObject *
+MountBase_get_available_inodes(PsiMountBaseObject *self, void *closure)
+{
+    if (check_init(self) < 0)
+        return NULL;
+    if (psi_checkattr("Mount.available_inodes", self->mounti->favail_status)<0)
+        return NULL;
+    return PyLong_FromUnsignedLong(self->mounti->favail);
+}
+
+
+static PyObject *
+MountBase_refresh(PsiMountBaseObject *self)
+{
+    psi_mountlist_t *mountlist;
+    psi_mountinfo_t *mounti;
+    int remote = 0;
+    int i;
+
+    if (PyObject_IsInstance((PyObject *)self, (PyObject *)&RemoteMount_Type))
+        remote = 1;
+    mountlist = psi_arch_mountlist(remote);
+    if (mountlist == NULL)
+        return NULL;
+    for (i = 0; i < mountlist->count; i++) {
+        mounti = mountlist->mounts[i];
+        if (strcmp(self->mounti->mount_path, mounti->mount_path) == 0 &&
+            strcmp(self->mounti->filesystem_path, mounti->filesystem_path) == 0)
+            break;
+    }
+    psi_free_mountinfo(self->mounti);
+    self->mounti = mounti;
+    mountlist->mounts[i] = NULL;
+    psi_free_mountlist(mountlist);
+    Py_RETURN_NONE;
+}
+
+
+static PyGetSetDef MountBase_getseters[] = {
+    {"fstype", (getter)MountBase_get_fstype, (setter)NULL,
+     "Type of the filesystem", NULL},
+    {"options", (getter)MountBase_get_options, (setter)NULL,
+     "Mount options", NULL},
+    {"mountpoint", (getter)MountBase_get_mountpoint, (setter)NULL,
+     "Where this filesystem is mounted on the filesystem hierarchy", NULL},
+    {"device", (getter)MountBase_get_device, (setter)NULL,
+     "Filesystem path", NULL},
+    {"total", (getter)MountBase_get_total, (setter)NULL,
+     "Total filesystem size in bytes", NULL},
+    {"free", (getter)MountBase_get_free, (setter)NULL,
+     "Free filesystem size in bytes", NULL},
+    {"available", (getter)MountBase_get_avail, (setter)NULL,
+     "Available filesystem size in bytes, i.e. free space for non-root", NULL},
+    {"inodes", (getter)MountBase_get_inodes, (setter)NULL,
+     "Number of inodes", NULL},
+    {"free_inodes", (getter)MountBase_get_free_inodes, (setter)NULL,
+     "Number of free inodes", NULL},
+    {"available_inodes", (getter)MountBase_get_available_inodes, (setter)NULL,
+     "Number of available nodes, i.e. free inodes for non-root", NULL},
+    {NULL}                      /* Sentinel */
+};
+
+
+static PyMethodDef MountBase_methods[] = {
+    {"refresh", (PyCFunction)MountBase_refresh, METH_NOARGS,
+     PyDoc_STR("Refresh the attributes with recent data")},
+    {NULL}                      /* Sentinel */
+};
+
+
+PyTypeObject MountBase_Type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "psi.mount.Mount",                        /* tp_name */
+    sizeof(PsiMountBaseObject),               /* tp_basicsize */
+    0,                                        /* tp_itemsize */
+    /* methods */
+    (destructor)MountBase_dealloc,            /* tp_dealloc */
+    0,                                        /* tp_print */
+    0,                                        /* tp_getattr */
+    0,                                        /* tp_setattr */
+    0,                                        /* tp_compare */
+    (reprfunc)MountBase_repr,                 /* tp_repr */
+    0,                                        /* tp_as_number */
+    0,                                        /* tp_as_sequence */
+    0,                                        /* tp_as_mapping */
+    0,                                        /* tp_hash */
+    0,                                        /* tp_call */
+    0,                                        /* tp_str */
+    0,                                        /* tp_getattro */
+    0,                                        /* tp_setattro */
+    0,                                        /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+    "Base object for all mount classes",      /* tp_doc */
+    0,                                        /* tp_traverse */
+    0,                                        /* tp_clear */
+    0,                                        /* tp_richcompare */
+    0,                                        /* tp_weaklistoffset */
+    0,                                        /* tp_iter */
+    0,                                        /* tp_iternext */
+    MountBase_methods,                        /* tp_methods */
+    0,                                        /* tp_members */
+    MountBase_getseters,                      /* tp_getset */
+    0,                                        /* tp_base */
+    0,                                        /* tp_dict */
+    0,                                        /* tp_descr_get */
+    0,                                        /* tp_descr_set */
+    0,                                        /* tp_dictoffset */
+    0,                                        /* tp_init */
+    0,                                        /* tp_alloc */
+    0,                                        /* tp_new */
+};
+
+
+PyTypeObject LocalMount_Type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "psi.mount.LocalMount",                   /* tp_name */
+    sizeof(PsiMountBaseObject),               /* tp_basicsize */
+    0,                                        /* tp_itemsize */
+    /* methods */
+    0,                                        /* tp_dealloc */
+    0,                                        /* tp_print */
+    0,                                        /* tp_getattr */
+    0,                                        /* tp_setattr */
+    0,                                        /* tp_compare */
+    0,                                        /* tp_repr */
+    0,                                        /* tp_as_number */
+    0,                                        /* tp_as_sequence */
+    0,                                        /* tp_as_mapping */
+    0,                                        /* tp_hash */
+    0,                                        /* tp_call */
+    0,                                        /* tp_str */
+    0,                                        /* tp_getattro */
+    0,                                        /* tp_setattro */
+    0,                                        /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+    "This object represents a local mountpoint", /* tp_doc */
+    0,                                        /* tp_traverse */
+    0,                                        /* tp_clear */
+    0,                                        /* tp_richcompare */
+    0,                                        /* tp_weaklistoffset */
+    0,                                        /* tp_iter */
+    0,                                        /* tp_iternext */
+    0,                                        /* tp_methods */
+    0,                                        /* tp_members */
+    0,                                        /* tp_getset */
+    &MountBase_Type,                          /* tp_base */
+    0,                                        /* tp_dict */
+    0,                                        /* tp_descr_get */
+    0,                                        /* tp_descr_set */
+    0,                                        /* tp_dictoffset */
+    0,                                        /* tp_init */
+    0,                                        /* tp_alloc */
+    0,                                        /* tp_new */
+};
+
+
+static PyObject *
+RemoteMount_get_host(PsiMountBaseObject *self)
+{
+    if (check_init(self) == -1)
+        return NULL;
+    if (psi_checkattr("Mount.filesystem_host", self->mounti->filesystem_host_status) == -1)
+        return NULL;
+    return PyStr_FromString(self->mounti->filesystem_host);
+}
+
+
+static PyGetSetDef RemoteMount_getseters[] = {
+    {"host", (getter)RemoteMount_get_host, (setter)NULL,
+     "The host of the filesystem", NULL},
+    {NULL}  /* Sentinel */
+};
+
+
+PyTypeObject RemoteMount_Type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "psi.mount.RemoteMount",                  /* tp_name */
+    sizeof(PsiMountBaseObject),               /* tp_basicsize */
+    0,                                        /* tp_itemsize */
+    /* methods */
+    0,                                        /* tp_dealloc */
+    0,                                        /* tp_print */
+    0,                                        /* tp_getattr */
+    0,                                        /* tp_setattr */
+    0,                                        /* tp_compare */
+    0,                                        /* tp_repr */
+    0,                                        /* tp_as_number */
+    0,                                        /* tp_as_sequence */
+    0,                                        /* tp_as_mapping */
+    0,                                        /* tp_hash */
+    0,                                        /* tp_call */
+    0,                                        /* tp_str */
+    0,                                        /* tp_getattro */
+    0,                                        /* tp_setattro */
+    0,                                        /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+    "This object represents a remote mountpoint", /* tp_doc */
+    0,                                        /* tp_traverse */
+    0,                                        /* tp_clear */
+    0,                                        /* tp_richcompare */
+    0,                                        /* tp_weaklistoffset */
+    0,                                        /* tp_iter */
+    0,                                        /* tp_iternext */
+    0,                                        /* tp_methods */
+    0,                                        /* tp_members */
+    RemoteMount_getseters,                    /* tp_getset */
+    &MountBase_Type,                          /* tp_base */
+    0,                                        /* tp_dict */
+    0,                                        /* tp_descr_get */
+    0,                                        /* tp_descr_set */
+    0,                                        /* tp_dictoffset */
+    0,                                        /* tp_init */
+    0,                                        /* tp_alloc */
+    0,                                        /* tp_new */
+};
+
+
+/* Object Creation Functions */
+
+
+PyObject *
+PsiMount_New(psi_mountinfo_t *mounti)
+{
+    PsiMountBaseObject *self;
+
+    if (mounti == NULL) {
+        PyErr_SetString(PyExc_RuntimeError,
+                        "Instance has not been initialised properly");
+        return NULL;
+    }
+    if (mounti->filesystem_host == NULL)
+        self = (PsiMountBaseObject *)PyType_GenericNew(&LocalMount_Type,
+                                                       NULL, NULL);
+    else
+        self = (PsiMountBaseObject *)PyType_GenericNew(&RemoteMount_Type,
+                                                       NULL, NULL);
+    if (self != NULL)
+        self->mounti = mounti;
+    return (PyObject *)self;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/mountmodule.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/mountmodule.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/mountmodule.c
new file mode 100644
index 0000000..c743bd2
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/mountmodule.c
@@ -0,0 +1,229 @@
+/* The MIT License
+ *
+ * Copyright (C) 2009 Erick Tryzelaar
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* The psi.mount module */
+
+
+#include <Python.h>
+
+#include "psi.h"
+#include "mount.h"
+
+
+/* Declarations (we need these since we use -Wmissing-declarations) */
+#ifdef PY3K
+PyMODINIT_FUNC PyInit_mount(void);
+#else
+PyMODINIT_FUNC initmount(void);
+#endif
+
+
+/* Re-declare these as non-extern since we're providing the symbols */
+PyObject *PsiExc_AttrNotAvailableError = NULL;
+PyObject *PsiExc_AttrInsufficientPrivsError = NULL;
+PyObject *PsiExc_AttrNotImplementedError = NULL;
+
+
+/* More contstants */
+static char MODULE_NAME[] = "psi.mount";
+PyDoc_STRVAR(MODULE_DOC, "Module for system mount information");
+
+
+PyDoc_STRVAR(psi_mount_mounts__doc, "\
+mounts(remote=False) -> iterator\n\
+\n\
+Return an iterator containing ojects representing mounted filesystems.  The\n\
+remote argument is a boolean value that can be used to control if remote\n\
+filesystems should be included or not.  Remote filesystems might take longer\n\
+to be created or suffer from timeouts collecting information from them.\n\
+");
+static PyObject *
+psi_mount_mounts(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    static char *kwlist[] = {"remote", NULL};
+    psi_mountlist_t *mountlist;
+    PyObject *mount;
+    PyObject *list;
+    PyObject *iter;
+    ssize_t i;
+    int remote = 0;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist, &remote))
+        return NULL;
+    mountlist = psi_arch_mountlist(remote);
+    if (mountlist == NULL)
+        return NULL;
+    list = PyList_New(mountlist->count);
+    if (list == NULL)
+        return psi_free_mountlist(mountlist);
+    for (i = 0; i < mountlist->count; ++i) {
+        mount = PsiMount_New(mountlist->mounts[i]);
+        if (mount == NULL) {
+            Py_DECREF(list);
+            return psi_free_mountlist(mountlist);
+        }
+        PyList_SET_ITEM(list, i, mount);
+
+        /* Python now owns the mountinfo, so clear it from the list. */
+        mountlist->mounts[i] = NULL;
+    }
+    psi_free_mountlist(mountlist);
+    iter = PySeqIter_New(list);
+    Py_DECREF(list);
+    return iter;
+}
+
+
+/** Finalise the types
+ *
+ * Calls PyType_Ready() and does anything else required.
+ */
+static int
+prepare_types(void)
+{
+    if (PyType_Ready(&MountBase_Type) < 0)
+        return -1;
+    if (PyType_Ready(&LocalMount_Type) < 0)
+        return -1;
+    if (PyType_Ready(&RemoteMount_Type) < 0)
+        return -1;
+    Py_INCREF(&MountBase_Type);
+    Py_INCREF(&LocalMount_Type);
+    Py_INCREF(&RemoteMount_Type);
+    return 0;
+}
+
+
+/** Initialise the global exceptions
+ *
+ * If this function fails the modinit function will Py_XDECREF the exceptions,
+ * so no need to do that here.
+ */
+static int
+init_exceptions(void)
+{
+    PyObject *_psimod;
+
+    _psimod = PyImport_ImportModule("psi._psi");
+    if (_psimod == NULL)
+        return -1;
+    PsiExc_AttrNotAvailableError = PyObject_GetAttrString(
+        _psimod, "AttrNotAvailableError");
+    if (PsiExc_AttrNotAvailableError == NULL)
+        goto error;
+    PsiExc_AttrInsufficientPrivsError = PyObject_GetAttrString(
+        _psimod, "AttrInsufficientPrivsError");
+    if (PsiExc_AttrInsufficientPrivsError == NULL)
+        goto error;
+    PsiExc_AttrNotImplementedError = PyObject_GetAttrString(
+        _psimod, "AttrNotImplementedError");
+    if (PsiExc_AttrNotImplementedError == NULL)
+        goto error;
+    Py_DECREF(_psimod);
+    return 0;
+
+  error:
+    Py_DECREF(_psimod);
+    return -1;
+}
+
+
+/* Add all the objects to the module */
+static int
+add_module_objects(PyObject *mod)
+{
+    if (PyModule_AddObject(mod, "MountBase", (PyObject *)&MountBase_Type) < 0)
+        return -1;
+    if (PyModule_AddObject(mod, "LocalMount", (PyObject *)&LocalMount_Type) < 0)
+        return -1;
+    if (PyModule_AddObject(mod, "RemoteMount", (PyObject *)&RemoteMount_Type) < 0)
+        return -1;
+    return 0;
+}
+
+
+static PyMethodDef mount_methods[] = {
+    {"mounts", (PyCFunction)psi_mount_mounts, METH_VARARGS | METH_KEYWORDS,
+     psi_mount_mounts__doc},
+    {NULL, NULL, 0, NULL}        /* Sentinel */
+};
+
+
+#ifdef PY3K
+static struct PyModuleDef moduledef = {
+        PyModuleDef_HEAD_INIT,  /* m_base */
+        MODULE_NAME,            /* m_name */
+        MODULE_DOC,             /* m_doc */
+        -1,                     /* m_size */
+        mount_methods,          /* m_methods */
+        NULL,                   /* m_reload */
+        NULL,                   /* m_traverse */
+        NULL,                   /* m_clear */
+        NULL                    /* m_free */
+};
+#endif
+
+
+/* Some defines to make the module init function readable */
+#ifdef PY3K
+#define MODFUNC PyInit_mount
+#define RETURN(VAR) return VAR
+#else
+#define MODFUNC initmount
+#define RETURN(VAR) return
+#endif
+
+
+/* Returns the psi.mount module */
+PyMODINIT_FUNC
+MODFUNC(void)
+{
+    PyObject *mod = NULL;
+
+    if (prepare_types() < 0)
+        RETURN(NULL);
+    if (init_exceptions() < 0)
+        goto error;
+#ifdef PY3K
+    mod = PyModule_Create(&moduledef);
+#else
+    mod = Py_InitModule3(MODULE_NAME, mount_methods, MODULE_DOC);
+#endif
+    if (mod == NULL)
+        goto error;
+    if (add_module_objects(mod) < 0)
+        goto error;
+    PyErr_WarnEx(PyExc_FutureWarning, "Experimental API", 1);
+    RETURN(mod);
+
+error:
+    Py_XDECREF(mod);
+    Py_XDECREF(PsiExc_AttrNotAvailableError);
+    Py_XDECREF(PsiExc_AttrInsufficientPrivsError);
+    Py_XDECREF(PsiExc_AttrNotImplementedError);
+    Py_XDECREF(&MountBase_Type);
+    Py_XDECREF(&LocalMount_Type);
+    Py_XDECREF(&RemoteMount_Type);
+    RETURN(NULL);
+}


Mime
View raw message