aboutsummaryrefslogtreecommitdiff
path: root/gcc/pex.cc
blob: 44a3ff13d91c53de9bf6a75e9674d00667e8f89d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/* C++ wrapper around libiberty's pex API.
   Copyright (C) 2025 Free Software Foundation, Inc.
   Contributed by David Malcolm <dmalcolm@redhat.com>.

This file is part of GCC.

GCC 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, or (at your option)
any later version.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#define INCLUDE_STRING
#define INCLUDE_VECTOR
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "pex.h"

/* Read the contents of FILE into memory, or return nullptr
   if there are any problems.  */

static std::unique_ptr<std::vector<char>>
read_all_of_file (FILE *f_in)
{
  /* Read content, allocating a buffer for it.  */
  auto result = std::make_unique<std::vector<char>> ();
  char buf[4096];
  size_t iter_sz_in;

  while ( (iter_sz_in = fread (buf, 1, sizeof (buf), f_in)) )
    {
      size_t old_total_sz = result->size ();
      size_t new_total_sz = old_total_sz + iter_sz_in;
      size_t old_alloc_sz = result->capacity ();
      if (new_total_sz > old_alloc_sz)
	{
	  size_t new_alloc_sz = std::max (old_alloc_sz * 2, new_total_sz);
	  result->reserve (new_alloc_sz);
	}
      gcc_assert (result->capacity () >= new_total_sz);
      result->resize (new_total_sz);
      memcpy (result->data () + old_total_sz, buf, iter_sz_in);
    }

  if (!feof (f_in))
    return nullptr;

  return result;
}

// struct file_wrapper

std::unique_ptr<std::vector<char>>
file_wrapper::read_all ()
{
  return read_all_of_file (m_file);
}

// struct pex

const char *
pex::run (int flags, const char *executable, const std::vector<std::string> &args,
	  const char *outname, const char *errname, int *err)
{
  std::vector<char *> argv;
  for (auto &iter : args)
    argv.push_back (const_cast<char *> (iter.c_str ()));
  argv.push_back (nullptr);
  return pex_run (m_obj, flags, executable, argv.data (),
		  outname, errname, err);
}