GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
unistd-wrappers.c
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2016-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 // These functions may be provided by gnulib. We don't include gnulib
27 // headers directly in Octave's C++ source files to avoid problems that
28 // may be caused by the way that gnulib overrides standard library
29 // functions.
30 
31 #if defined (HAVE_CONFIG_H)
32 # include "config.h"
33 #endif
34 
35 #include <stdio.h>
36 
37 #include <sys/types.h>
38 #include <unistd.h>
39 
40 #if defined (__WIN32__) && ! defined (__CYGWIN__)
41 # include <process.h>
42 #endif
43 
44 #if defined (OCTAVE_USE_WINDOWS_API)
45 # include <windows.h>
46 # include <wchar.h>
47 #endif
48 
49 #include "uniconv-wrappers.h"
50 #include "unistd-wrappers.h"
51 
52 int
54 {
55  return F_OK;
56 }
57 
58 int
60 {
61  return R_OK;
62 }
63 
64 int
66 {
67  return W_OK;
68 }
69 
70 int
72 {
73  return X_OK;
74 }
75 
76 int
77 octave_access_wrapper (const char *nm, int mode)
78 {
79  return access (nm, mode);
80 }
81 
82 int
83 octave_chdir_wrapper (const char *nm)
84 {
85 #if defined (OCTAVE_USE_WINDOWS_API)
86  wchar_t *wnm = u8_to_wchar (nm);
87  int status = _wchdir (wnm);
88  free ((void *) wnm);
89  return status;
90 #else
91  return chdir (nm);
92 #endif
93 }
94 
95 int
97 {
98  return close (fd);
99 }
100 
101 const char *
103 {
104 #if defined (HAVE_CTERMID)
105  return ctermid (0);
106 #else
107  return "/dev/tty";
108 #endif
109 }
110 
111 int
112 octave_dup2_wrapper (int fd1, int fd2)
113 {
114  return dup2 (fd1, fd2);
115 }
116 
117 #if defined (__WIN32__) && ! defined (__CYGWIN__)
118 
119 // Adapted from libtool wrapper.
120 
121 /* Prepares an argument vector before calling spawn().
122 
123  Note that spawn() does not by itself call the command interpreter
124  (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
125  ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
126  GetVersionEx(&v);
127  v.dwPlatformId == VER_PLATFORM_WIN32_NT;
128  }) ? "cmd.exe" : "command.com").
129 
130  Instead it simply concatenates the arguments, separated by ' ', and calls
131  CreateProcess(). We must quote the arguments since Win32 CreateProcess()
132  interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
133  special way:
134 
135  - Space and tab are interpreted as delimiters. They are not treated as
136  delimiters if they are surrounded by double quotes: "...".
137 
138  - Unescaped double quotes are removed from the input. Their only effect is
139  that within double quotes, space and tab are treated like normal
140  characters.
141 
142  - Backslashes not followed by double quotes are not special.
143 
144  - But 2*n+1 backslashes followed by a double quote become
145  n backslashes followed by a double quote (n >= 0):
146  \" -> "
147  \\\" -> \"
148  \\\\\" -> \\"
149  */
150 
151 #define SHELL_SPECIAL_CHARS \
152  "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
153 
154 #define SHELL_SPACE_CHARS \
155  " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
156 
157 static char **
158 prepare_spawn (char *const *argv)
159 {
160  size_t argc;
161  char **new_argv;
162  size_t i;
163 
164  /* Count number of arguments. */
165  for (argc = 0; argv[argc] != NULL; argc++)
166  ;
167 
168  /* Allocate new argument vector. */
169  new_argv = (char **) malloc (argc + 1);
170 
171  /* Put quoted arguments into the new argument vector. */
172  for (i = 0; i < argc; i++)
173  {
174  const char *string = argv[i];
175 
176  if (string[0] == '\0')
177  new_argv[i] = strdup ("\"\"");
178  else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
179  {
180  int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
181  size_t length;
182  unsigned int backslashes;
183  const char *s;
184  char *quoted_string;
185  char *p;
186 
187  length = 0;
188  backslashes = 0;
189  if (quote_around)
190  length++;
191  for (s = string; *s != '\0'; s++)
192  {
193  char c = *s;
194  if (c == '"')
195  length += backslashes + 1;
196  length++;
197  if (c == '\\')
198  backslashes++;
199  else
200  backslashes = 0;
201  }
202  if (quote_around)
203  length += backslashes + 1;
204 
205  quoted_string = (char *) malloc (length + 1);
206 
207  p = quoted_string;
208  backslashes = 0;
209  if (quote_around)
210  *p++ = '"';
211  for (s = string; *s != '\0'; s++)
212  {
213  char c = *s;
214  if (c == '"')
215  {
216  unsigned int j;
217  for (j = backslashes + 1; j > 0; j--)
218  *p++ = '\\';
219  }
220  *p++ = c;
221  if (c == '\\')
222  backslashes++;
223  else
224  backslashes = 0;
225  }
226  if (quote_around)
227  {
228  unsigned int j;
229  for (j = backslashes; j > 0; j--)
230  *p++ = '\\';
231  *p++ = '"';
232  }
233  *p = '\0';
234 
235  new_argv[i] = quoted_string;
236  }
237  else
238  new_argv[i] = strdup (string);
239  }
240 
241  new_argv[argc] = NULL;
242 
243  return new_argv;
244 }
245 
246 #endif
247 
248 int
249 octave_execv_wrapper (const char *file, char *const *argv)
250 {
251 #if defined (__WIN32__) && ! defined (__CYGWIN__)
252 
253  char **sanitized_argv = prepare_spawn (argv);
254 
255  int status = spawnv (P_OVERLAY, file, sanitized_argv);
256 
257  // This only happens if spawnv fails.
258 
259  char **p = sanitized_argv;
260  while (*p)
261  free (*p++);
262  free (sanitized_argv);
263 
264  return status;
265 
266 #else
267 
268  return execv (file, argv);
269 
270 #endif
271 }
272 
273 int
274 octave_execvp_wrapper (const char *file, char *const *argv)
275 {
276  return execvp (file, argv);
277 }
278 
279 pid_t
281 {
282 #if defined (HAVE_FORK)
283  return fork ();
284 #else
285  return -1;
286 #endif
287 }
288 
289 int
290 octave_ftruncate_wrapper (int fd, off_t sz)
291 {
292  return ftruncate (fd, sz);
293 }
294 
295 char *
296 octave_getcwd_wrapper (char *nm, size_t len)
297 {
298 #if defined (OCTAVE_USE_WINDOWS_API)
299  wchar_t *tmp = _wgetcwd (NULL, 0);
300  char *retval = NULL;
301 
302  if (! tmp)
303  return retval;
304 
305  retval = u8_from_wchar (tmp);
306  if (! nm)
307  return retval;
308  else
309  {
310  if (strlen (retval) > len)
311  return NULL;
312 
313  memcpy (nm, retval, len);
314  free (retval);
315  return nm;
316  }
317 #else
318  return getcwd (nm, len);
319 #endif
320 }
321 
322 gid_t
324 {
325 #if defined (HAVE_GETEGID)
326  return getegid ();
327 #else
328  return -1;
329 #endif
330 }
331 
332 uid_t
334 {
335 #if defined (HAVE_GETEUID)
336  return geteuid ();
337 #else
338  return -1;
339 #endif
340 }
341 
342 gid_t
344 {
345 #if defined (HAVE_GETGID)
346  return getgid ();
347 #else
348  return -1;
349 #endif
350 }
351 
352 int
353 octave_gethostname_wrapper (char *nm, size_t len)
354 {
355  return gethostname (nm, len);
356 }
357 
358 pid_t
360 {
361 #if defined (HAVE_GETPGRP)
362  return getpgrp ();
363 #else
364  return -1;
365 #endif
366 }
367 
368 pid_t
370 {
371 #if defined (HAVE_GETPID)
372  return getpid ();
373 #else
374  return -1;
375 #endif
376 }
377 
378 pid_t
380 {
381 #if defined (HAVE_GETPPID)
382  return getppid ();
383 #else
384  return -1;
385 #endif
386 }
387 
388 uid_t
390 {
391 #if defined (HAVE_GETUID)
392  return getuid ();
393 #else
394  return -1;
395 #endif
396 }
397 
398 int
400 {
401  return isatty (fd);
402 }
403 
404 int
405 octave_link_wrapper (const char *nm1, const char *nm2)
406 {
407  return link (nm1, nm2);
408 }
409 
410 int
412 {
413  return pipe (fd);
414 }
415 
416 int
417 octave_rmdir_wrapper (const char *nm)
418 {
419 #if defined (OCTAVE_USE_WINDOWS_API)
420  wchar_t *wnm = u8_to_wchar (nm);
421  int status = _wrmdir (wnm);
422  free ((void *) wnm);
423  return status;
424 #else
425  return rmdir (nm);
426 #endif
427 }
428 
429 pid_t
431 {
432 #if defined (HAVE_SETSID)
433  return setsid ();
434 #else
435  return -1;
436 #endif
437 }
438 
439 int
441 {
442  return STDIN_FILENO;
443 }
444 
445 int
447 {
448  return STDOUT_FILENO;
449 }
450 
451 int
452 octave_symlink_wrapper (const char *nm1, const char *nm2)
453 {
454  return symlink (nm1, nm2);
455 }
456 
457 int
458 octave_unlink_wrapper (const char *nm)
459 {
460 #if defined (OCTAVE_USE_WINDOWS_API)
461  wchar_t *wnm = u8_to_wchar (nm);
462  int status = _wunlink (wnm);
463  free ((void *) wnm);
464  return status;
465 #else
466  return unlink (nm);
467 #endif
468 }
469 
470 pid_t
472 {
473 #if defined (HAVE_VFORK)
474  return vfork ();
475 #else
476  return -1;
477 #endif
478 }
479 
480 bool
482 {
483 #if defined (HAVE_FORK)
484  return true;
485 #else
486  return false;
487 #endif
488 }
489 
490 bool
492 {
493 #if defined (HAVE_VFORK)
494  return true;
495 #else
496  return false;
497 #endif
498 }
static octave_idx_type link(octave_idx_type s, octave_idx_type t, octave_idx_type *pp)
Definition: colamd.cc:97
pid_t getppid(void)
pid_t getpid(void)
std::string getcwd(void)
Definition: lo-sysdep.cc:53
int pipe(int *fildes)
gid_t getegid(void)
gid_t getgid(void)
pid_t getpgrp(std::string &msg)
int symlink(const std::string &old_name, const std::string &new_name)
Definition: file-ops.cc:461
int rmdir(const std::string &name)
Definition: file-ops.cc:535
int execvp(const std::string &file, const string_vector &argv)
Definition: oct-syscalls.cc:75
int chdir(const std::string &path_arg)
Definition: lo-sysdep.cc:88
uid_t getuid(void)
int dup2(int old_fd, int new_fd)
Definition: oct-syscalls.cc:53
int unlink(const std::string &name)
Definition: file-ops.cc:626
uid_t geteuid(void)
pid_t fork(std::string &msg)
pid_t vfork(std::string &msg)
T::size_type strlen(const typename T::value_type *str)
Definition: oct-string.cc:85
#define isatty
void * malloc(unsigned)
void free(void *)
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811
#define STDIN_FILENO
Definition: sysdep.cc:92
wchar_t * u8_to_wchar(const char *u8)
char * u8_from_wchar(const wchar_t *wc)
int octave_access_f_ok(void)
pid_t octave_setsid_wrapper(void)
gid_t octave_getgid_wrapper(void)
uid_t octave_geteuid_wrapper(void)
int octave_ftruncate_wrapper(int fd, off_t sz)
int octave_gethostname_wrapper(char *nm, size_t len)
int octave_rmdir_wrapper(const char *nm)
pid_t octave_fork_wrapper(void)
pid_t octave_getpgrp_wrapper(void)
pid_t octave_getppid_wrapper(void)
int octave_access_r_ok(void)
bool octave_have_vfork(void)
int octave_execvp_wrapper(const char *file, char *const *argv)
gid_t octave_getegid_wrapper(void)
int octave_execv_wrapper(const char *file, char *const *argv)
pid_t octave_getpid_wrapper(void)
int octave_close_wrapper(int fd)
int octave_access_wrapper(const char *nm, int mode)
int octave_unlink_wrapper(const char *nm)
int octave_chdir_wrapper(const char *nm)
int octave_symlink_wrapper(const char *nm1, const char *nm2)
uid_t octave_getuid_wrapper(void)
int octave_access_x_ok(void)
int octave_link_wrapper(const char *nm1, const char *nm2)
int octave_access_w_ok(void)
const char * octave_ctermid_wrapper(void)
int octave_stdout_fileno(void)
char * octave_getcwd_wrapper(char *nm, size_t len)
pid_t octave_vfork_wrapper(void)
int octave_isatty_wrapper(int fd)
bool octave_have_fork(void)
int octave_dup2_wrapper(int fd1, int fd2)
int octave_stdin_fileno(void)
int octave_pipe_wrapper(int *fd)
F77_RET_T len
Definition: xerbla.cc:61