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