Merge branch 'master' into boehm-demers-weiser-gc
[bpt/guile.git] / libguile / posix.c
1 /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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
29 #include "libguile/_scm.h"
30 #include "libguile/dynwind.h"
31 #include "libguile/fports.h"
32 #include "libguile/scmsigs.h"
33 #include "libguile/feature.h"
34 #include "libguile/strings.h"
35 #include "libguile/srfi-13.h"
36 #include "libguile/srfi-14.h"
37 #include "libguile/vectors.h"
38 #include "libguile/values.h"
39 #include "libguile/lang.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
986 /* ttyname returns its result in a single static buffer, hence
987 scm_i_misc_mutex for thread safety. In glibc 2.3.2 two threads
988 continuously calling ttyname will otherwise get an overwrite quite
989 easily.
990
991 ttyname_r (when available) could be used instead of scm_i_misc_mutex, but
992 there's probably little to be gained in either speed or parallelism. */
993
994 #ifdef HAVE_TTYNAME
995 SCM_DEFINE (scm_ttyname, "ttyname", 1, 0, 0,
996 (SCM port),
997 "Return a string with the name of the serial terminal device\n"
998 "underlying @var{port}.")
999 #define FUNC_NAME s_scm_ttyname
1000 {
1001 char *result;
1002 int fd, err;
1003 SCM ret = SCM_BOOL_F;
1004
1005 port = SCM_COERCE_OUTPORT (port);
1006 SCM_VALIDATE_OPPORT (1, port);
1007 if (!SCM_FPORTP (port))
1008 return SCM_BOOL_F;
1009 fd = SCM_FPORT_FDES (port);
1010
1011 scm_i_scm_pthread_mutex_lock (&scm_i_misc_mutex);
1012
1013 SCM_SYSCALL (result = ttyname (fd));
1014 err = errno;
1015 if (result != NULL)
1016 result = strdup (result);
1017
1018 scm_i_pthread_mutex_unlock (&scm_i_misc_mutex);
1019
1020 if (!result)
1021 {
1022 errno = err;
1023 SCM_SYSERROR;
1024 }
1025 else
1026 ret = scm_take_locale_string (result);
1027
1028 return ret;
1029 }
1030 #undef FUNC_NAME
1031 #endif /* HAVE_TTYNAME */
1032
1033
1034 /* For thread safety "buf" is used instead of NULL for the ctermid static
1035 buffer. Actually it's unlikely the controlling terminal will change
1036 during program execution, and indeed on glibc (2.3.2) it's always just
1037 "/dev/tty", but L_ctermid on the stack is easy and fast and guarantees
1038 safety everywhere. */
1039 #ifdef HAVE_CTERMID
1040 SCM_DEFINE (scm_ctermid, "ctermid", 0, 0, 0,
1041 (),
1042 "Return a string containing the file name of the controlling\n"
1043 "terminal for the current process.")
1044 #define FUNC_NAME s_scm_ctermid
1045 {
1046 char buf[L_ctermid];
1047 char *result = ctermid (buf);
1048 if (*result == '\0')
1049 SCM_SYSERROR;
1050 return scm_from_locale_string (result);
1051 }
1052 #undef FUNC_NAME
1053 #endif /* HAVE_CTERMID */
1054
1055 #ifdef HAVE_TCGETPGRP
1056 SCM_DEFINE (scm_tcgetpgrp, "tcgetpgrp", 1, 0, 0,
1057 (SCM port),
1058 "Return the process group ID of the foreground process group\n"
1059 "associated with the terminal open on the file descriptor\n"
1060 "underlying @var{port}.\n"
1061 "\n"
1062 "If there is no foreground process group, the return value is a\n"
1063 "number greater than 1 that does not match the process group ID\n"
1064 "of any existing process group. This can happen if all of the\n"
1065 "processes in the job that was formerly the foreground job have\n"
1066 "terminated, and no other job has yet been moved into the\n"
1067 "foreground.")
1068 #define FUNC_NAME s_scm_tcgetpgrp
1069 {
1070 int fd;
1071 pid_t pgid;
1072
1073 port = SCM_COERCE_OUTPORT (port);
1074
1075 SCM_VALIDATE_OPFPORT (1, port);
1076 fd = SCM_FPORT_FDES (port);
1077 if ((pgid = tcgetpgrp (fd)) == -1)
1078 SCM_SYSERROR;
1079 return scm_from_int (pgid);
1080 }
1081 #undef FUNC_NAME
1082 #endif /* HAVE_TCGETPGRP */
1083
1084 #ifdef HAVE_TCSETPGRP
1085 SCM_DEFINE (scm_tcsetpgrp, "tcsetpgrp", 2, 0, 0,
1086 (SCM port, SCM pgid),
1087 "Set the foreground process group ID for the terminal used by the file\n"
1088 "descriptor underlying @var{port} to the integer @var{pgid}.\n"
1089 "The calling process\n"
1090 "must be a member of the same session as @var{pgid} and must have the same\n"
1091 "controlling terminal. The return value is unspecified.")
1092 #define FUNC_NAME s_scm_tcsetpgrp
1093 {
1094 int fd;
1095
1096 port = SCM_COERCE_OUTPORT (port);
1097
1098 SCM_VALIDATE_OPFPORT (1, port);
1099 fd = SCM_FPORT_FDES (port);
1100 if (tcsetpgrp (fd, scm_to_int (pgid)) == -1)
1101 SCM_SYSERROR;
1102 return SCM_UNSPECIFIED;
1103 }
1104 #undef FUNC_NAME
1105 #endif /* HAVE_TCSETPGRP */
1106
1107 SCM_DEFINE (scm_execl, "execl", 1, 0, 1,
1108 (SCM filename, SCM args),
1109 "Executes the file named by @var{path} as a new process image.\n"
1110 "The remaining arguments are supplied to the process; from a C program\n"
1111 "they are accessible as the @code{argv} argument to @code{main}.\n"
1112 "Conventionally the first @var{arg} is the same as @var{path}.\n"
1113 "All arguments must be strings.\n\n"
1114 "If @var{arg} is missing, @var{path} is executed with a null\n"
1115 "argument list, which may have system-dependent side-effects.\n\n"
1116 "This procedure is currently implemented using the @code{execv} system\n"
1117 "call, but we call it @code{execl} because of its Scheme calling interface.")
1118 #define FUNC_NAME s_scm_execl
1119 {
1120 char *exec_file;
1121 char **exec_argv;
1122
1123 scm_dynwind_begin (0);
1124
1125 exec_file = scm_to_locale_string (filename);
1126 scm_dynwind_free (exec_file);
1127
1128 exec_argv = scm_i_allocate_string_pointers (args);
1129
1130 execv (exec_file,
1131 #ifdef __MINGW32__
1132 /* extra "const" in mingw formals, provokes warning from gcc */
1133 (const char * const *)
1134 #endif
1135 exec_argv);
1136 SCM_SYSERROR;
1137
1138 /* not reached. */
1139 scm_dynwind_end ();
1140 return SCM_BOOL_F;
1141 }
1142 #undef FUNC_NAME
1143
1144 SCM_DEFINE (scm_execlp, "execlp", 1, 0, 1,
1145 (SCM filename, SCM args),
1146 "Similar to @code{execl}, however if\n"
1147 "@var{filename} does not contain a slash\n"
1148 "then the file to execute will be located by searching the\n"
1149 "directories listed in the @code{PATH} environment variable.\n\n"
1150 "This procedure is currently implemented using the @code{execvp} system\n"
1151 "call, but we call it @code{execlp} because of its Scheme calling interface.")
1152 #define FUNC_NAME s_scm_execlp
1153 {
1154 char *exec_file;
1155 char **exec_argv;
1156
1157 scm_dynwind_begin (0);
1158
1159 exec_file = scm_to_locale_string (filename);
1160 scm_dynwind_free (exec_file);
1161
1162 exec_argv = scm_i_allocate_string_pointers (args);
1163
1164 execvp (exec_file,
1165 #ifdef __MINGW32__
1166 /* extra "const" in mingw formals, provokes warning from gcc */
1167 (const char * const *)
1168 #endif
1169 exec_argv);
1170 SCM_SYSERROR;
1171
1172 /* not reached. */
1173 scm_dynwind_end ();
1174 return SCM_BOOL_F;
1175 }
1176 #undef FUNC_NAME
1177
1178
1179 /* OPTIMIZE-ME: scm_execle doesn't need malloced copies of the environment
1180 list strings the way environ_list_to_c gives. */
1181
1182 SCM_DEFINE (scm_execle, "execle", 2, 0, 1,
1183 (SCM filename, SCM env, SCM args),
1184 "Similar to @code{execl}, but the environment of the new process is\n"
1185 "specified by @var{env}, which must be a list of strings as returned by the\n"
1186 "@code{environ} procedure.\n\n"
1187 "This procedure is currently implemented using the @code{execve} system\n"
1188 "call, but we call it @code{execle} because of its Scheme calling interface.")
1189 #define FUNC_NAME s_scm_execle
1190 {
1191 char **exec_argv;
1192 char **exec_env;
1193 char *exec_file;
1194
1195 scm_dynwind_begin (0);
1196
1197 exec_file = scm_to_locale_string (filename);
1198 scm_dynwind_free (exec_file);
1199
1200 exec_argv = scm_i_allocate_string_pointers (args);
1201 exec_env = scm_i_allocate_string_pointers (env);
1202
1203 execve (exec_file,
1204 #ifdef __MINGW32__
1205 /* extra "const" in mingw formals, provokes warning from gcc */
1206 (const char * const *)
1207 #endif
1208 exec_argv,
1209 #ifdef __MINGW32__
1210 /* extra "const" in mingw formals, provokes warning from gcc */
1211 (const char * const *)
1212 #endif
1213 exec_env);
1214 SCM_SYSERROR;
1215
1216 /* not reached. */
1217 scm_dynwind_end ();
1218 return SCM_BOOL_F;
1219 }
1220 #undef FUNC_NAME
1221
1222 #ifdef HAVE_FORK
1223 SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
1224 (),
1225 "Creates a new \"child\" process by duplicating the current \"parent\" process.\n"
1226 "In the child the return value is 0. In the parent the return value is\n"
1227 "the integer process ID of the child.\n\n"
1228 "This procedure has been renamed from @code{fork} to avoid a naming conflict\n"
1229 "with the scsh fork.")
1230 #define FUNC_NAME s_scm_fork
1231 {
1232 int pid;
1233 pid = fork ();
1234 if (pid == -1)
1235 SCM_SYSERROR;
1236 return scm_from_int (pid);
1237 }
1238 #undef FUNC_NAME
1239 #endif /* HAVE_FORK */
1240
1241 #ifdef __MINGW32__
1242 # include "win32-uname.h"
1243 #endif
1244
1245 #if defined (HAVE_UNAME) || defined (__MINGW32__)
1246 SCM_DEFINE (scm_uname, "uname", 0, 0, 0,
1247 (),
1248 "Return an object with some information about the computer\n"
1249 "system the program is running on.")
1250 #define FUNC_NAME s_scm_uname
1251 {
1252 struct utsname buf;
1253 SCM result = scm_c_make_vector (5, SCM_UNSPECIFIED);
1254 if (uname (&buf) < 0)
1255 SCM_SYSERROR;
1256 SCM_SIMPLE_VECTOR_SET(result, 0, scm_from_locale_string (buf.sysname));
1257 SCM_SIMPLE_VECTOR_SET(result, 1, scm_from_locale_string (buf.nodename));
1258 SCM_SIMPLE_VECTOR_SET(result, 2, scm_from_locale_string (buf.release));
1259 SCM_SIMPLE_VECTOR_SET(result, 3, scm_from_locale_string (buf.version));
1260 SCM_SIMPLE_VECTOR_SET(result, 4, scm_from_locale_string (buf.machine));
1261 /*
1262 a linux special?
1263 SCM_SIMPLE_VECTOR_SET(result, 5, scm_from_locale_string (buf.domainname));
1264 */
1265 return result;
1266 }
1267 #undef FUNC_NAME
1268 #endif /* HAVE_UNAME */
1269
1270 SCM_DEFINE (scm_environ, "environ", 0, 1, 0,
1271 (SCM env),
1272 "If @var{env} is omitted, return the current environment (in the\n"
1273 "Unix sense) as a list of strings. Otherwise set the current\n"
1274 "environment, which is also the default environment for child\n"
1275 "processes, to the supplied list of strings. Each member of\n"
1276 "@var{env} should be of the form @code{NAME=VALUE} and values of\n"
1277 "@code{NAME} should not be duplicated. If @var{env} is supplied\n"
1278 "then the return value is unspecified.")
1279 #define FUNC_NAME s_scm_environ
1280 {
1281 if (SCM_UNBNDP (env))
1282 return scm_makfromstrs (-1, environ);
1283 else
1284 {
1285 environ = scm_i_allocate_string_pointers (env);
1286 return SCM_UNSPECIFIED;
1287 }
1288 }
1289 #undef FUNC_NAME
1290
1291 #ifdef L_tmpnam
1292
1293 SCM_DEFINE (scm_tmpnam, "tmpnam", 0, 0, 0,
1294 (),
1295 "Return a name in the file system that does not match any\n"
1296 "existing file. However there is no guarantee that another\n"
1297 "process will not create the file after @code{tmpnam} is called.\n"
1298 "Care should be taken if opening the file, e.g., use the\n"
1299 "@code{O_EXCL} open flag or use @code{mkstemp!} instead.")
1300 #define FUNC_NAME s_scm_tmpnam
1301 {
1302 char name[L_tmpnam];
1303 char *rv;
1304
1305 SCM_SYSCALL (rv = tmpnam (name));
1306 if (rv == NULL)
1307 /* not SCM_SYSERROR since errno probably not set. */
1308 SCM_MISC_ERROR ("tmpnam failed", SCM_EOL);
1309 return scm_from_locale_string (name);
1310 }
1311 #undef FUNC_NAME
1312
1313 #endif
1314
1315 #ifndef HAVE_MKSTEMP
1316 extern int mkstemp (char *);
1317 #endif
1318
1319 SCM_DEFINE (scm_mkstemp, "mkstemp!", 1, 0, 0,
1320 (SCM tmpl),
1321 "Create a new unique file in the file system and return a new\n"
1322 "buffered port open for reading and writing to the file.\n"
1323 "\n"
1324 "@var{tmpl} is a string specifying where the file should be\n"
1325 "created: it must end with @samp{XXXXXX} and those @samp{X}s\n"
1326 "will be changed in the string to return the name of the file.\n"
1327 "(@code{port-filename} on the port also gives the name.)\n"
1328 "\n"
1329 "POSIX doesn't specify the permissions mode of the file, on GNU\n"
1330 "and most systems it's @code{#o600}. An application can use\n"
1331 "@code{chmod} to relax that if desired. For example\n"
1332 "@code{#o666} less @code{umask}, which is usual for ordinary\n"
1333 "file creation,\n"
1334 "\n"
1335 "@example\n"
1336 "(let ((port (mkstemp! (string-copy \"/tmp/myfile-XXXXXX\"))))\n"
1337 " (chmod port (logand #o666 (lognot (umask))))\n"
1338 " ...)\n"
1339 "@end example")
1340 #define FUNC_NAME s_scm_mkstemp
1341 {
1342 char *c_tmpl;
1343 int rv;
1344
1345 scm_dynwind_begin (0);
1346
1347 c_tmpl = scm_to_locale_string (tmpl);
1348 scm_dynwind_free (c_tmpl);
1349
1350 SCM_SYSCALL (rv = mkstemp (c_tmpl));
1351 if (rv == -1)
1352 SCM_SYSERROR;
1353
1354 scm_substring_move_x (scm_from_locale_string (c_tmpl),
1355 SCM_INUM0, scm_string_length (tmpl),
1356 tmpl, SCM_INUM0);
1357
1358 scm_dynwind_end ();
1359 return scm_fdes_to_port (rv, "w+", tmpl);
1360 }
1361 #undef FUNC_NAME
1362
1363 SCM_DEFINE (scm_utime, "utime", 1, 2, 0,
1364 (SCM pathname, SCM actime, SCM modtime),
1365 "@code{utime} sets the access and modification times for the\n"
1366 "file named by @var{path}. If @var{actime} or @var{modtime} is\n"
1367 "not supplied, then the current time is used. @var{actime} and\n"
1368 "@var{modtime} must be integer time values as returned by the\n"
1369 "@code{current-time} procedure.\n"
1370 "@lisp\n"
1371 "(utime \"foo\" (- (current-time) 3600))\n"
1372 "@end lisp\n"
1373 "will set the access time to one hour in the past and the\n"
1374 "modification time to the current time.")
1375 #define FUNC_NAME s_scm_utime
1376 {
1377 int rv;
1378 struct utimbuf utm_tmp;
1379
1380 if (SCM_UNBNDP (actime))
1381 SCM_SYSCALL (time (&utm_tmp.actime));
1382 else
1383 utm_tmp.actime = SCM_NUM2ULONG (2, actime);
1384
1385 if (SCM_UNBNDP (modtime))
1386 SCM_SYSCALL (time (&utm_tmp.modtime));
1387 else
1388 utm_tmp.modtime = SCM_NUM2ULONG (3, modtime);
1389
1390 STRING_SYSCALL (pathname, c_pathname,
1391 rv = utime (c_pathname, &utm_tmp));
1392 if (rv != 0)
1393 SCM_SYSERROR;
1394 return SCM_UNSPECIFIED;
1395 }
1396 #undef FUNC_NAME
1397
1398 SCM_DEFINE (scm_access, "access?", 2, 0, 0,
1399 (SCM path, SCM how),
1400 "Test accessibility of a file under the real UID and GID of the\n"
1401 "calling process. The return is @code{#t} if @var{path} exists\n"
1402 "and the permissions requested by @var{how} are all allowed, or\n"
1403 "@code{#f} if not.\n"
1404 "\n"
1405 "@var{how} is an integer which is one of the following values,\n"
1406 "or a bitwise-OR (@code{logior}) of multiple values.\n"
1407 "\n"
1408 "@defvar R_OK\n"
1409 "Test for read permission.\n"
1410 "@end defvar\n"
1411 "@defvar W_OK\n"
1412 "Test for write permission.\n"
1413 "@end defvar\n"
1414 "@defvar X_OK\n"
1415 "Test for execute permission.\n"
1416 "@end defvar\n"
1417 "@defvar F_OK\n"
1418 "Test for existence of the file. This is implied by each of the\n"
1419 "other tests, so there's no need to combine it with them.\n"
1420 "@end defvar\n"
1421 "\n"
1422 "It's important to note that @code{access?} does not simply\n"
1423 "indicate what will happen on attempting to read or write a\n"
1424 "file. In normal circumstances it does, but in a set-UID or\n"
1425 "set-GID program it doesn't because @code{access?} tests the\n"
1426 "real ID, whereas an open or execute attempt uses the effective\n"
1427 "ID.\n"
1428 "\n"
1429 "A program which will never run set-UID/GID can ignore the\n"
1430 "difference between real and effective IDs, but for maximum\n"
1431 "generality, especially in library functions, it's best not to\n"
1432 "use @code{access?} to predict the result of an open or execute,\n"
1433 "instead simply attempt that and catch any exception.\n"
1434 "\n"
1435 "The main use for @code{access?} is to let a set-UID/GID program\n"
1436 "determine what the invoking user would have been allowed to do,\n"
1437 "without the greater (or perhaps lesser) privileges afforded by\n"
1438 "the effective ID. For more on this, see ``Testing File\n"
1439 "Access'' in The GNU C Library Reference Manual.")
1440 #define FUNC_NAME s_scm_access
1441 {
1442 int rv;
1443
1444 WITH_STRING (path, c_path,
1445 rv = access (c_path, scm_to_int (how)));
1446 return scm_from_bool (!rv);
1447 }
1448 #undef FUNC_NAME
1449
1450 SCM_DEFINE (scm_getpid, "getpid", 0, 0, 0,
1451 (),
1452 "Return an integer representing the current process ID.")
1453 #define FUNC_NAME s_scm_getpid
1454 {
1455 return scm_from_ulong (getpid ());
1456 }
1457 #undef FUNC_NAME
1458
1459 SCM_DEFINE (scm_putenv, "putenv", 1, 0, 0,
1460 (SCM str),
1461 "Modifies the environment of the current process, which is\n"
1462 "also the default environment inherited by child processes.\n\n"
1463 "If @var{string} is of the form @code{NAME=VALUE} then it will be written\n"
1464 "directly into the environment, replacing any existing environment string\n"
1465 "with\n"
1466 "name matching @code{NAME}. If @var{string} does not contain an equal\n"
1467 "sign, then any existing string with name matching @var{string} will\n"
1468 "be removed.\n\n"
1469 "The return value is unspecified.")
1470 #define FUNC_NAME s_scm_putenv
1471 {
1472 int rv;
1473 char *c_str = scm_to_locale_string (str);
1474
1475 /* Leave C_STR in the environment. */
1476
1477 /* Gnulib's `putenv' module honors the semantics described above. */
1478 rv = putenv (c_str);
1479 if (rv < 0)
1480 SCM_SYSERROR;
1481
1482 return SCM_UNSPECIFIED;
1483 }
1484 #undef FUNC_NAME
1485
1486 /* This mutex is used to serialize invocations of `setlocale ()' on non-GNU
1487 systems (i.e., systems where a reentrant locale API is not available). It
1488 is also acquired before calls to `nl_langinfo ()'. See `i18n.c' for
1489 details. */
1490 scm_i_pthread_mutex_t scm_i_locale_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER;
1491
1492 #ifdef HAVE_SETLOCALE
1493
1494 SCM_DEFINE (scm_setlocale, "setlocale", 1, 1, 0,
1495 (SCM category, SCM locale),
1496 "If @var{locale} is omitted, return the current value of the\n"
1497 "specified locale category as a system-dependent string.\n"
1498 "@var{category} should be specified using the values\n"
1499 "@code{LC_COLLATE}, @code{LC_ALL} etc.\n"
1500 "\n"
1501 "Otherwise the specified locale category is set to the string\n"
1502 "@var{locale} and the new value is returned as a\n"
1503 "system-dependent string. If @var{locale} is an empty string,\n"
1504 "the locale will be set using environment variables.")
1505 #define FUNC_NAME s_scm_setlocale
1506 {
1507 int c_category;
1508 char *clocale;
1509 char *rv;
1510
1511 scm_dynwind_begin (0);
1512
1513 if (SCM_UNBNDP (locale))
1514 {
1515 clocale = NULL;
1516 }
1517 else
1518 {
1519 clocale = scm_to_locale_string (locale);
1520 scm_dynwind_free (clocale);
1521 }
1522
1523 c_category = scm_i_to_lc_category (category, 1);
1524
1525 scm_i_pthread_mutex_lock (&scm_i_locale_mutex);
1526 rv = setlocale (c_category, clocale);
1527 scm_i_pthread_mutex_unlock (&scm_i_locale_mutex);
1528
1529 if (rv == NULL)
1530 {
1531 /* POSIX and C99 don't say anything about setlocale setting errno, so
1532 force a sensible value here. glibc leaves ENOENT, which would be
1533 fine, but it's not a documented feature. */
1534 errno = EINVAL;
1535 SCM_SYSERROR;
1536 }
1537
1538 /* Recompute the standard SRFI-14 character sets in a locale-dependent
1539 (actually charset-dependent) way. */
1540 scm_srfi_14_compute_char_sets ();
1541
1542 scm_dynwind_end ();
1543 return scm_from_locale_string (rv);
1544 }
1545 #undef FUNC_NAME
1546 #endif /* HAVE_SETLOCALE */
1547
1548 #ifdef HAVE_MKNOD
1549 SCM_DEFINE (scm_mknod, "mknod", 4, 0, 0,
1550 (SCM path, SCM type, SCM perms, SCM dev),
1551 "Creates a new special file, such as a file corresponding to a device.\n"
1552 "@var{path} specifies the name of the file. @var{type} should\n"
1553 "be one of the following symbols:\n"
1554 "regular, directory, symlink, block-special, char-special,\n"
1555 "fifo, or socket. @var{perms} (an integer) specifies the file permissions.\n"
1556 "@var{dev} (an integer) specifies which device the special file refers\n"
1557 "to. Its exact interpretation depends on the kind of special file\n"
1558 "being created.\n\n"
1559 "E.g.,\n"
1560 "@lisp\n"
1561 "(mknod \"/dev/fd0\" 'block-special #o660 (+ (* 2 256) 2))\n"
1562 "@end lisp\n\n"
1563 "The return value is unspecified.")
1564 #define FUNC_NAME s_scm_mknod
1565 {
1566 int val;
1567 const char *p;
1568 int ctype = 0;
1569
1570 SCM_VALIDATE_STRING (1, path);
1571 SCM_VALIDATE_SYMBOL (2, type);
1572
1573 p = scm_i_symbol_chars (type);
1574 if (strcmp (p, "regular") == 0)
1575 ctype = S_IFREG;
1576 else if (strcmp (p, "directory") == 0)
1577 ctype = S_IFDIR;
1578 #ifdef S_IFLNK
1579 /* systems without symlinks probably don't have S_IFLNK defined */
1580 else if (strcmp (p, "symlink") == 0)
1581 ctype = S_IFLNK;
1582 #endif
1583 else if (strcmp (p, "block-special") == 0)
1584 ctype = S_IFBLK;
1585 else if (strcmp (p, "char-special") == 0)
1586 ctype = S_IFCHR;
1587 else if (strcmp (p, "fifo") == 0)
1588 ctype = S_IFIFO;
1589 #ifdef S_IFSOCK
1590 else if (strcmp (p, "socket") == 0)
1591 ctype = S_IFSOCK;
1592 #endif
1593 else
1594 SCM_OUT_OF_RANGE (2, type);
1595
1596 STRING_SYSCALL (path, c_path,
1597 val = mknod (c_path,
1598 ctype | scm_to_int (perms),
1599 scm_to_int (dev)));
1600 if (val != 0)
1601 SCM_SYSERROR;
1602 return SCM_UNSPECIFIED;
1603 }
1604 #undef FUNC_NAME
1605 #endif /* HAVE_MKNOD */
1606
1607 #ifdef HAVE_NICE
1608 SCM_DEFINE (scm_nice, "nice", 1, 0, 0,
1609 (SCM incr),
1610 "Increment the priority of the current process by @var{incr}. A higher\n"
1611 "priority value means that the process runs less often.\n"
1612 "The return value is unspecified.")
1613 #define FUNC_NAME s_scm_nice
1614 {
1615 int nice_value;
1616
1617 /* nice() returns "prio-NZERO" on success or -1 on error, but -1 can arise
1618 from "prio-NZERO", so an error must be detected from errno changed */
1619 errno = 0;
1620 nice_value = nice (scm_to_int (incr));
1621 if (errno != 0)
1622 SCM_SYSERROR;
1623
1624 return SCM_UNSPECIFIED;
1625 }
1626 #undef FUNC_NAME
1627 #endif /* HAVE_NICE */
1628
1629 #ifdef HAVE_SYNC
1630 SCM_DEFINE (scm_sync, "sync", 0, 0, 0,
1631 (),
1632 "Flush the operating system disk buffers.\n"
1633 "The return value is unspecified.")
1634 #define FUNC_NAME s_scm_sync
1635 {
1636 sync();
1637 return SCM_UNSPECIFIED;
1638 }
1639 #undef FUNC_NAME
1640 #endif /* HAVE_SYNC */
1641
1642
1643 /* crypt() returns a pointer to a static buffer, so we use scm_i_misc_mutex
1644 to avoid another thread overwriting it. A test program running crypt
1645 continuously in two threads can be quickly seen tripping this problem.
1646 crypt() is pretty slow normally, so a mutex shouldn't add much overhead.
1647
1648 glibc has a thread-safe crypt_r, but (in version 2.3.2) it runs a lot
1649 slower (about 5x) than plain crypt if you pass an uninitialized data
1650 block each time. Presumably there's some one-time setups. The best way
1651 to use crypt_r for parallel execution in multiple threads would probably
1652 be to maintain a little pool of initialized crypt_data structures, take
1653 one and use it, then return it to the pool. That pool could be garbage
1654 collected so it didn't add permanently to memory use if only a few crypt
1655 calls are made. But we expect crypt will be used rarely, and even more
1656 rarely will there be any desire for lots of parallel execution on
1657 multiple cpus. So for now we don't bother with anything fancy, just
1658 ensure it works. */
1659
1660 #if HAVE_CRYPT
1661 SCM_DEFINE (scm_crypt, "crypt", 2, 0, 0,
1662 (SCM key, SCM salt),
1663 "Encrypt @var{key} using @var{salt} as the salt value to the\n"
1664 "crypt(3) library call.")
1665 #define FUNC_NAME s_scm_crypt
1666 {
1667 SCM ret;
1668 char *c_key, *c_salt, *c_ret;
1669
1670 scm_dynwind_begin (0);
1671 scm_i_dynwind_pthread_mutex_lock (&scm_i_misc_mutex);
1672
1673 c_key = scm_to_locale_string (key);
1674 scm_dynwind_free (c_key);
1675 c_salt = scm_to_locale_string (salt);
1676 scm_dynwind_free (c_salt);
1677
1678 /* The Linux crypt(3) man page says crypt will return NULL and set errno
1679 on error. (Eg. ENOSYS if legal restrictions mean it cannot be
1680 implemented). */
1681 c_ret = crypt (c_key, c_salt);
1682 if (c_ret == NULL)
1683 SCM_SYSERROR;
1684
1685 ret = scm_from_locale_string (c_ret);
1686 scm_dynwind_end ();
1687 return ret;
1688 }
1689 #undef FUNC_NAME
1690 #endif /* HAVE_CRYPT */
1691
1692 #if HAVE_CHROOT
1693 SCM_DEFINE (scm_chroot, "chroot", 1, 0, 0,
1694 (SCM path),
1695 "Change the root directory to that specified in @var{path}.\n"
1696 "This directory will be used for path names beginning with\n"
1697 "@file{/}. The root directory is inherited by all children\n"
1698 "of the current process. Only the superuser may change the\n"
1699 "root directory.")
1700 #define FUNC_NAME s_scm_chroot
1701 {
1702 int rv;
1703
1704 WITH_STRING (path, c_path,
1705 rv = chroot (c_path));
1706 if (rv == -1)
1707 SCM_SYSERROR;
1708 return SCM_UNSPECIFIED;
1709 }
1710 #undef FUNC_NAME
1711 #endif /* HAVE_CHROOT */
1712
1713
1714 #ifdef __MINGW32__
1715 /* Wrapper function to supplying `getlogin()' under Windows. */
1716 static char * getlogin (void)
1717 {
1718 static char user[256];
1719 static unsigned long len = 256;
1720
1721 if (!GetUserName (user, &len))
1722 return NULL;
1723 return user;
1724 }
1725 #endif /* __MINGW32__ */
1726
1727
1728 #if defined (HAVE_GETLOGIN) || defined (__MINGW32__)
1729 SCM_DEFINE (scm_getlogin, "getlogin", 0, 0, 0,
1730 (void),
1731 "Return a string containing the name of the user logged in on\n"
1732 "the controlling terminal of the process, or @code{#f} if this\n"
1733 "information cannot be obtained.")
1734 #define FUNC_NAME s_scm_getlogin
1735 {
1736 char * p;
1737
1738 p = getlogin ();
1739 if (!p || !*p)
1740 return SCM_BOOL_F;
1741 return scm_from_locale_string (p);
1742 }
1743 #undef FUNC_NAME
1744 #endif /* HAVE_GETLOGIN */
1745
1746 #if HAVE_CUSERID
1747
1748 # if !HAVE_DECL_CUSERID
1749 extern char *cuserid (char *);
1750 # endif
1751
1752 SCM_DEFINE (scm_cuserid, "cuserid", 0, 0, 0,
1753 (void),
1754 "Return a string containing a user name associated with the\n"
1755 "effective user id of the process. Return @code{#f} if this\n"
1756 "information cannot be obtained.")
1757 #define FUNC_NAME s_scm_cuserid
1758 {
1759 char buf[L_cuserid];
1760 char * p;
1761
1762 p = cuserid (buf);
1763 if (!p || !*p)
1764 return SCM_BOOL_F;
1765 return scm_from_locale_string (p);
1766 }
1767 #undef FUNC_NAME
1768 #endif /* HAVE_CUSERID */
1769
1770 #if HAVE_GETPRIORITY
1771 SCM_DEFINE (scm_getpriority, "getpriority", 2, 0, 0,
1772 (SCM which, SCM who),
1773 "Return the scheduling priority of the process, process group\n"
1774 "or user, as indicated by @var{which} and @var{who}. @var{which}\n"
1775 "is one of the variables @code{PRIO_PROCESS}, @code{PRIO_PGRP}\n"
1776 "or @code{PRIO_USER}, and @var{who} is interpreted relative to\n"
1777 "@var{which} (a process identifier for @code{PRIO_PROCESS},\n"
1778 "process group identifier for @code{PRIO_PGRP}, and a user\n"
1779 "identifier for @code{PRIO_USER}. A zero value of @var{who}\n"
1780 "denotes the current process, process group, or user. Return\n"
1781 "the highest priority (lowest numerical value) of any of the\n"
1782 "specified processes.")
1783 #define FUNC_NAME s_scm_getpriority
1784 {
1785 int cwhich, cwho, ret;
1786
1787 cwhich = scm_to_int (which);
1788 cwho = scm_to_int (who);
1789
1790 /* We have to clear errno and examine it later, because -1 is a
1791 legal return value for getpriority(). */
1792 errno = 0;
1793 ret = getpriority (cwhich, cwho);
1794 if (errno != 0)
1795 SCM_SYSERROR;
1796 return scm_from_int (ret);
1797 }
1798 #undef FUNC_NAME
1799 #endif /* HAVE_GETPRIORITY */
1800
1801 #if HAVE_SETPRIORITY
1802 SCM_DEFINE (scm_setpriority, "setpriority", 3, 0, 0,
1803 (SCM which, SCM who, SCM prio),
1804 "Set the scheduling priority of the process, process group\n"
1805 "or user, as indicated by @var{which} and @var{who}. @var{which}\n"
1806 "is one of the variables @code{PRIO_PROCESS}, @code{PRIO_PGRP}\n"
1807 "or @code{PRIO_USER}, and @var{who} is interpreted relative to\n"
1808 "@var{which} (a process identifier for @code{PRIO_PROCESS},\n"
1809 "process group identifier for @code{PRIO_PGRP}, and a user\n"
1810 "identifier for @code{PRIO_USER}. A zero value of @var{who}\n"
1811 "denotes the current process, process group, or user.\n"
1812 "@var{prio} is a value in the range -20 and 20, the default\n"
1813 "priority is 0; lower priorities cause more favorable\n"
1814 "scheduling. Sets the priority of all of the specified\n"
1815 "processes. Only the super-user may lower priorities.\n"
1816 "The return value is not specified.")
1817 #define FUNC_NAME s_scm_setpriority
1818 {
1819 int cwhich, cwho, cprio;
1820
1821 cwhich = scm_to_int (which);
1822 cwho = scm_to_int (who);
1823 cprio = scm_to_int (prio);
1824
1825 if (setpriority (cwhich, cwho, cprio) == -1)
1826 SCM_SYSERROR;
1827 return SCM_UNSPECIFIED;
1828 }
1829 #undef FUNC_NAME
1830 #endif /* HAVE_SETPRIORITY */
1831
1832 #if HAVE_GETPASS
1833 SCM_DEFINE (scm_getpass, "getpass", 1, 0, 0,
1834 (SCM prompt),
1835 "Display @var{prompt} to the standard error output and read\n"
1836 "a password from @file{/dev/tty}. If this file is not\n"
1837 "accessible, it reads from standard input. The password may be\n"
1838 "up to 127 characters in length. Additional characters and the\n"
1839 "terminating newline character are discarded. While reading\n"
1840 "the password, echoing and the generation of signals by special\n"
1841 "characters is disabled.")
1842 #define FUNC_NAME s_scm_getpass
1843 {
1844 char * p;
1845 SCM passwd;
1846
1847 SCM_VALIDATE_STRING (1, prompt);
1848
1849 WITH_STRING (prompt, c_prompt,
1850 p = getpass(c_prompt));
1851 passwd = scm_from_locale_string (p);
1852
1853 /* Clear out the password in the static buffer. */
1854 memset (p, 0, strlen (p));
1855
1856 return passwd;
1857 }
1858 #undef FUNC_NAME
1859 #endif /* HAVE_GETPASS */
1860
1861 SCM_DEFINE (scm_flock, "flock", 2, 0, 0,
1862 (SCM file, SCM operation),
1863 "Apply or remove an advisory lock on an open file.\n"
1864 "@var{operation} specifies the action to be done:\n"
1865 "\n"
1866 "@defvar LOCK_SH\n"
1867 "Shared lock. More than one process may hold a shared lock\n"
1868 "for a given file at a given time.\n"
1869 "@end defvar\n"
1870 "@defvar LOCK_EX\n"
1871 "Exclusive lock. Only one process may hold an exclusive lock\n"
1872 "for a given file at a given time.\n"
1873 "@end defvar\n"
1874 "@defvar LOCK_UN\n"
1875 "Unlock the file.\n"
1876 "@end defvar\n"
1877 "@defvar LOCK_NB\n"
1878 "Don't block when locking. This is combined with one of the\n"
1879 "other operations using @code{logior}. If @code{flock} would\n"
1880 "block an @code{EWOULDBLOCK} error is thrown.\n"
1881 "@end defvar\n"
1882 "\n"
1883 "The return value is not specified. @var{file} may be an open\n"
1884 "file descriptor or an open file descriptor port.\n"
1885 "\n"
1886 "Note that @code{flock} does not lock files across NFS.")
1887 #define FUNC_NAME s_scm_flock
1888 {
1889 int fdes;
1890
1891 if (scm_is_integer (file))
1892 fdes = scm_to_int (file);
1893 else
1894 {
1895 SCM_VALIDATE_OPFPORT (2, file);
1896
1897 fdes = SCM_FPORT_FDES (file);
1898 }
1899 if (flock (fdes, scm_to_int (operation)) == -1)
1900 SCM_SYSERROR;
1901 return SCM_UNSPECIFIED;
1902 }
1903 #undef FUNC_NAME
1904
1905 #if HAVE_SETHOSTNAME
1906 SCM_DEFINE (scm_sethostname, "sethostname", 1, 0, 0,
1907 (SCM name),
1908 "Set the host name of the current processor to @var{name}. May\n"
1909 "only be used by the superuser. The return value is not\n"
1910 "specified.")
1911 #define FUNC_NAME s_scm_sethostname
1912 {
1913 int rv;
1914
1915 WITH_STRING (name, c_name,
1916 rv = sethostname (c_name, strlen(c_name)));
1917 if (rv == -1)
1918 SCM_SYSERROR;
1919 return SCM_UNSPECIFIED;
1920 }
1921 #undef FUNC_NAME
1922 #endif /* HAVE_SETHOSTNAME */
1923
1924
1925 #if HAVE_GETHOSTNAME
1926 SCM_DEFINE (scm_gethostname, "gethostname", 0, 0, 0,
1927 (void),
1928 "Return the host name of the current processor.")
1929 #define FUNC_NAME s_scm_gethostname
1930 {
1931 #ifdef MAXHOSTNAMELEN
1932
1933 /* Various systems define MAXHOSTNAMELEN (including Solaris in fact).
1934 * On GNU/Linux this doesn't include the terminating '\0', hence "+ 1". */
1935 const int len = MAXHOSTNAMELEN + 1;
1936 char *const p = scm_malloc (len);
1937 const int res = gethostname (p, len);
1938
1939 scm_dynwind_begin (0);
1940 scm_dynwind_unwind_handler (free, p, 0);
1941
1942 #else
1943
1944 /* Default 256 is for Solaris, under Linux ENAMETOOLONG is returned if not
1945 * large enough. SUSv2 specifies 255 maximum too, apparently. */
1946 int len = 256;
1947 int res;
1948 char *p;
1949
1950 # if HAVE_SYSCONF && defined (_SC_HOST_NAME_MAX)
1951
1952 /* POSIX specifies the HOST_NAME_MAX system parameter for the max size,
1953 * which may reflect a particular kernel configuration.
1954 * Must watch out for this existing but giving -1, as happens for instance
1955 * in gnu/linux glibc 2.3.2. */
1956 {
1957 const long int n = sysconf (_SC_HOST_NAME_MAX);
1958 if (n != -1L)
1959 len = n;
1960 }
1961
1962 # endif
1963
1964 p = scm_malloc (len);
1965
1966 scm_dynwind_begin (0);
1967 scm_dynwind_unwind_handler (free, p, 0);
1968
1969 res = gethostname (p, len);
1970 while (res == -1 && errno == ENAMETOOLONG)
1971 {
1972 len *= 2;
1973
1974 /* scm_realloc may throw an exception. */
1975 p = scm_realloc (p, len);
1976 res = gethostname (p, len);
1977 }
1978
1979 #endif
1980
1981 if (res == -1)
1982 {
1983 const int save_errno = errno;
1984
1985 /* No guile exceptions can occur before we have freed p's memory. */
1986 scm_dynwind_end ();
1987 free (p);
1988
1989 errno = save_errno;
1990 SCM_SYSERROR;
1991 }
1992 else
1993 {
1994 /* scm_from_locale_string may throw an exception. */
1995 const SCM name = scm_from_locale_string (p);
1996
1997 /* No guile exceptions can occur before we have freed p's memory. */
1998 scm_dynwind_end ();
1999 free (p);
2000
2001 return name;
2002 }
2003 }
2004 #undef FUNC_NAME
2005 #endif /* HAVE_GETHOSTNAME */
2006
2007
2008 void
2009 scm_init_posix ()
2010 {
2011 scm_add_feature ("posix");
2012 #ifdef HAVE_GETEUID
2013 scm_add_feature ("EIDs");
2014 #endif
2015 #ifdef WAIT_ANY
2016 scm_c_define ("WAIT_ANY", scm_from_int (WAIT_ANY));
2017 #endif
2018 #ifdef WAIT_MYPGRP
2019 scm_c_define ("WAIT_MYPGRP", scm_from_int (WAIT_MYPGRP));
2020 #endif
2021 #ifdef WNOHANG
2022 scm_c_define ("WNOHANG", scm_from_int (WNOHANG));
2023 #endif
2024 #ifdef WUNTRACED
2025 scm_c_define ("WUNTRACED", scm_from_int (WUNTRACED));
2026 #endif
2027
2028 /* access() symbols. */
2029 scm_c_define ("R_OK", scm_from_int (R_OK));
2030 scm_c_define ("W_OK", scm_from_int (W_OK));
2031 scm_c_define ("X_OK", scm_from_int (X_OK));
2032 scm_c_define ("F_OK", scm_from_int (F_OK));
2033
2034 #ifdef LC_COLLATE
2035 scm_c_define ("LC_COLLATE", scm_from_int (LC_COLLATE));
2036 #endif
2037 #ifdef LC_CTYPE
2038 scm_c_define ("LC_CTYPE", scm_from_int (LC_CTYPE));
2039 #endif
2040 #ifdef LC_MONETARY
2041 scm_c_define ("LC_MONETARY", scm_from_int (LC_MONETARY));
2042 #endif
2043 #ifdef LC_NUMERIC
2044 scm_c_define ("LC_NUMERIC", scm_from_int (LC_NUMERIC));
2045 #endif
2046 #ifdef LC_TIME
2047 scm_c_define ("LC_TIME", scm_from_int (LC_TIME));
2048 #endif
2049 #ifdef LC_MESSAGES
2050 scm_c_define ("LC_MESSAGES", scm_from_int (LC_MESSAGES));
2051 #endif
2052 #ifdef LC_ALL
2053 scm_c_define ("LC_ALL", scm_from_int (LC_ALL));
2054 #endif
2055 #ifdef LC_PAPER
2056 scm_c_define ("LC_PAPER", scm_from_int (LC_PAPER));
2057 #endif
2058 #ifdef LC_NAME
2059 scm_c_define ("LC_NAME", scm_from_int (LC_NAME));
2060 #endif
2061 #ifdef LC_ADDRESS
2062 scm_c_define ("LC_ADDRESS", scm_from_int (LC_ADDRESS));
2063 #endif
2064 #ifdef LC_TELEPHONE
2065 scm_c_define ("LC_TELEPHONE", scm_from_int (LC_TELEPHONE));
2066 #endif
2067 #ifdef LC_MEASUREMENT
2068 scm_c_define ("LC_MEASUREMENT", scm_from_int (LC_MEASUREMENT));
2069 #endif
2070 #ifdef LC_IDENTIFICATION
2071 scm_c_define ("LC_IDENTIFICATION", scm_from_int (LC_IDENTIFICATION));
2072 #endif
2073 #ifdef PIPE_BUF
2074 scm_c_define ("PIPE_BUF", scm_from_long (PIPE_BUF));
2075 #endif
2076
2077 #ifdef PRIO_PROCESS
2078 scm_c_define ("PRIO_PROCESS", scm_from_int (PRIO_PROCESS));
2079 #endif
2080 #ifdef PRIO_PGRP
2081 scm_c_define ("PRIO_PGRP", scm_from_int (PRIO_PGRP));
2082 #endif
2083 #ifdef PRIO_USER
2084 scm_c_define ("PRIO_USER", scm_from_int (PRIO_USER));
2085 #endif
2086
2087 #ifdef LOCK_SH
2088 scm_c_define ("LOCK_SH", scm_from_int (LOCK_SH));
2089 #endif
2090 #ifdef LOCK_EX
2091 scm_c_define ("LOCK_EX", scm_from_int (LOCK_EX));
2092 #endif
2093 #ifdef LOCK_UN
2094 scm_c_define ("LOCK_UN", scm_from_int (LOCK_UN));
2095 #endif
2096 #ifdef LOCK_NB
2097 scm_c_define ("LOCK_NB", scm_from_int (LOCK_NB));
2098 #endif
2099
2100 #include "libguile/cpp_sig_symbols.c"
2101 #include "libguile/posix.x"
2102 }
2103
2104 /*
2105 Local Variables:
2106 c-file-style: "gnu"
2107 End:
2108 */