Fix `getgroups' for when zero supplementary group IDs exist.
[bpt/guile.git] / libguile / posix.c
1 /* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2 * 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public License
6 * as published by the Free Software Foundation; either version 3 of
7 * the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301 USA
18 */
19
20
21 \f
22 #ifdef HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <errno.h>
29 #include <uniconv.h>
30
31 #ifdef HAVE_SCHED_H
32 # include <sched.h>
33 #endif
34
35 #include "libguile/_scm.h"
36 #include "libguile/dynwind.h"
37 #include "libguile/fports.h"
38 #include "libguile/scmsigs.h"
39 #include "libguile/feature.h"
40 #include "libguile/strings.h"
41 #include "libguile/srfi-13.h"
42 #include "libguile/srfi-14.h"
43 #include "libguile/vectors.h"
44 #include "libguile/values.h"
45
46 #include "libguile/validate.h"
47 #include "libguile/posix.h"
48 #include "libguile/gettext.h"
49 #include "libguile/threads.h"
50 \f
51
52 #ifdef HAVE_STRING_H
53 #include <string.h>
54 #endif
55 #ifdef TIME_WITH_SYS_TIME
56 # include <sys/time.h>
57 # include <time.h>
58 #else
59 # if HAVE_SYS_TIME_H
60 # include <sys/time.h>
61 # else
62 # include <time.h>
63 # endif
64 #endif
65
66 #ifdef HAVE_UNISTD_H
67 #include <unistd.h>
68 #else
69 #ifndef ttyname
70 extern char *ttyname();
71 #endif
72 #endif
73
74 #ifdef LIBC_H_WITH_UNISTD_H
75 #include <libc.h>
76 #endif
77
78 #include <sys/types.h>
79 #include <sys/stat.h>
80 #include <fcntl.h>
81
82 #ifdef HAVE_PWD_H
83 #include <pwd.h>
84 #endif
85 #ifdef HAVE_IO_H
86 #include <io.h>
87 #endif
88 #ifdef HAVE_WINSOCK2_H
89 #include <winsock2.h>
90 #endif
91
92 #ifdef __MINGW32__
93 /* Some defines for Windows here. */
94 # include <process.h>
95 # define pipe(fd) _pipe (fd, 256, O_BINARY)
96 #endif /* __MINGW32__ */
97
98 #if HAVE_SYS_WAIT_H
99 # include <sys/wait.h>
100 #endif
101 #ifndef WEXITSTATUS
102 # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
103 #endif
104 #ifndef WIFEXITED
105 # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
106 #endif
107
108 #include <signal.h>
109
110 #ifdef HAVE_GRP_H
111 #include <grp.h>
112 #endif
113 #ifdef HAVE_SYS_UTSNAME_H
114 #include <sys/utsname.h>
115 #endif
116
117 #ifdef HAVE_SETLOCALE
118 #include <locale.h>
119 #endif
120
121 #if (defined HAVE_NEWLOCALE) && (defined HAVE_STRCOLL_L)
122 # define USE_GNU_LOCALE_API
123 #endif
124
125 #if (defined USE_GNU_LOCALE_API) && (defined HAVE_XLOCALE_H)
126 # include <xlocale.h>
127 #endif
128
129 #ifdef HAVE_CRYPT_H
130 # include <crypt.h>
131 #endif
132
133 #ifdef HAVE_NETDB_H
134 #include <netdb.h> /* for MAXHOSTNAMELEN on Solaris */
135 #endif
136
137 #ifdef HAVE_SYS_PARAM_H
138 #include <sys/param.h> /* for MAXHOSTNAMELEN */
139 #endif
140
141 #if HAVE_SYS_RESOURCE_H
142 # include <sys/resource.h>
143 #endif
144
145 #include <sys/file.h> /* from Gnulib */
146
147 /* Some Unix systems don't define these. CPP hair is dangerous, but
148 this seems safe enough... */
149 #ifndef R_OK
150 #define R_OK 4
151 #endif
152
153 #ifndef W_OK
154 #define W_OK 2
155 #endif
156
157 #ifndef X_OK
158 #define X_OK 1
159 #endif
160
161 #ifndef F_OK
162 #define F_OK 0
163 #endif
164
165 /* No prototype for this on Solaris 10. The man page says it's in
166 <unistd.h> ... but it lies. */
167 #if ! HAVE_DECL_SETHOSTNAME
168 int sethostname (char *name, size_t namelen);
169 #endif
170
171 /* On NextStep, <utime.h> doesn't define struct utime, unless we
172 #define _POSIX_SOURCE before #including it. I think this is less
173 of a kludge than defining struct utimbuf ourselves. */
174 #ifdef UTIMBUF_NEEDS_POSIX
175 #define _POSIX_SOURCE
176 #endif
177
178 #ifdef HAVE_SYS_UTIME_H
179 #include <sys/utime.h>
180 #endif
181
182 #ifdef HAVE_UTIME_H
183 #include <utime.h>
184 #endif
185
186 /* Please don't add any more #includes or #defines here. The hack
187 above means that _POSIX_SOURCE may be #defined, which will
188 encourage header files to do strange things.
189
190 FIXME: Maybe should undef _POSIX_SOURCE after it's done its job.
191
192 FIXME: Probably should do all the includes first, then all the fallback
193 declarations and defines, in case things are not in the header we
194 imagine. */
195
196
197
198
199 \f
200
201 /* Two often used patterns
202 */
203
204 #define WITH_STRING(str,cstr,code) \
205 do { \
206 char *cstr = scm_to_locale_string (str); \
207 code; \
208 free (cstr); \
209 } while (0)
210
211 #define STRING_SYSCALL(str,cstr,code) \
212 do { \
213 int eno; \
214 char *cstr = scm_to_locale_string (str); \
215 SCM_SYSCALL (code); \
216 eno = errno; free (cstr); errno = eno; \
217 } while (0)
218
219
220 \f
221 SCM_SYMBOL (sym_read_pipe, "read pipe");
222 SCM_SYMBOL (sym_write_pipe, "write pipe");
223
224 SCM_DEFINE (scm_pipe, "pipe", 0, 0, 0,
225 (),
226 "Return a newly created pipe: a pair of ports which are linked\n"
227 "together on the local machine. The @emph{car} is the input\n"
228 "port and the @emph{cdr} is the output port. Data written (and\n"
229 "flushed) to the output port can be read from the input port.\n"
230 "Pipes are commonly used for communication with a newly forked\n"
231 "child process. The need to flush the output port can be\n"
232 "avoided by making it unbuffered using @code{setvbuf}.\n"
233 "\n"
234 "Writes occur atomically provided the size of the data in bytes\n"
235 "is not greater than the value of @code{PIPE_BUF}. Note that\n"
236 "the output port is likely to block if too much data (typically\n"
237 "equal to @code{PIPE_BUF}) has been written but not yet read\n"
238 "from the input port.")
239 #define FUNC_NAME s_scm_pipe
240 {
241 int fd[2], rv;
242 SCM p_rd, p_wt;
243
244 rv = pipe (fd);
245 if (rv)
246 SCM_SYSERROR;
247
248 p_rd = scm_fdes_to_port (fd[0], "r", sym_read_pipe);
249 p_wt = scm_fdes_to_port (fd[1], "w", sym_write_pipe);
250 return scm_cons (p_rd, p_wt);
251 }
252 #undef FUNC_NAME
253
254
255 #ifdef HAVE_GETGROUPS
256 SCM_DEFINE (scm_getgroups, "getgroups", 0, 0, 0,
257 (),
258 "Return a vector of integers representing the current\n"
259 "supplementary group IDs.")
260 #define FUNC_NAME s_scm_getgroups
261 {
262 SCM result;
263 int ngroups;
264 size_t size;
265 GETGROUPS_T *groups;
266
267 ngroups = getgroups (0, NULL);
268 if (ngroups < 0)
269 SCM_SYSERROR;
270 else if (ngroups == 0)
271 return scm_c_make_vector (0, SCM_BOOL_F);
272
273 size = ngroups * sizeof (GETGROUPS_T);
274 groups = scm_malloc (size);
275 ngroups = getgroups (ngroups, groups);
276
277 result = scm_c_make_vector (ngroups, SCM_BOOL_F);
278 while (--ngroups >= 0)
279 SCM_SIMPLE_VECTOR_SET (result, ngroups, scm_from_ulong (groups[ngroups]));
280
281 free (groups);
282 return result;
283 }
284 #undef FUNC_NAME
285 #endif
286
287 #ifdef HAVE_SETGROUPS
288 SCM_DEFINE (scm_setgroups, "setgroups", 1, 0, 0,
289 (SCM group_vec),
290 "Set the current set of supplementary group IDs to the integers\n"
291 "in the given vector @var{group_vec}. The return value is\n"
292 "unspecified.\n"
293 "\n"
294 "Generally only the superuser can set the process group IDs.")
295 #define FUNC_NAME s_scm_setgroups
296 {
297 size_t ngroups;
298 size_t size;
299 size_t i;
300 int result;
301 int save_errno;
302 GETGROUPS_T *groups;
303
304 SCM_VALIDATE_VECTOR (SCM_ARG1, group_vec);
305
306 ngroups = SCM_SIMPLE_VECTOR_LENGTH (group_vec);
307
308 /* validate before allocating, so we don't have to worry about leaks */
309 for (i = 0; i < ngroups; i++)
310 {
311 unsigned long ulong_gid;
312 GETGROUPS_T gid;
313 SCM_VALIDATE_ULONG_COPY (1, SCM_SIMPLE_VECTOR_REF (group_vec, i),
314 ulong_gid);
315 gid = ulong_gid;
316 if (gid != ulong_gid)
317 SCM_OUT_OF_RANGE (1, SCM_SIMPLE_VECTOR_REF (group_vec, i));
318 }
319
320 size = ngroups * sizeof (GETGROUPS_T);
321 if (size / sizeof (GETGROUPS_T) != ngroups)
322 SCM_OUT_OF_RANGE (SCM_ARG1, scm_from_int (ngroups));
323 groups = scm_malloc (size);
324 for(i = 0; i < ngroups; i++)
325 groups [i] = SCM_NUM2ULONG (1, SCM_SIMPLE_VECTOR_REF (group_vec, i));
326
327 result = setgroups (ngroups, groups);
328 save_errno = errno; /* don't let free() touch errno */
329 free (groups);
330 errno = save_errno;
331 if (result < 0)
332 SCM_SYSERROR;
333 return SCM_UNSPECIFIED;
334 }
335 #undef FUNC_NAME
336 #endif
337
338 #ifdef HAVE_GETPWENT
339 SCM_DEFINE (scm_getpwuid, "getpw", 0, 1, 0,
340 (SCM user),
341 "Look up an entry in the user database. @var{user} can be an\n"
342 "integer, a string, or omitted, giving the behaviour of\n"
343 "@code{getpwuid}, @code{getpwnam} or @code{getpwent}\n"
344 "respectively.")
345 #define FUNC_NAME s_scm_getpwuid
346 {
347 struct passwd *entry;
348
349 SCM result = scm_c_make_vector (7, SCM_UNSPECIFIED);
350 if (SCM_UNBNDP (user) || scm_is_false (user))
351 {
352 SCM_SYSCALL (entry = getpwent ());
353 if (! entry)
354 {
355 return SCM_BOOL_F;
356 }
357 }
358 else if (scm_is_integer (user))
359 {
360 entry = getpwuid (scm_to_int (user));
361 }
362 else
363 {
364 WITH_STRING (user, c_user,
365 entry = getpwnam (c_user));
366 }
367 if (!entry)
368 SCM_MISC_ERROR ("entry not found", SCM_EOL);
369
370 SCM_SIMPLE_VECTOR_SET(result, 0, scm_from_locale_string (entry->pw_name));
371 SCM_SIMPLE_VECTOR_SET(result, 1, scm_from_locale_string (entry->pw_passwd));
372 SCM_SIMPLE_VECTOR_SET(result, 2, scm_from_ulong (entry->pw_uid));
373 SCM_SIMPLE_VECTOR_SET(result, 3, scm_from_ulong (entry->pw_gid));
374 SCM_SIMPLE_VECTOR_SET(result, 4, scm_from_locale_string (entry->pw_gecos));
375 if (!entry->pw_dir)
376 SCM_SIMPLE_VECTOR_SET(result, 5, scm_from_locale_string (""));
377 else
378 SCM_SIMPLE_VECTOR_SET(result, 5, scm_from_locale_string (entry->pw_dir));
379 if (!entry->pw_shell)
380 SCM_SIMPLE_VECTOR_SET(result, 6, scm_from_locale_string (""));
381 else
382 SCM_SIMPLE_VECTOR_SET(result, 6, scm_from_locale_string (entry->pw_shell));
383 return result;
384 }
385 #undef FUNC_NAME
386 #endif /* HAVE_GETPWENT */
387
388
389 #ifdef HAVE_SETPWENT
390 SCM_DEFINE (scm_setpwent, "setpw", 0, 1, 0,
391 (SCM arg),
392 "If called with a true argument, initialize or reset the password data\n"
393 "stream. Otherwise, close the stream. The @code{setpwent} and\n"
394 "@code{endpwent} procedures are implemented on top of this.")
395 #define FUNC_NAME s_scm_setpwent
396 {
397 if (SCM_UNBNDP (arg) || scm_is_false (arg))
398 endpwent ();
399 else
400 setpwent ();
401 return SCM_UNSPECIFIED;
402 }
403 #undef FUNC_NAME
404 #endif
405
406
407 #ifdef HAVE_GETGRENT
408 /* Combines getgrgid and getgrnam. */
409 SCM_DEFINE (scm_getgrgid, "getgr", 0, 1, 0,
410 (SCM name),
411 "Look up an entry in the group database. @var{name} can be an\n"
412 "integer, a string, or omitted, giving the behaviour of\n"
413 "@code{getgrgid}, @code{getgrnam} or @code{getgrent}\n"
414 "respectively.")
415 #define FUNC_NAME s_scm_getgrgid
416 {
417 struct group *entry;
418 SCM result = scm_c_make_vector (4, SCM_UNSPECIFIED);
419
420 if (SCM_UNBNDP (name) || scm_is_false (name))
421 {
422 SCM_SYSCALL (entry = getgrent ());
423 if (! entry)
424 {
425 return SCM_BOOL_F;
426 }
427 }
428 else if (scm_is_integer (name))
429 SCM_SYSCALL (entry = getgrgid (scm_to_int (name)));
430 else
431 STRING_SYSCALL (name, c_name,
432 entry = getgrnam (c_name));
433 if (!entry)
434 SCM_SYSERROR;
435
436 SCM_SIMPLE_VECTOR_SET(result, 0, scm_from_locale_string (entry->gr_name));
437 SCM_SIMPLE_VECTOR_SET(result, 1, scm_from_locale_string (entry->gr_passwd));
438 SCM_SIMPLE_VECTOR_SET(result, 2, scm_from_ulong (entry->gr_gid));
439 SCM_SIMPLE_VECTOR_SET(result, 3, scm_makfromstrs (-1, entry->gr_mem));
440 return result;
441 }
442 #undef FUNC_NAME
443
444
445
446 SCM_DEFINE (scm_setgrent, "setgr", 0, 1, 0,
447 (SCM arg),
448 "If called with a true argument, initialize or reset the group data\n"
449 "stream. Otherwise, close the stream. The @code{setgrent} and\n"
450 "@code{endgrent} procedures are implemented on top of this.")
451 #define FUNC_NAME s_scm_setgrent
452 {
453 if (SCM_UNBNDP (arg) || scm_is_false (arg))
454 endgrent ();
455 else
456 setgrent ();
457 return SCM_UNSPECIFIED;
458 }
459 #undef FUNC_NAME
460 #endif /* HAVE_GETGRENT */
461
462
463 #ifdef HAVE_GETRLIMIT
464 #ifdef RLIMIT_AS
465 SCM_SYMBOL (sym_as, "as");
466 #endif
467 #ifdef RLIMIT_CORE
468 SCM_SYMBOL (sym_core, "core");
469 #endif
470 #ifdef RLIMIT_CPU
471 SCM_SYMBOL (sym_cpu, "cpu");
472 #endif
473 #ifdef RLIMIT_DATA
474 SCM_SYMBOL (sym_data, "data");
475 #endif
476 #ifdef RLIMIT_FSIZE
477 SCM_SYMBOL (sym_fsize, "fsize");
478 #endif
479 #ifdef RLIMIT_MEMLOCK
480 SCM_SYMBOL (sym_memlock, "memlock");
481 #endif
482 #ifdef RLIMIT_MSGQUEUE
483 SCM_SYMBOL (sym_msgqueue, "msgqueue");
484 #endif
485 #ifdef RLIMIT_NICE
486 SCM_SYMBOL (sym_nice, "nice");
487 #endif
488 #ifdef RLIMIT_NOFILE
489 SCM_SYMBOL (sym_nofile, "nofile");
490 #endif
491 #ifdef RLIMIT_NPROC
492 SCM_SYMBOL (sym_nproc, "nproc");
493 #endif
494 #ifdef RLIMIT_RSS
495 SCM_SYMBOL (sym_rss, "rss");
496 #endif
497 #ifdef RLIMIT_RTPRIO
498 SCM_SYMBOL (sym_rtprio, "rtprio");
499 #endif
500 #ifdef RLIMIT_RTPRIO
501 SCM_SYMBOL (sym_rttime, "rttime");
502 #endif
503 #ifdef RLIMIT_SIGPENDING
504 SCM_SYMBOL (sym_sigpending, "sigpending");
505 #endif
506 #ifdef RLIMIT_STACK
507 SCM_SYMBOL (sym_stack, "stack");
508 #endif
509
510 static int
511 scm_to_resource (SCM s, const char *func, int pos)
512 {
513 if (scm_is_number (s))
514 return scm_to_int (s);
515
516 SCM_ASSERT_TYPE (scm_is_symbol (s), s, pos, func, "symbol");
517
518 #ifdef RLIMIT_AS
519 if (scm_is_eq (s, sym_as))
520 return RLIMIT_AS;
521 #endif
522 #ifdef RLIMIT_CORE
523 if (scm_is_eq (s, sym_core))
524 return RLIMIT_CORE;
525 #endif
526 #ifdef RLIMIT_CPU
527 if (scm_is_eq (s, sym_cpu))
528 return RLIMIT_CPU;
529 #endif
530 #ifdef RLIMIT_DATA
531 if (scm_is_eq (s, sym_data))
532 return RLIMIT_DATA;
533 #endif
534 #ifdef RLIMIT_FSIZE
535 if (scm_is_eq (s, sym_fsize))
536 return RLIMIT_FSIZE;
537 #endif
538 #ifdef RLIMIT_MEMLOCK
539 if (scm_is_eq (s, sym_memlock))
540 return RLIMIT_MEMLOCK;
541 #endif
542 #ifdef RLIMIT_MSGQUEUE
543 if (scm_is_eq (s, sym_msgqueue))
544 return RLIMIT_MSGQUEUE;
545 #endif
546 #ifdef RLIMIT_NICE
547 if (scm_is_eq (s, sym_nice))
548 return RLIMIT_NICE;
549 #endif
550 #ifdef RLIMIT_NOFILE
551 if (scm_is_eq (s, sym_nofile))
552 return RLIMIT_NOFILE;
553 #endif
554 #ifdef RLIMIT_NPROC
555 if (scm_is_eq (s, sym_nproc))
556 return RLIMIT_NPROC;
557 #endif
558 #ifdef RLIMIT_RSS
559 if (scm_is_eq (s, sym_rss))
560 return RLIMIT_RSS;
561 #endif
562 #ifdef RLIMIT_RTPRIO
563 if (scm_is_eq (s, sym_rtprio))
564 return RLIMIT_RTPRIO;
565 #endif
566 #ifdef RLIMIT_RTPRIO
567 if (scm_is_eq (s, sym_rttime))
568 return RLIMIT_RTPRIO;
569 #endif
570 #ifdef RLIMIT_SIGPENDING
571 if (scm_is_eq (s, sym_sigpending))
572 return RLIMIT_SIGPENDING;
573 #endif
574 #ifdef RLIMIT_STACK
575 if (scm_is_eq (s, sym_stack))
576 return RLIMIT_STACK;
577 #endif
578
579 scm_misc_error (func, "invalid rlimit resource ~A", scm_list_1 (s));
580 return 0;
581 }
582
583 SCM_DEFINE (scm_getrlimit, "getrlimit", 1, 0, 0,
584 (SCM resource),
585 "Get a resource limit for this process. @var{resource} identifies the resource,\n"
586 "either as an integer or as a symbol. For example, @code{(getrlimit 'stack)}\n"
587 "gets the limits associated with @code{RLIMIT_STACK}.\n\n"
588 "@code{getrlimit} returns two values, the soft and the hard limit. If no\n"
589 "limit is set for the resource in question, the returned limit will be @code{#f}.")
590 #define FUNC_NAME s_scm_getrlimit
591 {
592 int iresource;
593 struct rlimit lim = { 0, 0 };
594
595 iresource = scm_to_resource (resource, FUNC_NAME, 1);
596
597 if (getrlimit (iresource, &lim) != 0)
598 scm_syserror (FUNC_NAME);
599
600 return scm_values (scm_list_2 ((lim.rlim_cur == RLIM_INFINITY) ? SCM_BOOL_F
601 : scm_from_long (lim.rlim_cur),
602 (lim.rlim_max == RLIM_INFINITY) ? SCM_BOOL_F
603 : scm_from_long (lim.rlim_max)));
604 }
605 #undef FUNC_NAME
606
607
608 #ifdef HAVE_SETRLIMIT
609 SCM_DEFINE (scm_setrlimit, "setrlimit", 3, 0, 0,
610 (SCM resource, SCM soft, SCM hard),
611 "Set a resource limit for this process. @var{resource} identifies the resource,\n"
612 "either as an integer or as a symbol. @var{soft} and @var{hard} should be integers,\n"
613 "or @code{#f} to indicate no limit (i.e., @code{RLIM_INFINITY}).\n\n"
614 "For example, @code{(setrlimit 'stack 150000 300000)} sets the @code{RLIMIT_STACK}\n"
615 "limit to 150 kilobytes, with a hard limit of 300 kB.")
616 #define FUNC_NAME s_scm_setrlimit
617 {
618 int iresource;
619 struct rlimit lim = { 0, 0 };
620
621 iresource = scm_to_resource (resource, FUNC_NAME, 1);
622
623 lim.rlim_cur = scm_is_false (soft) ? RLIM_INFINITY : scm_to_long (soft);
624 lim.rlim_max = scm_is_false (hard) ? RLIM_INFINITY : scm_to_long (hard);
625
626 if (setrlimit (iresource, &lim) != 0)
627 scm_syserror (FUNC_NAME);
628
629 return SCM_UNSPECIFIED;
630 }
631 #undef FUNC_NAME
632 #endif /* HAVE_SETRLIMIT */
633 #endif /* HAVE_GETRLIMIT */
634
635
636 SCM_DEFINE (scm_kill, "kill", 2, 0, 0,
637 (SCM pid, SCM sig),
638 "Sends a signal to the specified process or group of processes.\n\n"
639 "@var{pid} specifies the processes to which the signal is sent:\n\n"
640 "@table @r\n"
641 "@item @var{pid} greater than 0\n"
642 "The process whose identifier is @var{pid}.\n"
643 "@item @var{pid} equal to 0\n"
644 "All processes in the current process group.\n"
645 "@item @var{pid} less than -1\n"
646 "The process group whose identifier is -@var{pid}\n"
647 "@item @var{pid} equal to -1\n"
648 "If the process is privileged, all processes except for some special\n"
649 "system processes. Otherwise, all processes with the current effective\n"
650 "user ID.\n"
651 "@end table\n\n"
652 "@var{sig} should be specified using a variable corresponding to\n"
653 "the Unix symbolic name, e.g.,\n\n"
654 "@defvar SIGHUP\n"
655 "Hang-up signal.\n"
656 "@end defvar\n\n"
657 "@defvar SIGINT\n"
658 "Interrupt signal.\n"
659 "@end defvar")
660 #define FUNC_NAME s_scm_kill
661 {
662 /* Signal values are interned in scm_init_posix(). */
663 #ifdef HAVE_KILL
664 if (kill (scm_to_int (pid), scm_to_int (sig)) != 0)
665 SCM_SYSERROR;
666 #else
667 /* Mingw has raise(), but not kill(). (Other raw DOS environments might
668 be similar.) Use raise() when the requested pid is our own process,
669 otherwise bomb. */
670 if (scm_to_int (pid) == getpid ())
671 {
672 if (raise (scm_to_int (sig)) != 0)
673 {
674 err:
675 SCM_SYSERROR;
676 }
677 else
678 {
679 errno = ENOSYS;
680 goto err;
681 }
682 }
683 #endif
684 return SCM_UNSPECIFIED;
685 }
686 #undef FUNC_NAME
687
688 #ifdef HAVE_WAITPID
689 SCM_DEFINE (scm_waitpid, "waitpid", 1, 1, 0,
690 (SCM pid, SCM options),
691 "This procedure collects status information from a child process which\n"
692 "has terminated or (optionally) stopped. Normally it will\n"
693 "suspend the calling process until this can be done. If more than one\n"
694 "child process is eligible then one will be chosen by the operating system.\n\n"
695 "The value of @var{pid} determines the behaviour:\n\n"
696 "@table @r\n"
697 "@item @var{pid} greater than 0\n"
698 "Request status information from the specified child process.\n"
699 "@item @var{pid} equal to -1 or WAIT_ANY\n"
700 "Request status information for any child process.\n"
701 "@item @var{pid} equal to 0 or WAIT_MYPGRP\n"
702 "Request status information for any child process in the current process\n"
703 "group.\n"
704 "@item @var{pid} less than -1\n"
705 "Request status information for any child process whose process group ID\n"
706 "is -@var{pid}.\n"
707 "@end table\n\n"
708 "The @var{options} argument, if supplied, should be the bitwise OR of the\n"
709 "values of zero or more of the following variables:\n\n"
710 "@defvar WNOHANG\n"
711 "Return immediately even if there are no child processes to be collected.\n"
712 "@end defvar\n\n"
713 "@defvar WUNTRACED\n"
714 "Report status information for stopped processes as well as terminated\n"
715 "processes.\n"
716 "@end defvar\n\n"
717 "The return value is a pair containing:\n\n"
718 "@enumerate\n"
719 "@item\n"
720 "The process ID of the child process, or 0 if @code{WNOHANG} was\n"
721 "specified and no process was collected.\n"
722 "@item\n"
723 "The integer status value.\n"
724 "@end enumerate")
725 #define FUNC_NAME s_scm_waitpid
726 {
727 int i;
728 int status;
729 int ioptions;
730 if (SCM_UNBNDP (options))
731 ioptions = 0;
732 else
733 {
734 /* Flags are interned in scm_init_posix. */
735 ioptions = scm_to_int (options);
736 }
737 SCM_SYSCALL (i = waitpid (scm_to_int (pid), &status, ioptions));
738 if (i == -1)
739 SCM_SYSERROR;
740 return scm_cons (scm_from_int (i), scm_from_int (status));
741 }
742 #undef FUNC_NAME
743 #endif /* HAVE_WAITPID */
744
745 #ifndef __MINGW32__
746 SCM_DEFINE (scm_status_exit_val, "status:exit-val", 1, 0, 0,
747 (SCM status),
748 "Return the exit status value, as would be set if a process\n"
749 "ended normally through a call to @code{exit} or @code{_exit},\n"
750 "if any, otherwise @code{#f}.")
751 #define FUNC_NAME s_scm_status_exit_val
752 {
753 int lstatus;
754
755 /* On Ultrix, the WIF... macros assume their argument is an lvalue;
756 go figure. */
757 lstatus = scm_to_int (status);
758 if (WIFEXITED (lstatus))
759 return (scm_from_int (WEXITSTATUS (lstatus)));
760 else
761 return SCM_BOOL_F;
762 }
763 #undef FUNC_NAME
764
765 SCM_DEFINE (scm_status_term_sig, "status:term-sig", 1, 0, 0,
766 (SCM status),
767 "Return the signal number which terminated the process, if any,\n"
768 "otherwise @code{#f}.")
769 #define FUNC_NAME s_scm_status_term_sig
770 {
771 int lstatus;
772
773 lstatus = scm_to_int (status);
774 if (WIFSIGNALED (lstatus))
775 return scm_from_int (WTERMSIG (lstatus));
776 else
777 return SCM_BOOL_F;
778 }
779 #undef FUNC_NAME
780
781 SCM_DEFINE (scm_status_stop_sig, "status:stop-sig", 1, 0, 0,
782 (SCM status),
783 "Return the signal number which stopped the process, if any,\n"
784 "otherwise @code{#f}.")
785 #define FUNC_NAME s_scm_status_stop_sig
786 {
787 int lstatus;
788
789 lstatus = scm_to_int (status);
790 if (WIFSTOPPED (lstatus))
791 return scm_from_int (WSTOPSIG (lstatus));
792 else
793 return SCM_BOOL_F;
794 }
795 #undef FUNC_NAME
796 #endif /* __MINGW32__ */
797
798 #ifdef HAVE_GETPPID
799 SCM_DEFINE (scm_getppid, "getppid", 0, 0, 0,
800 (),
801 "Return an integer representing the process ID of the parent\n"
802 "process.")
803 #define FUNC_NAME s_scm_getppid
804 {
805 return scm_from_int (getppid ());
806 }
807 #undef FUNC_NAME
808 #endif /* HAVE_GETPPID */
809
810
811 #ifndef __MINGW32__
812 SCM_DEFINE (scm_getuid, "getuid", 0, 0, 0,
813 (),
814 "Return an integer representing the current real user ID.")
815 #define FUNC_NAME s_scm_getuid
816 {
817 return scm_from_int (getuid ());
818 }
819 #undef FUNC_NAME
820
821
822
823 SCM_DEFINE (scm_getgid, "getgid", 0, 0, 0,
824 (),
825 "Return an integer representing the current real group ID.")
826 #define FUNC_NAME s_scm_getgid
827 {
828 return scm_from_int (getgid ());
829 }
830 #undef FUNC_NAME
831
832
833
834 SCM_DEFINE (scm_geteuid, "geteuid", 0, 0, 0,
835 (),
836 "Return an integer representing the current effective user ID.\n"
837 "If the system does not support effective IDs, then the real ID\n"
838 "is returned. @code{(provided? 'EIDs)} reports whether the\n"
839 "system supports effective IDs.")
840 #define FUNC_NAME s_scm_geteuid
841 {
842 #ifdef HAVE_GETEUID
843 return scm_from_int (geteuid ());
844 #else
845 return scm_from_int (getuid ());
846 #endif
847 }
848 #undef FUNC_NAME
849
850
851 SCM_DEFINE (scm_getegid, "getegid", 0, 0, 0,
852 (),
853 "Return an integer representing the current effective group ID.\n"
854 "If the system does not support effective IDs, then the real ID\n"
855 "is returned. @code{(provided? 'EIDs)} reports whether the\n"
856 "system supports effective IDs.")
857 #define FUNC_NAME s_scm_getegid
858 {
859 #ifdef HAVE_GETEUID
860 return scm_from_int (getegid ());
861 #else
862 return scm_from_int (getgid ());
863 #endif
864 }
865 #undef FUNC_NAME
866
867
868 SCM_DEFINE (scm_setuid, "setuid", 1, 0, 0,
869 (SCM id),
870 "Sets both the real and effective user IDs to the integer @var{id}, provided\n"
871 "the process has appropriate privileges.\n"
872 "The return value is unspecified.")
873 #define FUNC_NAME s_scm_setuid
874 {
875 if (setuid (scm_to_int (id)) != 0)
876 SCM_SYSERROR;
877 return SCM_UNSPECIFIED;
878 }
879 #undef FUNC_NAME
880
881 SCM_DEFINE (scm_setgid, "setgid", 1, 0, 0,
882 (SCM id),
883 "Sets both the real and effective group IDs to the integer @var{id}, provided\n"
884 "the process has appropriate privileges.\n"
885 "The return value is unspecified.")
886 #define FUNC_NAME s_scm_setgid
887 {
888 if (setgid (scm_to_int (id)) != 0)
889 SCM_SYSERROR;
890 return SCM_UNSPECIFIED;
891 }
892 #undef FUNC_NAME
893
894 SCM_DEFINE (scm_seteuid, "seteuid", 1, 0, 0,
895 (SCM id),
896 "Sets the effective user ID to the integer @var{id}, provided the process\n"
897 "has appropriate privileges. If effective IDs are not supported, the\n"
898 "real ID is set instead -- @code{(provided? 'EIDs)} reports whether the\n"
899 "system supports effective IDs.\n"
900 "The return value is unspecified.")
901 #define FUNC_NAME s_scm_seteuid
902 {
903 int rv;
904
905 #ifdef HAVE_SETEUID
906 rv = seteuid (scm_to_int (id));
907 #else
908 rv = setuid (scm_to_int (id));
909 #endif
910 if (rv != 0)
911 SCM_SYSERROR;
912 return SCM_UNSPECIFIED;
913 }
914 #undef FUNC_NAME
915 #endif /* __MINGW32__ */
916
917
918 #ifdef HAVE_SETEGID
919 SCM_DEFINE (scm_setegid, "setegid", 1, 0, 0,
920 (SCM id),
921 "Sets the effective group ID to the integer @var{id}, provided the process\n"
922 "has appropriate privileges. If effective IDs are not supported, the\n"
923 "real ID is set instead -- @code{(provided? 'EIDs)} reports whether the\n"
924 "system supports effective IDs.\n"
925 "The return value is unspecified.")
926 #define FUNC_NAME s_scm_setegid
927 {
928 int rv;
929
930 #ifdef HAVE_SETEUID
931 rv = setegid (scm_to_int (id));
932 #else
933 rv = setgid (scm_to_int (id));
934 #endif
935 if (rv != 0)
936 SCM_SYSERROR;
937 return SCM_UNSPECIFIED;
938
939 }
940 #undef FUNC_NAME
941 #endif
942
943
944 #ifdef HAVE_GETPGRP
945 SCM_DEFINE (scm_getpgrp, "getpgrp", 0, 0, 0,
946 (),
947 "Return an integer representing the current process group ID.\n"
948 "This is the POSIX definition, not BSD.")
949 #define FUNC_NAME s_scm_getpgrp
950 {
951 int (*fn)();
952 fn = (int (*) ()) getpgrp;
953 return scm_from_int (fn (0));
954 }
955 #undef FUNC_NAME
956 #endif /* HAVE_GETPGRP */
957
958
959 #ifdef HAVE_SETPGID
960 SCM_DEFINE (scm_setpgid, "setpgid", 2, 0, 0,
961 (SCM pid, SCM pgid),
962 "Move the process @var{pid} into the process group @var{pgid}. @var{pid} or\n"
963 "@var{pgid} must be integers: they can be zero to indicate the ID of the\n"
964 "current process.\n"
965 "Fails on systems that do not support job control.\n"
966 "The return value is unspecified.")
967 #define FUNC_NAME s_scm_setpgid
968 {
969 /* FIXME(?): may be known as setpgrp. */
970 if (setpgid (scm_to_int (pid), scm_to_int (pgid)) != 0)
971 SCM_SYSERROR;
972 return SCM_UNSPECIFIED;
973 }
974 #undef FUNC_NAME
975 #endif /* HAVE_SETPGID */
976
977 #ifdef HAVE_SETSID
978 SCM_DEFINE (scm_setsid, "setsid", 0, 0, 0,
979 (),
980 "Creates a new session. The current process becomes the session leader\n"
981 "and is put in a new process group. The process will be detached\n"
982 "from its controlling terminal if it has one.\n"
983 "The return value is an integer representing the new process group ID.")
984 #define FUNC_NAME s_scm_setsid
985 {
986 pid_t sid = setsid ();
987 if (sid == -1)
988 SCM_SYSERROR;
989 return SCM_UNSPECIFIED;
990 }
991 #undef FUNC_NAME
992 #endif /* HAVE_SETSID */
993
994 #ifdef HAVE_GETSID
995 SCM_DEFINE (scm_getsid, "getsid", 1, 0, 0,
996 (SCM pid),
997 "Returns the session ID of process @var{pid}. (The session\n"
998 "ID of a process is the process group ID of its session leader.)")
999 #define FUNC_NAME s_scm_getsid
1000 {
1001 return scm_from_int (getsid (scm_to_int (pid)));
1002 }
1003 #undef FUNC_NAME
1004 #endif /* HAVE_GETSID */
1005
1006
1007 /* ttyname returns its result in a single static buffer, hence
1008 scm_i_misc_mutex for thread safety. In glibc 2.3.2 two threads
1009 continuously calling ttyname will otherwise get an overwrite quite
1010 easily.
1011
1012 ttyname_r (when available) could be used instead of scm_i_misc_mutex, but
1013 there's probably little to be gained in either speed or parallelism. */
1014
1015 #ifdef HAVE_TTYNAME
1016 SCM_DEFINE (scm_ttyname, "ttyname", 1, 0, 0,
1017 (SCM port),
1018 "Return a string with the name of the serial terminal device\n"
1019 "underlying @var{port}.")
1020 #define FUNC_NAME s_scm_ttyname
1021 {
1022 char *result;
1023 int fd, err;
1024 SCM ret = SCM_BOOL_F;
1025
1026 port = SCM_COERCE_OUTPORT (port);
1027 SCM_VALIDATE_OPPORT (1, port);
1028 if (!SCM_FPORTP (port))
1029 return SCM_BOOL_F;
1030 fd = SCM_FPORT_FDES (port);
1031
1032 scm_i_scm_pthread_mutex_lock (&scm_i_misc_mutex);
1033
1034 SCM_SYSCALL (result = ttyname (fd));
1035 err = errno;
1036 if (result != NULL)
1037 result = strdup (result);
1038
1039 scm_i_pthread_mutex_unlock (&scm_i_misc_mutex);
1040
1041 if (!result)
1042 {
1043 errno = err;
1044 SCM_SYSERROR;
1045 }
1046 else
1047 ret = scm_take_locale_string (result);
1048
1049 return ret;
1050 }
1051 #undef FUNC_NAME
1052 #endif /* HAVE_TTYNAME */
1053
1054
1055 /* For thread safety "buf" is used instead of NULL for the ctermid static
1056 buffer. Actually it's unlikely the controlling terminal will change
1057 during program execution, and indeed on glibc (2.3.2) it's always just
1058 "/dev/tty", but L_ctermid on the stack is easy and fast and guarantees
1059 safety everywhere. */
1060 #ifdef HAVE_CTERMID
1061 SCM_DEFINE (scm_ctermid, "ctermid", 0, 0, 0,
1062 (),
1063 "Return a string containing the file name of the controlling\n"
1064 "terminal for the current process.")
1065 #define FUNC_NAME s_scm_ctermid
1066 {
1067 char buf[L_ctermid];
1068 char *result = ctermid (buf);
1069 if (*result == '\0')
1070 SCM_SYSERROR;
1071 return scm_from_locale_string (result);
1072 }
1073 #undef FUNC_NAME
1074 #endif /* HAVE_CTERMID */
1075
1076 #ifdef HAVE_TCGETPGRP
1077 SCM_DEFINE (scm_tcgetpgrp, "tcgetpgrp", 1, 0, 0,
1078 (SCM port),
1079 "Return the process group ID of the foreground process group\n"
1080 "associated with the terminal open on the file descriptor\n"
1081 "underlying @var{port}.\n"
1082 "\n"
1083 "If there is no foreground process group, the return value is a\n"
1084 "number greater than 1 that does not match the process group ID\n"
1085 "of any existing process group. This can happen if all of the\n"
1086 "processes in the job that was formerly the foreground job have\n"
1087 "terminated, and no other job has yet been moved into the\n"
1088 "foreground.")
1089 #define FUNC_NAME s_scm_tcgetpgrp
1090 {
1091 int fd;
1092 pid_t pgid;
1093
1094 port = SCM_COERCE_OUTPORT (port);
1095
1096 SCM_VALIDATE_OPFPORT (1, port);
1097 fd = SCM_FPORT_FDES (port);
1098 if ((pgid = tcgetpgrp (fd)) == -1)
1099 SCM_SYSERROR;
1100 return scm_from_int (pgid);
1101 }
1102 #undef FUNC_NAME
1103 #endif /* HAVE_TCGETPGRP */
1104
1105 #ifdef HAVE_TCSETPGRP
1106 SCM_DEFINE (scm_tcsetpgrp, "tcsetpgrp", 2, 0, 0,
1107 (SCM port, SCM pgid),
1108 "Set the foreground process group ID for the terminal used by the file\n"
1109 "descriptor underlying @var{port} to the integer @var{pgid}.\n"
1110 "The calling process\n"
1111 "must be a member of the same session as @var{pgid} and must have the same\n"
1112 "controlling terminal. The return value is unspecified.")
1113 #define FUNC_NAME s_scm_tcsetpgrp
1114 {
1115 int fd;
1116
1117 port = SCM_COERCE_OUTPORT (port);
1118
1119 SCM_VALIDATE_OPFPORT (1, port);
1120 fd = SCM_FPORT_FDES (port);
1121 if (tcsetpgrp (fd, scm_to_int (pgid)) == -1)
1122 SCM_SYSERROR;
1123 return SCM_UNSPECIFIED;
1124 }
1125 #undef FUNC_NAME
1126 #endif /* HAVE_TCSETPGRP */
1127
1128 SCM_DEFINE (scm_execl, "execl", 1, 0, 1,
1129 (SCM filename, SCM args),
1130 "Executes the file named by @var{filename} as a new process image.\n"
1131 "The remaining arguments are supplied to the process; from a C program\n"
1132 "they are accessible as the @code{argv} argument to @code{main}.\n"
1133 "Conventionally the first @var{arg} is the same as @var{filename}.\n"
1134 "All arguments must be strings.\n\n"
1135 "If @var{arg} is missing, @var{path} is executed with a null\n"
1136 "argument list, which may have system-dependent side-effects.\n\n"
1137 "This procedure is currently implemented using the @code{execv} system\n"
1138 "call, but we call it @code{execl} because of its Scheme calling interface.")
1139 #define FUNC_NAME s_scm_execl
1140 {
1141 char *exec_file;
1142 char **exec_argv;
1143
1144 scm_dynwind_begin (0);
1145
1146 exec_file = scm_to_locale_string (filename);
1147 scm_dynwind_free (exec_file);
1148
1149 exec_argv = scm_i_allocate_string_pointers (args);
1150
1151 execv (exec_file,
1152 #ifdef __MINGW32__
1153 /* extra "const" in mingw formals, provokes warning from gcc */
1154 (const char * const *)
1155 #endif
1156 exec_argv);
1157 SCM_SYSERROR;
1158
1159 /* not reached. */
1160 scm_dynwind_end ();
1161 return SCM_BOOL_F;
1162 }
1163 #undef FUNC_NAME
1164
1165 SCM_DEFINE (scm_execlp, "execlp", 1, 0, 1,
1166 (SCM filename, SCM args),
1167 "Similar to @code{execl}, however if\n"
1168 "@var{filename} does not contain a slash\n"
1169 "then the file to execute will be located by searching the\n"
1170 "directories listed in the @code{PATH} environment variable.\n\n"
1171 "This procedure is currently implemented using the @code{execvp} system\n"
1172 "call, but we call it @code{execlp} because of its Scheme calling interface.")
1173 #define FUNC_NAME s_scm_execlp
1174 {
1175 char *exec_file;
1176 char **exec_argv;
1177
1178 scm_dynwind_begin (0);
1179
1180 exec_file = scm_to_locale_string (filename);
1181 scm_dynwind_free (exec_file);
1182
1183 exec_argv = scm_i_allocate_string_pointers (args);
1184
1185 execvp (exec_file,
1186 #ifdef __MINGW32__
1187 /* extra "const" in mingw formals, provokes warning from gcc */
1188 (const char * const *)
1189 #endif
1190 exec_argv);
1191 SCM_SYSERROR;
1192
1193 /* not reached. */
1194 scm_dynwind_end ();
1195 return SCM_BOOL_F;
1196 }
1197 #undef FUNC_NAME
1198
1199
1200 /* OPTIMIZE-ME: scm_execle doesn't need malloced copies of the environment
1201 list strings the way environ_list_to_c gives. */
1202
1203 SCM_DEFINE (scm_execle, "execle", 2, 0, 1,
1204 (SCM filename, SCM env, SCM args),
1205 "Similar to @code{execl}, but the environment of the new process is\n"
1206 "specified by @var{env}, which must be a list of strings as returned by the\n"
1207 "@code{environ} procedure.\n\n"
1208 "This procedure is currently implemented using the @code{execve} system\n"
1209 "call, but we call it @code{execle} because of its Scheme calling interface.")
1210 #define FUNC_NAME s_scm_execle
1211 {
1212 char **exec_argv;
1213 char **exec_env;
1214 char *exec_file;
1215
1216 scm_dynwind_begin (0);
1217
1218 exec_file = scm_to_locale_string (filename);
1219 scm_dynwind_free (exec_file);
1220
1221 exec_argv = scm_i_allocate_string_pointers (args);
1222 exec_env = scm_i_allocate_string_pointers (env);
1223
1224 execve (exec_file,
1225 #ifdef __MINGW32__
1226 /* extra "const" in mingw formals, provokes warning from gcc */
1227 (const char * const *)
1228 #endif
1229 exec_argv,
1230 #ifdef __MINGW32__
1231 /* extra "const" in mingw formals, provokes warning from gcc */
1232 (const char * const *)
1233 #endif
1234 exec_env);
1235 SCM_SYSERROR;
1236
1237 /* not reached. */
1238 scm_dynwind_end ();
1239 return SCM_BOOL_F;
1240 }
1241 #undef FUNC_NAME
1242
1243 #ifdef HAVE_FORK
1244 SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
1245 (),
1246 "Creates a new \"child\" process by duplicating the current \"parent\" process.\n"
1247 "In the child the return value is 0. In the parent the return value is\n"
1248 "the integer process ID of the child.\n\n"
1249 "This procedure has been renamed from @code{fork} to avoid a naming conflict\n"
1250 "with the scsh fork.")
1251 #define FUNC_NAME s_scm_fork
1252 {
1253 int pid;
1254 if (scm_ilength (scm_all_threads ()) != 1)
1255 /* Other threads may be holding on to resources that Guile needs --
1256 it is not safe to permit one thread to fork while others are
1257 running.
1258
1259 In addition, POSIX clearly specifies that if a multi-threaded
1260 program forks, the child must only call functions that are
1261 async-signal-safe. We can't guarantee that in general. The best
1262 we can do is to allow forking only very early, before any call to
1263 sigaction spawns the signal-handling thread. */
1264 scm_display
1265 (scm_from_latin1_string
1266 ("warning: call to primitive-fork while multiple threads are running;\n"
1267 " further behavior unspecified. See \"Processes\" in the\n"
1268 " manual, for more information.\n"),
1269 scm_current_warning_port ());
1270 pid = fork ();
1271 if (pid == -1)
1272 SCM_SYSERROR;
1273 return scm_from_int (pid);
1274 }
1275 #undef FUNC_NAME
1276
1277 /* Since Guile uses threads, we have to be very careful to avoid calling
1278 functions that are not async-signal-safe in the child. That's why
1279 this function is implemented in C. */
1280 static SCM
1281 scm_open_process (SCM mode, SCM prog, SCM args)
1282 #define FUNC_NAME "open-process"
1283 {
1284 long mode_bits;
1285 int reading, writing;
1286 int c2p[2]; /* Child to parent. */
1287 int p2c[2]; /* Parent to child. */
1288 int in = -1, out = -1, err = -1;
1289 int pid;
1290 char *exec_file;
1291 char **exec_argv;
1292 int max_fd = 1024;
1293
1294 exec_file = scm_to_locale_string (prog);
1295 exec_argv = scm_i_allocate_string_pointers (scm_cons (prog, args));
1296
1297 mode_bits = scm_i_mode_bits (mode);
1298 reading = mode_bits & SCM_RDNG;
1299 writing = mode_bits & SCM_WRTNG;
1300
1301 if (reading)
1302 {
1303 if (pipe (c2p))
1304 {
1305 int errno_save = errno;
1306 free (exec_file);
1307 errno = errno_save;
1308 SCM_SYSERROR;
1309 }
1310 out = c2p[1];
1311 }
1312
1313 if (writing)
1314 {
1315 if (pipe (p2c))
1316 {
1317 int errno_save = errno;
1318 free (exec_file);
1319 if (reading)
1320 {
1321 close (c2p[0]);
1322 close (c2p[1]);
1323 }
1324 errno = errno_save;
1325 SCM_SYSERROR;
1326 }
1327 in = p2c[0];
1328 }
1329
1330 {
1331 SCM port;
1332
1333 if (SCM_OPOUTFPORTP ((port = scm_current_error_port ())))
1334 err = SCM_FPORT_FDES (port);
1335 if (out == -1 && SCM_OPOUTFPORTP ((port = scm_current_output_port ())))
1336 out = SCM_FPORT_FDES (port);
1337 if (in == -1 && SCM_OPINFPORTP ((port = scm_current_input_port ())))
1338 in = SCM_FPORT_FDES (port);
1339 }
1340
1341 #if defined (HAVE_GETRLIMIT) && defined (RLIMIT_NOFILE)
1342 {
1343 struct rlimit lim = { 0, 0 };
1344 if (getrlimit (RLIMIT_NOFILE, &lim) == 0)
1345 max_fd = lim.rlim_cur;
1346 }
1347 #endif
1348
1349 pid = fork ();
1350
1351 if (pid == -1)
1352 {
1353 int errno_save = errno;
1354 free (exec_file);
1355 if (reading)
1356 {
1357 close (c2p[0]);
1358 close (c2p[1]);
1359 }
1360 if (writing)
1361 {
1362 close (p2c[0]);
1363 close (p2c[1]);
1364 }
1365 errno = errno_save;
1366 SCM_SYSERROR;
1367 }
1368
1369 if (pid)
1370 /* Parent. */
1371 {
1372 SCM read_port = SCM_BOOL_F, write_port = SCM_BOOL_F;
1373
1374 /* There is no sense in catching errors on close(). */
1375 if (reading)
1376 {
1377 close (c2p[1]);
1378 read_port = scm_fdes_to_port (c2p[0], "r", sym_read_pipe);
1379 scm_setvbuf (read_port, scm_from_int (_IONBF), SCM_UNDEFINED);
1380 }
1381 if (writing)
1382 {
1383 close (p2c[0]);
1384 write_port = scm_fdes_to_port (p2c[1], "w", sym_write_pipe);
1385 scm_setvbuf (write_port, scm_from_int (_IONBF), SCM_UNDEFINED);
1386 }
1387
1388 return scm_values
1389 (scm_list_3 (read_port, write_port, scm_from_int (pid)));
1390 }
1391
1392 /* The child. */
1393 if (reading)
1394 close (c2p[0]);
1395 if (writing)
1396 close (p2c[1]);
1397
1398 /* Close all file descriptors in ports inherited from the parent
1399 except for in, out, and err. Heavy-handed, but robust. */
1400 while (max_fd--)
1401 if (max_fd != in && max_fd != out && max_fd != err)
1402 close (max_fd);
1403
1404 /* Ignore errors on these open() calls. */
1405 if (in == -1)
1406 in = open ("/dev/null", O_RDONLY);
1407 if (out == -1)
1408 out = open ("/dev/null", O_WRONLY);
1409 if (err == -1)
1410 err = open ("/dev/null", O_WRONLY);
1411
1412 if (in > 0)
1413 {
1414 if (out == 0)
1415 do out = dup (out); while (errno == EINTR);
1416 if (err == 0)
1417 do err = dup (err); while (errno == EINTR);
1418 do dup2 (in, 0); while (errno == EINTR);
1419 close (in);
1420 }
1421 if (out > 1)
1422 {
1423 if (err == 1)
1424 do err = dup (err); while (errno == EINTR);
1425 do dup2 (out, 1); while (errno == EINTR);
1426 close (out);
1427 }
1428 if (err > 2)
1429 {
1430 do dup2 (err, 2); while (errno == EINTR);
1431 close (err);
1432 }
1433
1434 execvp (exec_file,
1435 #ifdef __MINGW32__
1436 /* extra "const" in mingw formals, provokes warning from gcc */
1437 (const char * const *)
1438 #endif
1439 exec_argv);
1440
1441 /* The exec failed! There is nothing sensible to do. */
1442 if (err > 0)
1443 {
1444 char *msg = strerror (errno);
1445 fprintf (fdopen (err, "a"), "In execlp of %s: %s\n",
1446 exec_file, msg);
1447 }
1448
1449 _exit (EXIT_FAILURE);
1450 /* Not reached. */
1451 return SCM_BOOL_F;
1452 }
1453 #undef FUNC_NAME
1454 #endif /* HAVE_FORK */
1455
1456 #ifdef __MINGW32__
1457 # include "win32-uname.h"
1458 #endif
1459
1460 #if defined (HAVE_UNAME) || defined (__MINGW32__)
1461 SCM_DEFINE (scm_uname, "uname", 0, 0, 0,
1462 (),
1463 "Return an object with some information about the computer\n"
1464 "system the program is running on.")
1465 #define FUNC_NAME s_scm_uname
1466 {
1467 struct utsname buf;
1468 SCM result = scm_c_make_vector (5, SCM_UNSPECIFIED);
1469 if (uname (&buf) < 0)
1470 SCM_SYSERROR;
1471 SCM_SIMPLE_VECTOR_SET(result, 0, scm_from_locale_string (buf.sysname));
1472 SCM_SIMPLE_VECTOR_SET(result, 1, scm_from_locale_string (buf.nodename));
1473 SCM_SIMPLE_VECTOR_SET(result, 2, scm_from_locale_string (buf.release));
1474 SCM_SIMPLE_VECTOR_SET(result, 3, scm_from_locale_string (buf.version));
1475 SCM_SIMPLE_VECTOR_SET(result, 4, scm_from_locale_string (buf.machine));
1476 /*
1477 a linux special?
1478 SCM_SIMPLE_VECTOR_SET(result, 5, scm_from_locale_string (buf.domainname));
1479 */
1480 return result;
1481 }
1482 #undef FUNC_NAME
1483 #endif /* HAVE_UNAME */
1484
1485 SCM_DEFINE (scm_environ, "environ", 0, 1, 0,
1486 (SCM env),
1487 "If @var{env} is omitted, return the current environment (in the\n"
1488 "Unix sense) as a list of strings. Otherwise set the current\n"
1489 "environment, which is also the default environment for child\n"
1490 "processes, to the supplied list of strings. Each member of\n"
1491 "@var{env} should be of the form @code{NAME=VALUE} and values of\n"
1492 "@code{NAME} should not be duplicated. If @var{env} is supplied\n"
1493 "then the return value is unspecified.")
1494 #define FUNC_NAME s_scm_environ
1495 {
1496 if (SCM_UNBNDP (env))
1497 return scm_makfromstrs (-1, environ);
1498 else
1499 {
1500 environ = scm_i_allocate_string_pointers (env);
1501 return SCM_UNSPECIFIED;
1502 }
1503 }
1504 #undef FUNC_NAME
1505
1506 #ifdef L_tmpnam
1507
1508 SCM_DEFINE (scm_tmpnam, "tmpnam", 0, 0, 0,
1509 (),
1510 "Return a name in the file system that does not match any\n"
1511 "existing file. However there is no guarantee that another\n"
1512 "process will not create the file after @code{tmpnam} is called.\n"
1513 "Care should be taken if opening the file, e.g., use the\n"
1514 "@code{O_EXCL} open flag or use @code{mkstemp!} instead.")
1515 #define FUNC_NAME s_scm_tmpnam
1516 {
1517 char name[L_tmpnam];
1518 char *rv;
1519
1520 SCM_SYSCALL (rv = tmpnam (name));
1521 if (rv == NULL)
1522 /* not SCM_SYSERROR since errno probably not set. */
1523 SCM_MISC_ERROR ("tmpnam failed", SCM_EOL);
1524 return scm_from_locale_string (name);
1525 }
1526 #undef FUNC_NAME
1527
1528 #endif
1529
1530 SCM_DEFINE (scm_tmpfile, "tmpfile", 0, 0, 0,
1531 (void),
1532 "Return an input/output port to a unique temporary file\n"
1533 "named using the path prefix @code{P_tmpdir} defined in\n"
1534 "@file{stdio.h}.\n"
1535 "The file is automatically deleted when the port is closed\n"
1536 "or the program terminates.")
1537 #define FUNC_NAME s_scm_tmpfile
1538 {
1539 FILE *rv;
1540 int fd;
1541
1542 if (! (rv = tmpfile ()))
1543 SCM_SYSERROR;
1544
1545 #ifndef __MINGW32__
1546 fd = dup (fileno (rv));
1547 fclose (rv);
1548 #else
1549 fd = fileno (rv);
1550 /* FIXME: leaking the file, it will never be closed! */
1551 #endif
1552
1553 return scm_fdes_to_port (fd, "w+", SCM_BOOL_F);
1554 }
1555 #undef FUNC_NAME
1556
1557 SCM_DEFINE (scm_utime, "utime", 1, 5, 0,
1558 (SCM pathname, SCM actime, SCM modtime, SCM actimens, SCM modtimens,
1559 SCM flags),
1560 "@code{utime} sets the access and modification times for the\n"
1561 "file named by @var{pathname}. If @var{actime} or @var{modtime} is\n"
1562 "not supplied, then the current time is used. @var{actime} and\n"
1563 "@var{modtime} must be integer time values as returned by the\n"
1564 "@code{current-time} procedure.\n\n"
1565 "The optional @var{actimens} and @var{modtimens} are nanoseconds\n"
1566 "to add @var{actime} and @var{modtime}. Nanosecond precision is\n"
1567 "only supported on some combinations of file systems and operating\n"
1568 "systems.\n"
1569 "@lisp\n"
1570 "(utime \"foo\" (- (current-time) 3600))\n"
1571 "@end lisp\n"
1572 "will set the access time to one hour in the past and the\n"
1573 "modification time to the current time.")
1574 #define FUNC_NAME s_scm_utime
1575 {
1576 int rv;
1577 time_t atim_sec, mtim_sec;
1578 long atim_nsec, mtim_nsec;
1579 int f;
1580
1581 if (SCM_UNBNDP (actime))
1582 {
1583 #ifdef HAVE_UTIMENSAT
1584 atim_sec = 0;
1585 atim_nsec = UTIME_NOW;
1586 #else
1587 SCM_SYSCALL (time (&atim_sec));
1588 atim_nsec = 0;
1589 #endif
1590 }
1591 else
1592 {
1593 atim_sec = SCM_NUM2ULONG (2, actime);
1594 if (SCM_UNBNDP (actimens))
1595 atim_nsec = 0;
1596 else
1597 atim_nsec = SCM_NUM2LONG (4, actimens);
1598 }
1599
1600 if (SCM_UNBNDP (modtime))
1601 {
1602 #ifdef HAVE_UTIMENSAT
1603 mtim_sec = 0;
1604 mtim_nsec = UTIME_NOW;
1605 #else
1606 SCM_SYSCALL (time (&mtim_sec));
1607 mtim_nsec = 0;
1608 #endif
1609 }
1610 else
1611 {
1612 mtim_sec = SCM_NUM2ULONG (3, modtime);
1613 if (SCM_UNBNDP (modtimens))
1614 mtim_nsec = 0;
1615 else
1616 mtim_nsec = SCM_NUM2LONG (5, modtimens);
1617 }
1618
1619 if (SCM_UNBNDP (flags))
1620 f = 0;
1621 else
1622 f = SCM_NUM2INT (6, flags);
1623
1624 #ifdef HAVE_UTIMENSAT
1625 {
1626 struct timespec times[2];
1627 times[0].tv_sec = atim_sec;
1628 times[0].tv_nsec = atim_nsec;
1629 times[1].tv_sec = mtim_sec;
1630 times[1].tv_nsec = mtim_nsec;
1631
1632 STRING_SYSCALL (pathname, c_pathname,
1633 rv = utimensat (AT_FDCWD, c_pathname, times, f));
1634 }
1635 #else
1636 {
1637 struct utimbuf utm;
1638 utm.actime = atim_sec;
1639 utm.modtime = mtim_sec;
1640
1641 STRING_SYSCALL (pathname, c_pathname,
1642 rv = utime (c_pathname, &utm));
1643 }
1644 #endif
1645
1646 if (rv != 0)
1647 SCM_SYSERROR;
1648 return SCM_UNSPECIFIED;
1649 }
1650 #undef FUNC_NAME
1651
1652 SCM_DEFINE (scm_getpid, "getpid", 0, 0, 0,
1653 (),
1654 "Return an integer representing the current process ID.")
1655 #define FUNC_NAME s_scm_getpid
1656 {
1657 return scm_from_ulong (getpid ());
1658 }
1659 #undef FUNC_NAME
1660
1661 SCM_DEFINE (scm_putenv, "putenv", 1, 0, 0,
1662 (SCM str),
1663 "Modifies the environment of the current process, which is also\n"
1664 "the default environment inherited by child processes. If\n"
1665 "@var{str} is of the form @code{NAME=VALUE} then it will be\n"
1666 "written directly into the environment, replacing any existing\n"
1667 "environment string with name matching @code{NAME}. If\n"
1668 "@var{str} does not contain an equal sign, then any existing\n"
1669 "string with name matching @var{str} will be removed.\n"
1670 "\n"
1671 "The return value is unspecified.")
1672 #define FUNC_NAME s_scm_putenv
1673 {
1674 int rv;
1675 char *c_str = scm_to_locale_string (str);
1676
1677 /* Leave C_STR in the environment. */
1678
1679 /* Gnulib's `putenv' module honors the semantics described above. */
1680 rv = putenv (c_str);
1681 if (rv < 0)
1682 SCM_SYSERROR;
1683
1684 return SCM_UNSPECIFIED;
1685 }
1686 #undef FUNC_NAME
1687
1688 /* This mutex is used to serialize invocations of `setlocale ()' on non-GNU
1689 systems (i.e., systems where a reentrant locale API is not available). It
1690 is also acquired before calls to `nl_langinfo ()'. See `i18n.c' for
1691 details. */
1692 scm_i_pthread_mutex_t scm_i_locale_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER;
1693
1694 #ifdef HAVE_SETLOCALE
1695
1696 SCM_DEFINE (scm_setlocale, "setlocale", 1, 1, 0,
1697 (SCM category, SCM locale),
1698 "If @var{locale} is omitted, return the current value of the\n"
1699 "specified locale category as a system-dependent string.\n"
1700 "@var{category} should be specified using the values\n"
1701 "@code{LC_COLLATE}, @code{LC_ALL} etc.\n"
1702 "\n"
1703 "Otherwise the specified locale category is set to the string\n"
1704 "@var{locale} and the new value is returned as a\n"
1705 "system-dependent string. If @var{locale} is an empty string,\n"
1706 "the locale will be set using environment variables.\n"
1707 "\n"
1708 "When the locale is changed, the character encoding of the new\n"
1709 "locale (UTF-8, ISO-8859-1, etc.) is used for the current\n"
1710 "input, output, and error ports\n")
1711 #define FUNC_NAME s_scm_setlocale
1712 {
1713 int c_category;
1714 char *clocale;
1715 char *rv;
1716 const char *enc;
1717
1718 scm_dynwind_begin (0);
1719
1720 if (SCM_UNBNDP (locale))
1721 {
1722 clocale = NULL;
1723 }
1724 else
1725 {
1726 clocale = scm_to_locale_string (locale);
1727 scm_dynwind_free (clocale);
1728 }
1729
1730 c_category = scm_i_to_lc_category (category, 1);
1731
1732 scm_i_pthread_mutex_lock (&scm_i_locale_mutex);
1733 rv = setlocale (c_category, clocale);
1734 scm_i_pthread_mutex_unlock (&scm_i_locale_mutex);
1735
1736 if (rv == NULL)
1737 {
1738 /* POSIX and C99 don't say anything about setlocale setting errno, so
1739 force a sensible value here. glibc leaves ENOENT, which would be
1740 fine, but it's not a documented feature. */
1741 errno = EINVAL;
1742 SCM_SYSERROR;
1743 }
1744
1745 enc = locale_charset ();
1746
1747 /* Set the default encoding for new ports. */
1748 scm_i_set_default_port_encoding (enc);
1749
1750 /* Set the encoding for the stdio ports. */
1751 scm_i_set_port_encoding_x (scm_current_input_port (), enc);
1752 scm_i_set_port_encoding_x (scm_current_output_port (), enc);
1753 scm_i_set_port_encoding_x (scm_current_error_port (), enc);
1754
1755 scm_dynwind_end ();
1756 return scm_from_locale_string (rv);
1757 }
1758 #undef FUNC_NAME
1759 #endif /* HAVE_SETLOCALE */
1760
1761 #ifdef HAVE_MKNOD
1762 SCM_DEFINE (scm_mknod, "mknod", 4, 0, 0,
1763 (SCM path, SCM type, SCM perms, SCM dev),
1764 "Creates a new special file, such as a file corresponding to a device.\n"
1765 "@var{path} specifies the name of the file. @var{type} should\n"
1766 "be one of the following symbols:\n"
1767 "regular, directory, symlink, block-special, char-special,\n"
1768 "fifo, or socket. @var{perms} (an integer) specifies the file permissions.\n"
1769 "@var{dev} (an integer) specifies which device the special file refers\n"
1770 "to. Its exact interpretation depends on the kind of special file\n"
1771 "being created.\n\n"
1772 "E.g.,\n"
1773 "@lisp\n"
1774 "(mknod \"/dev/fd0\" 'block-special #o660 (+ (* 2 256) 2))\n"
1775 "@end lisp\n\n"
1776 "The return value is unspecified.")
1777 #define FUNC_NAME s_scm_mknod
1778 {
1779 int val;
1780 const char *p;
1781 int ctype = 0;
1782
1783 SCM_VALIDATE_STRING (1, path);
1784 SCM_VALIDATE_SYMBOL (2, type);
1785
1786 p = scm_i_symbol_chars (type);
1787 if (strcmp (p, "regular") == 0)
1788 ctype = S_IFREG;
1789 else if (strcmp (p, "directory") == 0)
1790 ctype = S_IFDIR;
1791 #ifdef S_IFLNK
1792 /* systems without symlinks probably don't have S_IFLNK defined */
1793 else if (strcmp (p, "symlink") == 0)
1794 ctype = S_IFLNK;
1795 #endif
1796 else if (strcmp (p, "block-special") == 0)
1797 ctype = S_IFBLK;
1798 else if (strcmp (p, "char-special") == 0)
1799 ctype = S_IFCHR;
1800 else if (strcmp (p, "fifo") == 0)
1801 ctype = S_IFIFO;
1802 #ifdef S_IFSOCK
1803 else if (strcmp (p, "socket") == 0)
1804 ctype = S_IFSOCK;
1805 #endif
1806 else
1807 SCM_OUT_OF_RANGE (2, type);
1808
1809 STRING_SYSCALL (path, c_path,
1810 val = mknod (c_path,
1811 ctype | scm_to_int (perms),
1812 scm_to_int (dev)));
1813 if (val != 0)
1814 SCM_SYSERROR;
1815 return SCM_UNSPECIFIED;
1816 }
1817 #undef FUNC_NAME
1818 #endif /* HAVE_MKNOD */
1819
1820 #ifdef HAVE_NICE
1821 SCM_DEFINE (scm_nice, "nice", 1, 0, 0,
1822 (SCM incr),
1823 "Increment the priority of the current process by @var{incr}. A higher\n"
1824 "priority value means that the process runs less often.\n"
1825 "The return value is unspecified.")
1826 #define FUNC_NAME s_scm_nice
1827 {
1828 /* nice() returns "prio-NZERO" on success or -1 on error, but -1 can arise
1829 from "prio-NZERO", so an error must be detected from errno changed */
1830 errno = 0;
1831 nice (scm_to_int (incr));
1832 if (errno != 0)
1833 SCM_SYSERROR;
1834
1835 return SCM_UNSPECIFIED;
1836 }
1837 #undef FUNC_NAME
1838 #endif /* HAVE_NICE */
1839
1840 #ifdef HAVE_SYNC
1841 SCM_DEFINE (scm_sync, "sync", 0, 0, 0,
1842 (),
1843 "Flush the operating system disk buffers.\n"
1844 "The return value is unspecified.")
1845 #define FUNC_NAME s_scm_sync
1846 {
1847 sync();
1848 return SCM_UNSPECIFIED;
1849 }
1850 #undef FUNC_NAME
1851 #endif /* HAVE_SYNC */
1852
1853
1854 /* crypt() returns a pointer to a static buffer, so we use scm_i_misc_mutex
1855 to avoid another thread overwriting it. A test program running crypt
1856 continuously in two threads can be quickly seen tripping this problem.
1857 crypt() is pretty slow normally, so a mutex shouldn't add much overhead.
1858
1859 glibc has a thread-safe crypt_r, but (in version 2.3.2) it runs a lot
1860 slower (about 5x) than plain crypt if you pass an uninitialized data
1861 block each time. Presumably there's some one-time setups. The best way
1862 to use crypt_r for parallel execution in multiple threads would probably
1863 be to maintain a little pool of initialized crypt_data structures, take
1864 one and use it, then return it to the pool. That pool could be garbage
1865 collected so it didn't add permanently to memory use if only a few crypt
1866 calls are made. But we expect crypt will be used rarely, and even more
1867 rarely will there be any desire for lots of parallel execution on
1868 multiple cpus. So for now we don't bother with anything fancy, just
1869 ensure it works. */
1870
1871 #ifdef HAVE_CRYPT
1872 SCM_DEFINE (scm_crypt, "crypt", 2, 0, 0,
1873 (SCM key, SCM salt),
1874 "Encrypt @var{key} using @var{salt} as the salt value to the\n"
1875 "crypt(3) library call.")
1876 #define FUNC_NAME s_scm_crypt
1877 {
1878 SCM ret;
1879 char *c_key, *c_salt, *c_ret;
1880
1881 scm_dynwind_begin (0);
1882 scm_i_dynwind_pthread_mutex_lock (&scm_i_misc_mutex);
1883
1884 c_key = scm_to_locale_string (key);
1885 scm_dynwind_free (c_key);
1886 c_salt = scm_to_locale_string (salt);
1887 scm_dynwind_free (c_salt);
1888
1889 /* The Linux crypt(3) man page says crypt will return NULL and set errno
1890 on error. (Eg. ENOSYS if legal restrictions mean it cannot be
1891 implemented). */
1892 c_ret = crypt (c_key, c_salt);
1893 if (c_ret == NULL)
1894 SCM_SYSERROR;
1895
1896 ret = scm_from_locale_string (c_ret);
1897 scm_dynwind_end ();
1898 return ret;
1899 }
1900 #undef FUNC_NAME
1901 #endif /* HAVE_CRYPT */
1902
1903 #if HAVE_CHROOT
1904 SCM_DEFINE (scm_chroot, "chroot", 1, 0, 0,
1905 (SCM path),
1906 "Change the root directory to that specified in @var{path}.\n"
1907 "This directory will be used for path names beginning with\n"
1908 "@file{/}. The root directory is inherited by all children\n"
1909 "of the current process. Only the superuser may change the\n"
1910 "root directory.")
1911 #define FUNC_NAME s_scm_chroot
1912 {
1913 int rv;
1914
1915 WITH_STRING (path, c_path,
1916 rv = chroot (c_path));
1917 if (rv == -1)
1918 SCM_SYSERROR;
1919 return SCM_UNSPECIFIED;
1920 }
1921 #undef FUNC_NAME
1922 #endif /* HAVE_CHROOT */
1923
1924
1925 #ifdef __MINGW32__
1926 /* Wrapper function to supplying `getlogin()' under Windows. */
1927 static char * getlogin (void)
1928 {
1929 static char user[256];
1930 static unsigned long len = 256;
1931
1932 if (!GetUserName (user, &len))
1933 return NULL;
1934 return user;
1935 }
1936 #endif /* __MINGW32__ */
1937
1938
1939 #if defined (HAVE_GETLOGIN) || defined (__MINGW32__)
1940 SCM_DEFINE (scm_getlogin, "getlogin", 0, 0, 0,
1941 (void),
1942 "Return a string containing the name of the user logged in on\n"
1943 "the controlling terminal of the process, or @code{#f} if this\n"
1944 "information cannot be obtained.")
1945 #define FUNC_NAME s_scm_getlogin
1946 {
1947 char * p;
1948
1949 p = getlogin ();
1950 if (!p || !*p)
1951 return SCM_BOOL_F;
1952 return scm_from_locale_string (p);
1953 }
1954 #undef FUNC_NAME
1955 #endif /* HAVE_GETLOGIN */
1956
1957 #if HAVE_GETPRIORITY
1958 SCM_DEFINE (scm_getpriority, "getpriority", 2, 0, 0,
1959 (SCM which, SCM who),
1960 "Return the scheduling priority of the process, process group\n"
1961 "or user, as indicated by @var{which} and @var{who}. @var{which}\n"
1962 "is one of the variables @code{PRIO_PROCESS}, @code{PRIO_PGRP}\n"
1963 "or @code{PRIO_USER}, and @var{who} is interpreted relative to\n"
1964 "@var{which} (a process identifier for @code{PRIO_PROCESS},\n"
1965 "process group identifier for @code{PRIO_PGRP}, and a user\n"
1966 "identifier for @code{PRIO_USER}. A zero value of @var{who}\n"
1967 "denotes the current process, process group, or user. Return\n"
1968 "the highest priority (lowest numerical value) of any of the\n"
1969 "specified processes.")
1970 #define FUNC_NAME s_scm_getpriority
1971 {
1972 int cwhich, cwho, ret;
1973
1974 cwhich = scm_to_int (which);
1975 cwho = scm_to_int (who);
1976
1977 /* We have to clear errno and examine it later, because -1 is a
1978 legal return value for getpriority(). */
1979 errno = 0;
1980 ret = getpriority (cwhich, cwho);
1981 if (errno != 0)
1982 SCM_SYSERROR;
1983 return scm_from_int (ret);
1984 }
1985 #undef FUNC_NAME
1986 #endif /* HAVE_GETPRIORITY */
1987
1988 #if HAVE_SETPRIORITY
1989 SCM_DEFINE (scm_setpriority, "setpriority", 3, 0, 0,
1990 (SCM which, SCM who, SCM prio),
1991 "Set the scheduling priority of the process, process group\n"
1992 "or user, as indicated by @var{which} and @var{who}. @var{which}\n"
1993 "is one of the variables @code{PRIO_PROCESS}, @code{PRIO_PGRP}\n"
1994 "or @code{PRIO_USER}, and @var{who} is interpreted relative to\n"
1995 "@var{which} (a process identifier for @code{PRIO_PROCESS},\n"
1996 "process group identifier for @code{PRIO_PGRP}, and a user\n"
1997 "identifier for @code{PRIO_USER}. A zero value of @var{who}\n"
1998 "denotes the current process, process group, or user.\n"
1999 "@var{prio} is a value in the range -20 and 20, the default\n"
2000 "priority is 0; lower priorities cause more favorable\n"
2001 "scheduling. Sets the priority of all of the specified\n"
2002 "processes. Only the super-user may lower priorities.\n"
2003 "The return value is not specified.")
2004 #define FUNC_NAME s_scm_setpriority
2005 {
2006 int cwhich, cwho, cprio;
2007
2008 cwhich = scm_to_int (which);
2009 cwho = scm_to_int (who);
2010 cprio = scm_to_int (prio);
2011
2012 if (setpriority (cwhich, cwho, cprio) == -1)
2013 SCM_SYSERROR;
2014 return SCM_UNSPECIFIED;
2015 }
2016 #undef FUNC_NAME
2017 #endif /* HAVE_SETPRIORITY */
2018
2019 #ifdef HAVE_SCHED_GETAFFINITY
2020
2021 static SCM
2022 cpu_set_to_bitvector (const cpu_set_t *cs)
2023 {
2024 SCM bv;
2025 size_t cpu;
2026
2027 bv = scm_c_make_bitvector (sizeof (*cs), SCM_BOOL_F);
2028
2029 for (cpu = 0; cpu < sizeof (*cs); cpu++)
2030 {
2031 if (CPU_ISSET (cpu, cs))
2032 /* XXX: This is inefficient but avoids code duplication. */
2033 scm_c_bitvector_set_x (bv, cpu, SCM_BOOL_T);
2034 }
2035
2036 return bv;
2037 }
2038
2039 SCM_DEFINE (scm_getaffinity, "getaffinity", 1, 0, 0,
2040 (SCM pid),
2041 "Return a bitvector representing the CPU affinity mask for\n"
2042 "process @var{pid}. Each CPU the process has affinity with\n"
2043 "has its corresponding bit set in the returned bitvector.\n"
2044 "The number of bits set is a good estimate of how many CPUs\n"
2045 "Guile can use without stepping on other processes' toes.\n\n"
2046 "Currently this procedure is only defined on GNU variants\n"
2047 "(@pxref{CPU Affinity, @code{sched_getaffinity},, libc, The\n"
2048 "GNU C Library Reference Manual}).\n")
2049 #define FUNC_NAME s_scm_getaffinity
2050 {
2051 int err;
2052 cpu_set_t cs;
2053
2054 CPU_ZERO (&cs);
2055 err = sched_getaffinity (scm_to_int (pid), sizeof (cs), &cs);
2056 if (err)
2057 SCM_SYSERROR;
2058
2059 return cpu_set_to_bitvector (&cs);
2060 }
2061 #undef FUNC_NAME
2062
2063 #endif /* HAVE_SCHED_GETAFFINITY */
2064
2065 #ifdef HAVE_SCHED_SETAFFINITY
2066
2067 SCM_DEFINE (scm_setaffinity, "setaffinity", 2, 0, 0,
2068 (SCM pid, SCM mask),
2069 "Install the CPU affinity mask @var{mask}, a bitvector, for\n"
2070 "the process or thread with ID @var{pid}. The return value\n"
2071 "is unspecified.\n\n"
2072 "Currently this procedure is only defined on GNU variants\n"
2073 "(@pxref{CPU Affinity, @code{sched_setaffinity},, libc, The\n"
2074 "GNU C Library Reference Manual}).\n")
2075 #define FUNC_NAME s_scm_setaffinity
2076 {
2077 cpu_set_t cs;
2078 scm_t_array_handle handle;
2079 const scm_t_uint32 *c_mask;
2080 size_t len, off, cpu;
2081 ssize_t inc;
2082 int err;
2083
2084 c_mask = scm_bitvector_elements (mask, &handle, &off, &len, &inc);
2085
2086 CPU_ZERO (&cs);
2087 for (cpu = 0; cpu < len; cpu++)
2088 {
2089 size_t idx;
2090
2091 idx = cpu * inc + off;
2092 if (c_mask[idx / 32] & (1UL << (idx % 32)))
2093 CPU_SET (cpu, &cs);
2094 }
2095
2096 err = sched_setaffinity (scm_to_int (pid), sizeof (cs), &cs);
2097 if (err)
2098 SCM_SYSERROR;
2099
2100 return SCM_UNSPECIFIED;
2101 }
2102 #undef FUNC_NAME
2103
2104 #endif /* HAVE_SCHED_SETAFFINITY */
2105
2106 \f
2107 #if HAVE_GETPASS
2108 SCM_DEFINE (scm_getpass, "getpass", 1, 0, 0,
2109 (SCM prompt),
2110 "Display @var{prompt} to the standard error output and read\n"
2111 "a password from @file{/dev/tty}. If this file is not\n"
2112 "accessible, it reads from standard input. The password may be\n"
2113 "up to 127 characters in length. Additional characters and the\n"
2114 "terminating newline character are discarded. While reading\n"
2115 "the password, echoing and the generation of signals by special\n"
2116 "characters is disabled.")
2117 #define FUNC_NAME s_scm_getpass
2118 {
2119 char * p;
2120 SCM passwd;
2121
2122 SCM_VALIDATE_STRING (1, prompt);
2123
2124 WITH_STRING (prompt, c_prompt,
2125 p = getpass(c_prompt));
2126 passwd = scm_from_locale_string (p);
2127
2128 /* Clear out the password in the static buffer. */
2129 memset (p, 0, strlen (p));
2130
2131 return passwd;
2132 }
2133 #undef FUNC_NAME
2134 #endif /* HAVE_GETPASS */
2135
2136 SCM_DEFINE (scm_flock, "flock", 2, 0, 0,
2137 (SCM file, SCM operation),
2138 "Apply or remove an advisory lock on an open file.\n"
2139 "@var{operation} specifies the action to be done:\n"
2140 "\n"
2141 "@defvar LOCK_SH\n"
2142 "Shared lock. More than one process may hold a shared lock\n"
2143 "for a given file at a given time.\n"
2144 "@end defvar\n"
2145 "@defvar LOCK_EX\n"
2146 "Exclusive lock. Only one process may hold an exclusive lock\n"
2147 "for a given file at a given time.\n"
2148 "@end defvar\n"
2149 "@defvar LOCK_UN\n"
2150 "Unlock the file.\n"
2151 "@end defvar\n"
2152 "@defvar LOCK_NB\n"
2153 "Don't block when locking. This is combined with one of the\n"
2154 "other operations using @code{logior}. If @code{flock} would\n"
2155 "block an @code{EWOULDBLOCK} error is thrown.\n"
2156 "@end defvar\n"
2157 "\n"
2158 "The return value is not specified. @var{file} may be an open\n"
2159 "file descriptor or an open file descriptor port.\n"
2160 "\n"
2161 "Note that @code{flock} does not lock files across NFS.")
2162 #define FUNC_NAME s_scm_flock
2163 {
2164 int fdes;
2165
2166 if (scm_is_integer (file))
2167 fdes = scm_to_int (file);
2168 else
2169 {
2170 SCM_VALIDATE_OPFPORT (2, file);
2171
2172 fdes = SCM_FPORT_FDES (file);
2173 }
2174 if (flock (fdes, scm_to_int (operation)) == -1)
2175 SCM_SYSERROR;
2176 return SCM_UNSPECIFIED;
2177 }
2178 #undef FUNC_NAME
2179
2180 #if HAVE_SETHOSTNAME
2181 SCM_DEFINE (scm_sethostname, "sethostname", 1, 0, 0,
2182 (SCM name),
2183 "Set the host name of the current processor to @var{name}. May\n"
2184 "only be used by the superuser. The return value is not\n"
2185 "specified.")
2186 #define FUNC_NAME s_scm_sethostname
2187 {
2188 int rv;
2189
2190 WITH_STRING (name, c_name,
2191 rv = sethostname (c_name, strlen(c_name)));
2192 if (rv == -1)
2193 SCM_SYSERROR;
2194 return SCM_UNSPECIFIED;
2195 }
2196 #undef FUNC_NAME
2197 #endif /* HAVE_SETHOSTNAME */
2198
2199
2200 #if HAVE_GETHOSTNAME
2201 SCM_DEFINE (scm_gethostname, "gethostname", 0, 0, 0,
2202 (void),
2203 "Return the host name of the current processor.")
2204 #define FUNC_NAME s_scm_gethostname
2205 {
2206 #ifdef MAXHOSTNAMELEN
2207
2208 /* Various systems define MAXHOSTNAMELEN (including Solaris in fact).
2209 * On GNU/Linux this doesn't include the terminating '\0', hence "+ 1". */
2210 const int len = MAXHOSTNAMELEN + 1;
2211 char *const p = scm_malloc (len);
2212 const int res = gethostname (p, len);
2213
2214 scm_dynwind_begin (0);
2215 scm_dynwind_unwind_handler (free, p, 0);
2216
2217 #else
2218
2219 /* Default 256 is for Solaris, under Linux ENAMETOOLONG is returned if not
2220 * large enough. SUSv2 specifies 255 maximum too, apparently. */
2221 int len = 256;
2222 int res;
2223 char *p;
2224
2225 # if HAVE_SYSCONF && defined (_SC_HOST_NAME_MAX)
2226
2227 /* POSIX specifies the HOST_NAME_MAX system parameter for the max size,
2228 * which may reflect a particular kernel configuration.
2229 * Must watch out for this existing but giving -1, as happens for instance
2230 * in gnu/linux glibc 2.3.2. */
2231 {
2232 const long int n = sysconf (_SC_HOST_NAME_MAX);
2233 if (n != -1L)
2234 len = n;
2235 }
2236
2237 # endif
2238
2239 p = scm_malloc (len);
2240
2241 scm_dynwind_begin (0);
2242 scm_dynwind_unwind_handler (free, p, 0);
2243
2244 res = gethostname (p, len);
2245 while (res == -1 && errno == ENAMETOOLONG)
2246 {
2247 len *= 2;
2248
2249 /* scm_realloc may throw an exception. */
2250 p = scm_realloc (p, len);
2251 res = gethostname (p, len);
2252 }
2253
2254 #endif
2255
2256 if (res == -1)
2257 {
2258 const int save_errno = errno;
2259
2260 /* No guile exceptions can occur before we have freed p's memory. */
2261 scm_dynwind_end ();
2262 free (p);
2263
2264 errno = save_errno;
2265 SCM_SYSERROR;
2266 }
2267 else
2268 {
2269 /* scm_from_locale_string may throw an exception. */
2270 const SCM name = scm_from_locale_string (p);
2271
2272 /* No guile exceptions can occur before we have freed p's memory. */
2273 scm_dynwind_end ();
2274 free (p);
2275
2276 return name;
2277 }
2278 }
2279 #undef FUNC_NAME
2280 #endif /* HAVE_GETHOSTNAME */
2281
2282 \f
2283 #ifdef HAVE_FORK
2284 static void
2285 scm_init_popen (void)
2286 {
2287 scm_c_define_gsubr ("open-process", 2, 0, 1, scm_open_process);
2288 }
2289 #endif
2290
2291 void
2292 scm_init_posix ()
2293 {
2294 scm_add_feature ("posix");
2295 #ifdef HAVE_GETEUID
2296 scm_add_feature ("EIDs");
2297 #endif
2298 #ifdef WAIT_ANY
2299 scm_c_define ("WAIT_ANY", scm_from_int (WAIT_ANY));
2300 #endif
2301 #ifdef WAIT_MYPGRP
2302 scm_c_define ("WAIT_MYPGRP", scm_from_int (WAIT_MYPGRP));
2303 #endif
2304 #ifdef WNOHANG
2305 scm_c_define ("WNOHANG", scm_from_int (WNOHANG));
2306 #endif
2307 #ifdef WUNTRACED
2308 scm_c_define ("WUNTRACED", scm_from_int (WUNTRACED));
2309 #endif
2310
2311 #ifdef LC_COLLATE
2312 scm_c_define ("LC_COLLATE", scm_from_int (LC_COLLATE));
2313 #endif
2314 #ifdef LC_CTYPE
2315 scm_c_define ("LC_CTYPE", scm_from_int (LC_CTYPE));
2316 #endif
2317 #ifdef LC_MONETARY
2318 scm_c_define ("LC_MONETARY", scm_from_int (LC_MONETARY));
2319 #endif
2320 #ifdef LC_NUMERIC
2321 scm_c_define ("LC_NUMERIC", scm_from_int (LC_NUMERIC));
2322 #endif
2323 #ifdef LC_TIME
2324 scm_c_define ("LC_TIME", scm_from_int (LC_TIME));
2325 #endif
2326 #ifdef LC_MESSAGES
2327 scm_c_define ("LC_MESSAGES", scm_from_int (LC_MESSAGES));
2328 #endif
2329 #ifdef LC_ALL
2330 scm_c_define ("LC_ALL", scm_from_int (LC_ALL));
2331 #endif
2332 #ifdef LC_PAPER
2333 scm_c_define ("LC_PAPER", scm_from_int (LC_PAPER));
2334 #endif
2335 #ifdef LC_NAME
2336 scm_c_define ("LC_NAME", scm_from_int (LC_NAME));
2337 #endif
2338 #ifdef LC_ADDRESS
2339 scm_c_define ("LC_ADDRESS", scm_from_int (LC_ADDRESS));
2340 #endif
2341 #ifdef LC_TELEPHONE
2342 scm_c_define ("LC_TELEPHONE", scm_from_int (LC_TELEPHONE));
2343 #endif
2344 #ifdef LC_MEASUREMENT
2345 scm_c_define ("LC_MEASUREMENT", scm_from_int (LC_MEASUREMENT));
2346 #endif
2347 #ifdef LC_IDENTIFICATION
2348 scm_c_define ("LC_IDENTIFICATION", scm_from_int (LC_IDENTIFICATION));
2349 #endif
2350 #ifdef PIPE_BUF
2351 scm_c_define ("PIPE_BUF", scm_from_long (PIPE_BUF));
2352 #endif
2353
2354 #ifdef PRIO_PROCESS
2355 scm_c_define ("PRIO_PROCESS", scm_from_int (PRIO_PROCESS));
2356 #endif
2357 #ifdef PRIO_PGRP
2358 scm_c_define ("PRIO_PGRP", scm_from_int (PRIO_PGRP));
2359 #endif
2360 #ifdef PRIO_USER
2361 scm_c_define ("PRIO_USER", scm_from_int (PRIO_USER));
2362 #endif
2363
2364 #ifdef LOCK_SH
2365 scm_c_define ("LOCK_SH", scm_from_int (LOCK_SH));
2366 #endif
2367 #ifdef LOCK_EX
2368 scm_c_define ("LOCK_EX", scm_from_int (LOCK_EX));
2369 #endif
2370 #ifdef LOCK_UN
2371 scm_c_define ("LOCK_UN", scm_from_int (LOCK_UN));
2372 #endif
2373 #ifdef LOCK_NB
2374 scm_c_define ("LOCK_NB", scm_from_int (LOCK_NB));
2375 #endif
2376
2377 #include "libguile/cpp-SIG.c"
2378 #include "libguile/posix.x"
2379
2380 #ifdef HAVE_FORK
2381 scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
2382 "scm_init_popen",
2383 (scm_t_extension_init_func) scm_init_popen,
2384 NULL);
2385 #endif /* HAVE_FORK */
2386 }
2387
2388 /*
2389 Local Variables:
2390 c-file-style: "gnu"
2391 End:
2392 */