perl / Git.xson commit Git.pm: Call external commands using execv_git_cmd() (8062f81)
   1/* By carefully stacking #includes here (even if WE don't really need them)
   2 * we strive to make the thing actually compile. Git header files aren't very
   3 * nice. Perl headers are one of the signs of the coming apocalypse. */
   4#include <ctype.h>
   5/* Ok, it hasn't been so bad so far. */
   6
   7/* libgit interface */
   8#include "../cache.h"
   9#include "../exec_cmd.h"
  10
  11/* XS and Perl interface */
  12#include "EXTERN.h"
  13#include "perl.h"
  14#include "XSUB.h"
  15
  16#include "ppport.h"
  17
  18
  19MODULE = Git            PACKAGE = Git
  20
  21PROTOTYPES: DISABLE
  22
  23# /* TODO: xs_call_gate(). See Git.pm. */
  24
  25
  26const char *
  27xs_exec_path()
  28CODE:
  29{
  30        RETVAL = git_exec_path();
  31}
  32OUTPUT:
  33        RETVAL
  34
  35
  36void
  37xs__execv_git_cmd(...)
  38CODE:
  39{
  40        const char **argv;
  41        int i;
  42
  43        argv = malloc(sizeof(const char *) * (items + 1));
  44        if (!argv)
  45                croak("malloc failed");
  46        for (i = 0; i < items; i++)
  47                argv[i] = strdup(SvPV_nolen(ST(i)));
  48        argv[i] = NULL;
  49
  50        execv_git_cmd(argv);
  51
  52        for (i = 0; i < items; i++)
  53                if (argv[i])
  54                        free((char *) argv[i]);
  55        free((char **) argv);
  56}
  57
  58char *
  59xs_hash_object(file, type = "blob")
  60        SV *file;
  61        char *type;
  62CODE:
  63{
  64        unsigned char sha1[20];
  65
  66        if (SvTYPE(file) == SVt_RV)
  67                file = SvRV(file);
  68
  69        if (SvTYPE(file) == SVt_PVGV) {
  70                /* Filehandle */
  71                PerlIO *pio;
  72
  73                pio = IoIFP(sv_2io(file));
  74                if (!pio)
  75                        croak("You passed me something weird - a dir glob?");
  76                /* XXX: I just hope PerlIO didn't read anything from it yet.
  77                 * --pasky */
  78                if (index_pipe(sha1, PerlIO_fileno(pio), type, 0))
  79                        croak("Unable to hash given filehandle");
  80                /* Avoid any nasty surprises. */
  81                PerlIO_close(pio);
  82
  83        } else {
  84                /* String */
  85                char *path = SvPV_nolen(file);
  86                int fd = open(path, O_RDONLY);
  87                struct stat st;
  88
  89                if (fd < 0 ||
  90                    fstat(fd, &st) < 0 ||
  91                    index_fd(sha1, fd, &st, 0, type))
  92                        croak("Unable to hash %s", path);
  93                close(fd);
  94        }
  95        RETVAL = sha1_to_hex(sha1);
  96}
  97OUTPUT:
  98        RETVAL