This file is indexed.

/usr/share/octave/packages/parallel-3.1.1/rfeval.m is in octave-parallel 3.1.1-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
## Copyright (C) 2015, 2016 Olaf Till <i7tiol@t-online.de>
##
## 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/>.

## -*- texinfo -*-
## @deftypefn{Function File} {} rfeval (@var{func}, @dots{}, @var{nout}, @var{isout}, @var{connection})
## Evaluate a function at a remote machine.
##
## @var{func} is evaluated with arguments @code{@dots{}} and number of
## output arguments set to @var{nout} at remote machine given by
## @var{connection}. If @var{isout} is not empty, it must be a logical
## array with @var{nout} elements, which are true for each of the
## @var{nout} output arguments which are requested from the function;
## the other output arguments will be  marked as not requested
## with @code{~} at remote execution.
##
## This function can only be successfully called at the client machine.
## See @code{pconnect} for a description of the @var{connection}
## variable. @var{connection} must contain one single connection.
##
## If an output argument is given to @code{rfeval}, the function waits
## for completion of the remote function call, retrieves the results and
## returns them. They will be returned as one cell-array with an entry
## for each output argument. If some output arguments are marked as not
## requested by setting some elements of @var{isout} to false, the
## returned cell-array will only have entries for the requested output
## arguments. For consistency, the returned cell-array can be empty. To
## assign the output arguments to single variables, you can for example
## use: @code{[a, b, c] = returned_cell_array@{:@};}.
##
## If no output argument is given to @code{rfeval}, the function does
## not retrieve the results of the remote function call but returns
## immediately. It is left to the user to retrieve the results with
## @code{precv}. The results will be in the same format as if returned
## by @code{rfeval}. Note that a cell-array, possibly empty, will always
## have to be retrieved, even if the remote function call should have
## been performed without output arguments.
##
## Parallel execution can be achieved by calling @code{rfeval} several
## times with different specified server machines before starting to
## retrieve the results.
##
## The specified function handle can refer to a function present at the
## executing machine or be an anonymous function. In the latter case,
## the function specification sent to the server includes the anonymous
## functions context (generation of the sent function specification is
## implemented in the Octave core). Sending a handle to a subfunction,
## however, will currently not work. Sending a handle to a private
## function will only work if its file path is the same at the server.
## Sending an anonymous function using "varargin" in the argument list
## will currently not work.
##
## @seealso{pconnect, pserver, sclose, install_vars, netcellfun}
## @end deftypefn

function ret = rfeval (varargin)

  if ((nargs = nargin ()) < 4)
    print_usage ();
  endif

  fname = "rfeval";

  if (! isa (conn = varargin{end}, "pconnections"))
    error ("%s:  `connection' must be a parallel connections object", fname);
  elseif (numel (conn) != 1)
    error ("%s: exactly one connection must be specified", fname);
  elseif (network_get_info (conn).local_machine)
    error ("%s: client was specified instead of server");
    ## reval() checks if specified at server side
  endif

  if (! is_function_handle (varargin{1}))
    error ("%s: `func' must be a function handle", fname);
  endif

  if (! isnumeric (nout = varargin{end - 2}) || ! isscalar (nout) || ...
      (nout = round (nout)) < 0)
    error ("%s: `nout' must be a non-negative integer", fname);
  endif

  if (isempty (isout = varargin{end - 1}))
    isout = true (1, nout);
  elseif (! islogical (isout) || numel (isout) != nout)
    error ("%s: `isout' must be empty or a logical with `nout' elements",
           fname);
  endif
  isout = isout(:);

  ## feval() isn't called remotely since it doesn't resepect ignoring of
  ## output variables with '~'. So the function handle has to be sent
  ## separately and a remote temporary variable has to be used for it.
  ##
  ## rargs = varargin(1 : end - 3); # could be used with feval
  func = varargin{1};
  rargs = varargin(2 : end - 3);

  if (any (ign = ! isout))
    rout = repmat ({"__pserver_tout__{%i},"}, nout, 1);
    rout(ign) = {"~,"};
    rout = cstrcat (rout{:});
    rout = sprintf (rout, 1 : sum (isout));
    rout = rout(1 : end - 1); # remove final ','
    rout = sprintf ("[%s]", rout);
    if (all (ign))
      init_rout = "__pserver_tout__ = {}; ";
    else
      init_rout = "";
    endif
  else
    rout = sprintf ("[__pserver_tout__{1:%i}]", nout);
    init_rout = "";
  endif

  cmd = sprintf ...
      ("__pserver_tfunc__ = precv (sockets(1)); %s%s = __pserver_tfunc__ (precv (sockets(1)){:}); psend (__pserver_tout__, sockets(1)); clear ('__pserver_tout__');",
       init_rout, rout);

  reval (cmd, conn);

  ready = false;

  unwind_protect

    psend (func, conn);

    psend (rargs, conn);

    ready = true;

  unwind_protect_cleanup

    if (! ready)
      sclose (conns); # might already be closed from within reval or psend
    endif

  end_unwind_protect

  if (nargout () > 0)
    ret = precv (conn);
  endif

endfunction