remove libguile/lang.h, deprecate %nil (in favor of #nil)
[bpt/guile.git] / libguile / posix.c
CommitLineData
adfb4284 1/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
0f2d19dd 2 *
73be1d9e 3 * This library is free software; you can redistribute it and/or
53befeb7
NJ
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.
0f2d19dd 7 *
53befeb7
NJ
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
0f2d19dd 12 *
73be1d9e
MV
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
53befeb7
NJ
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301 USA
73be1d9e 17 */
1bbd0b84 18
1bbd0b84 19
0f2d19dd 20\f
dbb605f5 21#ifdef HAVE_CONFIG_H
2546b5c3
RB
22# include <config.h>
23#endif
0f2d19dd 24
3731192f 25#include <stdlib.h>
0f2d19dd 26#include <stdio.h>
e6e2e95a 27#include <errno.h>
889975e5 28#include <uniconv.h>
e6e2e95a 29
a0599745 30#include "libguile/_scm.h"
b28f5b3c 31#include "libguile/dynwind.h"
a0599745
MD
32#include "libguile/fports.h"
33#include "libguile/scmsigs.h"
34#include "libguile/feature.h"
35#include "libguile/strings.h"
c44ca4fe 36#include "libguile/srfi-13.h"
a17d2654 37#include "libguile/srfi-14.h"
a0599745 38#include "libguile/vectors.h"
4ea9429e 39#include "libguile/values.h"
a0599745
MD
40
41#include "libguile/validate.h"
42#include "libguile/posix.h"
b89c4943 43#include "libguile/gettext.h"
9de87eea 44#include "libguile/threads.h"
0f2d19dd
JB
45\f
46
02b754d3
GH
47#ifdef HAVE_STRING_H
48#include <string.h>
49#endif
0f2d19dd
JB
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>
95b88819
GH
63#else
64#ifndef ttyname
65extern char *ttyname();
66#endif
0f2d19dd
JB
67#endif
68
3594582b 69#ifdef LIBC_H_WITH_UNISTD_H
bab0f4e5
JB
70#include <libc.h>
71#endif
72
8cc71382 73#include <sys/types.h>
0f2d19dd
JB
74#include <sys/stat.h>
75#include <fcntl.h>
76
82893676 77#ifdef HAVE_PWD_H
0f2d19dd 78#include <pwd.h>
82893676
MG
79#endif
80#ifdef HAVE_IO_H
81#include <io.h>
82#endif
f87c105a 83#ifdef HAVE_WINSOCK2_H
82893676
MG
84#include <winsock2.h>
85#endif
86
87#ifdef __MINGW32__
88/* Some defines for Windows here. */
7beabedb 89# include <process.h>
82893676
MG
90# define pipe(fd) _pipe (fd, 256, O_BINARY)
91#endif /* __MINGW32__ */
0f2d19dd
JB
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
82893676 105#ifdef HAVE_GRP_H
0f2d19dd 106#include <grp.h>
82893676
MG
107#endif
108#ifdef HAVE_SYS_UTSNAME_H
0f2d19dd 109#include <sys/utsname.h>
82893676 110#endif
0f2d19dd 111
0f2d19dd
JB
112#ifdef HAVE_SETLOCALE
113#include <locale.h>
114#endif
115
b89c4943
LC
116#if (defined HAVE_NEWLOCALE) && (defined HAVE_STRCOLL_L)
117# define USE_GNU_LOCALE_API
118#endif
119
a2f00b9b
LC
120#if (defined USE_GNU_LOCALE_API) && (defined HAVE_XLOCALE_H)
121# include <xlocale.h>
122#endif
123
b9a7b725 124#if HAVE_CRYPT_H
94e6d793
MG
125# include <crypt.h>
126#endif
127
0eaf1055
KR
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
94e6d793
MG
136#if HAVE_SYS_RESOURCE_H
137# include <sys/resource.h>
138#endif
139
837b0ae0 140#include <sys/file.h> /* from Gnulib */
eb7e1603 141
bab0f4e5
JB
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
398609a5 159
8ab3d8a0
KR
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
163int sethostname (char *name, size_t namelen);
164#endif
165
398609a5
JB
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
eb7e1603
KR
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
0f2d19dd 194\f
f015614a
MV
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
bc45012d
JB
216SCM_SYMBOL (sym_read_pipe, "read pipe");
217SCM_SYMBOL (sym_write_pipe, "write pipe");
0f2d19dd 218
a1ec6916 219SCM_DEFINE (scm_pipe, "pipe", 0, 0, 0,
1bbd0b84 220 (),
1e6808ea
MG
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.")
1bbd0b84 234#define FUNC_NAME s_scm_pipe
0f2d19dd
JB
235{
236 int fd[2], rv;
0f2d19dd 237 SCM p_rd, p_wt;
02b754d3 238
0f2d19dd
JB
239 rv = pipe (fd);
240 if (rv)
1bbd0b84 241 SCM_SYSERROR;
ee149d03
JB
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);
0f2d19dd
JB
245 return scm_cons (p_rd, p_wt);
246}
1bbd0b84 247#undef FUNC_NAME
0f2d19dd
JB
248
249
0e958795 250#ifdef HAVE_GETGROUPS
a1ec6916 251SCM_DEFINE (scm_getgroups, "getgroups", 0, 0, 0,
1bbd0b84 252 (),
1e6808ea 253 "Return a vector of integers representing the current\n"
bb2c02f2 254 "supplementary group IDs.")
1bbd0b84 255#define FUNC_NAME s_scm_getgroups
0f2d19dd 256{
1d1559ce 257 SCM result;
66460dfb 258 int ngroups;
1be6b49c 259 size_t size;
66460dfb
DH
260 GETGROUPS_T *groups;
261
262 ngroups = getgroups (0, NULL);
263 if (ngroups <= 0)
1bbd0b84 264 SCM_SYSERROR;
66460dfb
DH
265
266 size = ngroups * sizeof (GETGROUPS_T);
4c9419ac 267 groups = scm_malloc (size);
634aa8de 268 ngroups = getgroups (ngroups, groups);
66460dfb 269
f360a962
MV
270 result = scm_c_make_vector (ngroups, SCM_BOOL_F);
271 while (--ngroups >= 0)
4057a3e0 272 SCM_SIMPLE_VECTOR_SET (result, ngroups, scm_from_ulong (groups[ngroups]));
66460dfb 273
4c9419ac 274 free (groups);
1d1559ce 275 return result;
1bbd0b84
GB
276}
277#undef FUNC_NAME
0e958795 278#endif
0f2d19dd 279
f360a962
MV
280#ifdef HAVE_SETGROUPS
281SCM_DEFINE (scm_setgroups, "setgroups", 1, 0, 0,
282 (SCM group_vec),
fcc3adc2
KR
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.")
f360a962
MV
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
4057a3e0 299 ngroups = SCM_SIMPLE_VECTOR_LENGTH (group_vec);
f360a962
MV
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;
4057a3e0
MV
306 SCM_VALIDATE_ULONG_COPY (1, SCM_SIMPLE_VECTOR_REF (group_vec, i),
307 ulong_gid);
f360a962
MV
308 gid = ulong_gid;
309 if (gid != ulong_gid)
4057a3e0 310 SCM_OUT_OF_RANGE (1, SCM_SIMPLE_VECTOR_REF (group_vec, i));
f360a962
MV
311 }
312
313 size = ngroups * sizeof (GETGROUPS_T);
2eb78d06 314 if (size / sizeof (GETGROUPS_T) != ngroups)
e11e83f3 315 SCM_OUT_OF_RANGE (SCM_ARG1, scm_from_int (ngroups));
f360a962
MV
316 groups = scm_malloc (size);
317 for(i = 0; i < ngroups; i++)
4057a3e0 318 groups [i] = SCM_NUM2ULONG (1, SCM_SIMPLE_VECTOR_REF (group_vec, i));
f360a962
MV
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
82893676 331#ifdef HAVE_GETPWENT
a1ec6916 332SCM_DEFINE (scm_getpwuid, "getpw", 0, 1, 0,
1bbd0b84 333 (SCM user),
b380b885
MD
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.")
1bbd0b84 337#define FUNC_NAME s_scm_getpwuid
0f2d19dd 338{
0f2d19dd 339 struct passwd *entry;
0f2d19dd 340
1d1559ce 341 SCM result = scm_c_make_vector (7, SCM_UNSPECIFIED);
7888309b 342 if (SCM_UNBNDP (user) || scm_is_false (user))
0f2d19dd 343 {
0f2d19dd 344 SCM_SYSCALL (entry = getpwent ());
3d781d49
JB
345 if (! entry)
346 {
3d781d49
JB
347 return SCM_BOOL_F;
348 }
0f2d19dd 349 }
e11e83f3 350 else if (scm_is_integer (user))
0f2d19dd 351 {
e11e83f3 352 entry = getpwuid (scm_to_int (user));
0f2d19dd
JB
353 }
354 else
355 {
f015614a
MV
356 WITH_STRING (user, c_user,
357 entry = getpwnam (c_user));
0f2d19dd
JB
358 }
359 if (!entry)
1bbd0b84 360 SCM_MISC_ERROR ("entry not found", SCM_EOL);
02b754d3 361
4057a3e0
MV
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));
0f2d19dd 367 if (!entry->pw_dir)
4057a3e0 368 SCM_SIMPLE_VECTOR_SET(result, 5, scm_from_locale_string (""));
0f2d19dd 369 else
4057a3e0 370 SCM_SIMPLE_VECTOR_SET(result, 5, scm_from_locale_string (entry->pw_dir));
0f2d19dd 371 if (!entry->pw_shell)
4057a3e0 372 SCM_SIMPLE_VECTOR_SET(result, 6, scm_from_locale_string (""));
0f2d19dd 373 else
4057a3e0 374 SCM_SIMPLE_VECTOR_SET(result, 6, scm_from_locale_string (entry->pw_shell));
1d1559ce 375 return result;
0f2d19dd 376}
1bbd0b84 377#undef FUNC_NAME
82893676 378#endif /* HAVE_GETPWENT */
0f2d19dd
JB
379
380
0e958795 381#ifdef HAVE_SETPWENT
a1ec6916 382SCM_DEFINE (scm_setpwent, "setpw", 0, 1, 0,
1bbd0b84 383 (SCM arg),
b380b885
MD
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.")
1bbd0b84 387#define FUNC_NAME s_scm_setpwent
0f2d19dd 388{
7888309b 389 if (SCM_UNBNDP (arg) || scm_is_false (arg))
0f2d19dd
JB
390 endpwent ();
391 else
392 setpwent ();
393 return SCM_UNSPECIFIED;
394}
1bbd0b84 395#undef FUNC_NAME
0e958795 396#endif
0f2d19dd
JB
397
398
82893676 399#ifdef HAVE_GETGRENT
0f2d19dd 400/* Combines getgrgid and getgrnam. */
a1ec6916 401SCM_DEFINE (scm_getgrgid, "getgr", 0, 1, 0,
1bbd0b84 402 (SCM name),
b380b885
MD
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.")
1bbd0b84 406#define FUNC_NAME s_scm_getgrgid
0f2d19dd 407{
0f2d19dd 408 struct group *entry;
1d1559ce 409 SCM result = scm_c_make_vector (4, SCM_UNSPECIFIED);
34d19ef6 410
7888309b 411 if (SCM_UNBNDP (name) || scm_is_false (name))
3d781d49
JB
412 {
413 SCM_SYSCALL (entry = getgrent ());
414 if (! entry)
415 {
3d781d49
JB
416 return SCM_BOOL_F;
417 }
418 }
e11e83f3
MV
419 else if (scm_is_integer (name))
420 SCM_SYSCALL (entry = getgrgid (scm_to_int (name)));
0f2d19dd 421 else
f015614a
MV
422 STRING_SYSCALL (name, c_name,
423 entry = getgrnam (c_name));
0f2d19dd 424 if (!entry)
1bbd0b84 425 SCM_SYSERROR;
02b754d3 426
4057a3e0
MV
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));
1d1559ce 431 return result;
0f2d19dd 432}
1bbd0b84 433#undef FUNC_NAME
0f2d19dd
JB
434
435
436
a1ec6916 437SCM_DEFINE (scm_setgrent, "setgr", 0, 1, 0,
1bbd0b84 438 (SCM arg),
b380b885
MD
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.")
1bbd0b84 442#define FUNC_NAME s_scm_setgrent
0f2d19dd 443{
7888309b 444 if (SCM_UNBNDP (arg) || scm_is_false (arg))
0f2d19dd
JB
445 endgrent ();
446 else
447 setgrent ();
448 return SCM_UNSPECIFIED;
449}
1bbd0b84 450#undef FUNC_NAME
82893676 451#endif /* HAVE_GETGRENT */
0f2d19dd
JB
452
453
4ea9429e
AW
454#ifdef HAVE_GETRLIMIT
455#ifdef RLIMIT_AS
456SCM_SYMBOL (sym_as, "as");
457#endif
458#ifdef RLIMIT_CORE
459SCM_SYMBOL (sym_core, "core");
460#endif
461#ifdef RLIMIT_CPU
462SCM_SYMBOL (sym_cpu, "cpu");
463#endif
464#ifdef RLIMIT_DATA
465SCM_SYMBOL (sym_data, "data");
466#endif
467#ifdef RLIMIT_FSIZE
468SCM_SYMBOL (sym_fsize, "fsize");
469#endif
470#ifdef RLIMIT_MEMLOCK
471SCM_SYMBOL (sym_memlock, "memlock");
472#endif
473#ifdef RLIMIT_MSGQUEUE
474SCM_SYMBOL (sym_msgqueue, "msgqueue");
475#endif
476#ifdef RLIMIT_NICE
477SCM_SYMBOL (sym_nice, "nice");
478#endif
479#ifdef RLIMIT_NOFILE
480SCM_SYMBOL (sym_nofile, "nofile");
481#endif
482#ifdef RLIMIT_NPROC
483SCM_SYMBOL (sym_nproc, "nproc");
484#endif
485#ifdef RLIMIT_RSS
486SCM_SYMBOL (sym_rss, "rss");
487#endif
488#ifdef RLIMIT_RTPRIO
489SCM_SYMBOL (sym_rtprio, "rtprio");
490#endif
491#ifdef RLIMIT_RTPRIO
492SCM_SYMBOL (sym_rttime, "rttime");
493#endif
494#ifdef RLIMIT_SIGPENDING
495SCM_SYMBOL (sym_sigpending, "sigpending");
496#endif
497#ifdef RLIMIT_STACK
498SCM_SYMBOL (sym_stack, "stack");
499#endif
500
501static int
502scm_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
574SCM_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
600SCM_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
a1ec6916 627SCM_DEFINE (scm_kill, "kill", 2, 0, 0,
1bbd0b84 628 (SCM pid, SCM sig),
b380b885
MD
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")
1bbd0b84 651#define FUNC_NAME s_scm_kill
0f2d19dd 652{
0f2d19dd 653 /* Signal values are interned in scm_init_posix(). */
82893676 654#ifdef HAVE_KILL
a55c2b68 655 if (kill (scm_to_int (pid), scm_to_int (sig)) != 0)
23d72566 656 SCM_SYSERROR;
82893676 657#else
23d72566
KR
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. */
a55c2b68 661 if (scm_to_int (pid) == getpid ())
23d72566
KR
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 }
82893676 674#endif
02b754d3 675 return SCM_UNSPECIFIED;
0f2d19dd 676}
1bbd0b84 677#undef FUNC_NAME
0f2d19dd 678
d00ae47e 679#ifdef HAVE_WAITPID
a1ec6916 680SCM_DEFINE (scm_waitpid, "waitpid", 1, 1, 0,
1bbd0b84 681 (SCM pid, SCM options),
b380b885
MD
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")
1bbd0b84 716#define FUNC_NAME s_scm_waitpid
0f2d19dd
JB
717{
718 int i;
719 int status;
720 int ioptions;
0f2d19dd
JB
721 if (SCM_UNBNDP (options))
722 ioptions = 0;
723 else
724 {
0f2d19dd 725 /* Flags are interned in scm_init_posix. */
a55c2b68 726 ioptions = scm_to_int (options);
0f2d19dd 727 }
a55c2b68 728 SCM_SYSCALL (i = waitpid (scm_to_int (pid), &status, ioptions));
02b754d3 729 if (i == -1)
1bbd0b84 730 SCM_SYSERROR;
a55c2b68 731 return scm_cons (scm_from_int (i), scm_from_int (status));
0f2d19dd 732}
1bbd0b84 733#undef FUNC_NAME
d00ae47e 734#endif /* HAVE_WAITPID */
0f2d19dd 735
82893676 736#ifndef __MINGW32__
a1ec6916 737SCM_DEFINE (scm_status_exit_val, "status:exit-val", 1, 0, 0,
1bbd0b84 738 (SCM status),
1e6808ea
MG
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}.")
1bbd0b84 742#define FUNC_NAME s_scm_status_exit_val
67ec3667 743{
e67dc2be
JB
744 int lstatus;
745
e67dc2be 746 /* On Ultrix, the WIF... macros assume their argument is an lvalue;
e11e83f3 747 go figure. */
a55c2b68 748 lstatus = scm_to_int (status);
e67dc2be 749 if (WIFEXITED (lstatus))
a55c2b68 750 return (scm_from_int (WEXITSTATUS (lstatus)));
67ec3667
GH
751 else
752 return SCM_BOOL_F;
753}
1bbd0b84 754#undef FUNC_NAME
e67dc2be 755
a1ec6916 756SCM_DEFINE (scm_status_term_sig, "status:term-sig", 1, 0, 0,
1bbd0b84 757 (SCM status),
1e6808ea
MG
758 "Return the signal number which terminated the process, if any,\n"
759 "otherwise @code{#f}.")
1bbd0b84 760#define FUNC_NAME s_scm_status_term_sig
67ec3667 761{
e67dc2be
JB
762 int lstatus;
763
a55c2b68 764 lstatus = scm_to_int (status);
e67dc2be 765 if (WIFSIGNALED (lstatus))
a55c2b68 766 return scm_from_int (WTERMSIG (lstatus));
67ec3667
GH
767 else
768 return SCM_BOOL_F;
769}
1bbd0b84 770#undef FUNC_NAME
0f2d19dd 771
a1ec6916 772SCM_DEFINE (scm_status_stop_sig, "status:stop-sig", 1, 0, 0,
1bbd0b84 773 (SCM status),
1e6808ea
MG
774 "Return the signal number which stopped the process, if any,\n"
775 "otherwise @code{#f}.")
1bbd0b84 776#define FUNC_NAME s_scm_status_stop_sig
67ec3667 777{
e67dc2be
JB
778 int lstatus;
779
a55c2b68 780 lstatus = scm_to_int (status);
e67dc2be 781 if (WIFSTOPPED (lstatus))
a55c2b68 782 return scm_from_int (WSTOPSIG (lstatus));
67ec3667
GH
783 else
784 return SCM_BOOL_F;
785}
1bbd0b84 786#undef FUNC_NAME
82893676 787#endif /* __MINGW32__ */
0f2d19dd 788
82893676 789#ifdef HAVE_GETPPID
a1ec6916 790SCM_DEFINE (scm_getppid, "getppid", 0, 0, 0,
1bbd0b84 791 (),
1e6808ea
MG
792 "Return an integer representing the process ID of the parent\n"
793 "process.")
1bbd0b84 794#define FUNC_NAME s_scm_getppid
0f2d19dd 795{
e11e83f3 796 return scm_from_int (getppid ());
0f2d19dd 797}
1bbd0b84 798#undef FUNC_NAME
82893676 799#endif /* HAVE_GETPPID */
0f2d19dd
JB
800
801
82893676 802#ifndef __MINGW32__
a1ec6916 803SCM_DEFINE (scm_getuid, "getuid", 0, 0, 0,
1bbd0b84 804 (),
1e6808ea 805 "Return an integer representing the current real user ID.")
1bbd0b84 806#define FUNC_NAME s_scm_getuid
0f2d19dd 807{
e11e83f3 808 return scm_from_int (getuid ());
0f2d19dd 809}
1bbd0b84 810#undef FUNC_NAME
0f2d19dd
JB
811
812
813
a1ec6916 814SCM_DEFINE (scm_getgid, "getgid", 0, 0, 0,
1bbd0b84 815 (),
1e6808ea 816 "Return an integer representing the current real group ID.")
1bbd0b84 817#define FUNC_NAME s_scm_getgid
0f2d19dd 818{
e11e83f3 819 return scm_from_int (getgid ());
0f2d19dd 820}
1bbd0b84 821#undef FUNC_NAME
0f2d19dd
JB
822
823
824
a1ec6916 825SCM_DEFINE (scm_geteuid, "geteuid", 0, 0, 0,
1bbd0b84 826 (),
1e6808ea 827 "Return an integer representing the current effective user ID.\n"
b380b885 828 "If the system does not support effective IDs, then the real ID\n"
480fa28d 829 "is returned. @code{(provided? 'EIDs)} reports whether the\n"
1e6808ea 830 "system supports effective IDs.")
1bbd0b84 831#define FUNC_NAME s_scm_geteuid
0f2d19dd
JB
832{
833#ifdef HAVE_GETEUID
e11e83f3 834 return scm_from_int (geteuid ());
0f2d19dd 835#else
e11e83f3 836 return scm_from_int (getuid ());
0f2d19dd
JB
837#endif
838}
1bbd0b84 839#undef FUNC_NAME
0f2d19dd
JB
840
841
a1ec6916 842SCM_DEFINE (scm_getegid, "getegid", 0, 0, 0,
1bbd0b84 843 (),
1e6808ea 844 "Return an integer representing the current effective group ID.\n"
b380b885 845 "If the system does not support effective IDs, then the real ID\n"
480fa28d 846 "is returned. @code{(provided? 'EIDs)} reports whether the\n"
1e6808ea 847 "system supports effective IDs.")
1bbd0b84 848#define FUNC_NAME s_scm_getegid
0f2d19dd
JB
849{
850#ifdef HAVE_GETEUID
e11e83f3 851 return scm_from_int (getegid ());
0f2d19dd 852#else
e11e83f3 853 return scm_from_int (getgid ());
0f2d19dd
JB
854#endif
855}
1bbd0b84 856#undef FUNC_NAME
0f2d19dd
JB
857
858
a1ec6916 859SCM_DEFINE (scm_setuid, "setuid", 1, 0, 0,
1bbd0b84 860 (SCM id),
b380b885
MD
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.")
1bbd0b84 864#define FUNC_NAME s_scm_setuid
0f2d19dd 865{
a55c2b68 866 if (setuid (scm_to_int (id)) != 0)
1bbd0b84 867 SCM_SYSERROR;
02b754d3 868 return SCM_UNSPECIFIED;
0f2d19dd 869}
1bbd0b84 870#undef FUNC_NAME
0f2d19dd 871
a1ec6916 872SCM_DEFINE (scm_setgid, "setgid", 1, 0, 0,
1bbd0b84 873 (SCM id),
b380b885
MD
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.")
1bbd0b84 877#define FUNC_NAME s_scm_setgid
0f2d19dd 878{
a55c2b68 879 if (setgid (scm_to_int (id)) != 0)
1bbd0b84 880 SCM_SYSERROR;
02b754d3 881 return SCM_UNSPECIFIED;
0f2d19dd 882}
1bbd0b84 883#undef FUNC_NAME
0f2d19dd 884
a1ec6916 885SCM_DEFINE (scm_seteuid, "seteuid", 1, 0, 0,
1bbd0b84 886 (SCM id),
b380b885
MD
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"
480fa28d 889 "real ID is set instead -- @code{(provided? 'EIDs)} reports whether the\n"
b380b885
MD
890 "system supports effective IDs.\n"
891 "The return value is unspecified.")
1bbd0b84 892#define FUNC_NAME s_scm_seteuid
0f2d19dd 893{
02b754d3
GH
894 int rv;
895
0f2d19dd 896#ifdef HAVE_SETEUID
a55c2b68 897 rv = seteuid (scm_to_int (id));
0f2d19dd 898#else
a55c2b68 899 rv = setuid (scm_to_int (id));
0f2d19dd 900#endif
02b754d3 901 if (rv != 0)
1bbd0b84 902 SCM_SYSERROR;
02b754d3 903 return SCM_UNSPECIFIED;
0f2d19dd 904}
1bbd0b84 905#undef FUNC_NAME
7beabedb
MG
906#endif /* __MINGW32__ */
907
0f2d19dd 908
0e958795 909#ifdef HAVE_SETEGID
a1ec6916 910SCM_DEFINE (scm_setegid, "setegid", 1, 0, 0,
1bbd0b84 911 (SCM id),
b380b885
MD
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"
480fa28d 914 "real ID is set instead -- @code{(provided? 'EIDs)} reports whether the\n"
b380b885
MD
915 "system supports effective IDs.\n"
916 "The return value is unspecified.")
1bbd0b84 917#define FUNC_NAME s_scm_setegid
0f2d19dd 918{
02b754d3
GH
919 int rv;
920
0f2d19dd 921#ifdef HAVE_SETEUID
a55c2b68 922 rv = setegid (scm_to_int (id));
0f2d19dd 923#else
a55c2b68 924 rv = setgid (scm_to_int (id));
0f2d19dd 925#endif
02b754d3 926 if (rv != 0)
1bbd0b84 927 SCM_SYSERROR;
02b754d3
GH
928 return SCM_UNSPECIFIED;
929
0f2d19dd 930}
1bbd0b84 931#undef FUNC_NAME
0e958795 932#endif
0f2d19dd 933
82893676
MG
934
935#ifdef HAVE_GETPGRP
a1ec6916 936SCM_DEFINE (scm_getpgrp, "getpgrp", 0, 0, 0,
1bbd0b84 937 (),
1e6808ea 938 "Return an integer representing the current process group ID.\n"
b380b885 939 "This is the POSIX definition, not BSD.")
1bbd0b84 940#define FUNC_NAME s_scm_getpgrp
0f2d19dd
JB
941{
942 int (*fn)();
4625e44f 943 fn = (int (*) ()) getpgrp;
e11e83f3 944 return scm_from_int (fn (0));
0f2d19dd 945}
1bbd0b84 946#undef FUNC_NAME
82893676
MG
947#endif /* HAVE_GETPGRP */
948
0f2d19dd 949
f25f761d 950#ifdef HAVE_SETPGID
a1ec6916 951SCM_DEFINE (scm_setpgid, "setpgid", 2, 0, 0,
1bbd0b84 952 (SCM pid, SCM pgid),
b380b885
MD
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.")
1bbd0b84 958#define FUNC_NAME s_scm_setpgid
0f2d19dd 959{
02b754d3 960 /* FIXME(?): may be known as setpgrp. */
a55c2b68 961 if (setpgid (scm_to_int (pid), scm_to_int (pgid)) != 0)
1bbd0b84 962 SCM_SYSERROR;
02b754d3 963 return SCM_UNSPECIFIED;
0f2d19dd 964}
1bbd0b84 965#undef FUNC_NAME
f25f761d 966#endif /* HAVE_SETPGID */
0f2d19dd 967
f25f761d 968#ifdef HAVE_SETSID
a1ec6916 969SCM_DEFINE (scm_setsid, "setsid", 0, 0, 0,
1bbd0b84 970 (),
b380b885
MD
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.")
1bbd0b84 975#define FUNC_NAME s_scm_setsid
0f2d19dd
JB
976{
977 pid_t sid = setsid ();
02b754d3 978 if (sid == -1)
1bbd0b84 979 SCM_SYSERROR;
02b754d3 980 return SCM_UNSPECIFIED;
0f2d19dd 981}
1bbd0b84 982#undef FUNC_NAME
f25f761d 983#endif /* HAVE_SETSID */
0f2d19dd 984
3e5aed1c
NJ
985#ifdef HAVE_GETSID
986SCM_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
e8a59063
KR
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
82893676 1006#ifdef HAVE_TTYNAME
a1ec6916 1007SCM_DEFINE (scm_ttyname, "ttyname", 1, 0, 0,
1bbd0b84 1008 (SCM port),
1e6808ea
MG
1009 "Return a string with the name of the serial terminal device\n"
1010 "underlying @var{port}.")
1bbd0b84 1011#define FUNC_NAME s_scm_ttyname
0f2d19dd 1012{
1d1559ce 1013 char *result;
e8a59063 1014 int fd, err;
a1ef7406 1015 SCM ret = SCM_BOOL_F;
78446828
MV
1016
1017 port = SCM_COERCE_OUTPORT (port);
34d19ef6 1018 SCM_VALIDATE_OPPORT (1, port);
a98bddfd 1019 if (!SCM_FPORTP (port))
0f2d19dd 1020 return SCM_BOOL_F;
ee149d03 1021 fd = SCM_FPORT_FDES (port);
e8a59063 1022
9de87eea 1023 scm_i_scm_pthread_mutex_lock (&scm_i_misc_mutex);
a1ef7406 1024
1d1559ce 1025 SCM_SYSCALL (result = ttyname (fd));
e8a59063 1026 err = errno;
a1ef7406
LC
1027 if (result != NULL)
1028 result = strdup (result);
1029
9de87eea 1030 scm_i_pthread_mutex_unlock (&scm_i_misc_mutex);
e8a59063 1031
1d1559ce 1032 if (!result)
e8a59063
KR
1033 {
1034 errno = err;
1035 SCM_SYSERROR;
1036 }
a1ef7406
LC
1037 else
1038 ret = scm_take_locale_string (result);
1039
e8a59063 1040 return ret;
0f2d19dd 1041}
1bbd0b84 1042#undef FUNC_NAME
82893676 1043#endif /* HAVE_TTYNAME */
0f2d19dd 1044
e8a59063 1045
0a9d83b0
KR
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. */
f25f761d 1051#ifdef HAVE_CTERMID
a1ec6916 1052SCM_DEFINE (scm_ctermid, "ctermid", 0, 0, 0,
1bbd0b84 1053 (),
1e6808ea
MG
1054 "Return a string containing the file name of the controlling\n"
1055 "terminal for the current process.")
1bbd0b84 1056#define FUNC_NAME s_scm_ctermid
0f2d19dd 1057{
0a9d83b0
KR
1058 char buf[L_ctermid];
1059 char *result = ctermid (buf);
02b754d3 1060 if (*result == '\0')
1bbd0b84 1061 SCM_SYSERROR;
cc95e00a 1062 return scm_from_locale_string (result);
0f2d19dd 1063}
1bbd0b84 1064#undef FUNC_NAME
f25f761d 1065#endif /* HAVE_CTERMID */
0f2d19dd 1066
f25f761d 1067#ifdef HAVE_TCGETPGRP
a1ec6916 1068SCM_DEFINE (scm_tcgetpgrp, "tcgetpgrp", 1, 0, 0,
1bbd0b84 1069 (SCM port),
1e6808ea
MG
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"
b380b885
MD
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.")
1bbd0b84 1080#define FUNC_NAME s_scm_tcgetpgrp
0f2d19dd
JB
1081{
1082 int fd;
1083 pid_t pgid;
78446828
MV
1084
1085 port = SCM_COERCE_OUTPORT (port);
1086
34d19ef6 1087 SCM_VALIDATE_OPFPORT (1, port);
ee149d03
JB
1088 fd = SCM_FPORT_FDES (port);
1089 if ((pgid = tcgetpgrp (fd)) == -1)
1bbd0b84 1090 SCM_SYSERROR;
e11e83f3 1091 return scm_from_int (pgid);
1bbd0b84
GB
1092}
1093#undef FUNC_NAME
f25f761d 1094#endif /* HAVE_TCGETPGRP */
0f2d19dd 1095
f25f761d 1096#ifdef HAVE_TCSETPGRP
a1ec6916 1097SCM_DEFINE (scm_tcsetpgrp, "tcsetpgrp", 2, 0, 0,
1bbd0b84 1098 (SCM port, SCM pgid),
b380b885
MD
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.")
1bbd0b84 1104#define FUNC_NAME s_scm_tcsetpgrp
0f2d19dd
JB
1105{
1106 int fd;
78446828
MV
1107
1108 port = SCM_COERCE_OUTPORT (port);
1109
34d19ef6 1110 SCM_VALIDATE_OPFPORT (1, port);
ee149d03 1111 fd = SCM_FPORT_FDES (port);
a55c2b68 1112 if (tcsetpgrp (fd, scm_to_int (pgid)) == -1)
1bbd0b84 1113 SCM_SYSERROR;
02b754d3 1114 return SCM_UNSPECIFIED;
1bbd0b84
GB
1115}
1116#undef FUNC_NAME
f25f761d 1117#endif /* HAVE_TCSETPGRP */
0f2d19dd 1118
a1ec6916 1119SCM_DEFINE (scm_execl, "execl", 1, 0, 1,
1bbd0b84 1120 (SCM filename, SCM args),
b380b885
MD
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"
bb2c02f2 1123 "they are accessible as the @code{argv} argument to @code{main}.\n"
b380b885 1124 "Conventionally the first @var{arg} is the same as @var{path}.\n"
8f85c0c6 1125 "All arguments must be strings.\n\n"
b380b885
MD
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.")
1bbd0b84 1130#define FUNC_NAME s_scm_execl
0f2d19dd 1131{
7f03f970
MV
1132 char *exec_file;
1133 char **exec_argv;
1134
661ae7ab 1135 scm_dynwind_begin (0);
7f03f970
MV
1136
1137 exec_file = scm_to_locale_string (filename);
661ae7ab 1138 scm_dynwind_free (exec_file);
7f03f970
MV
1139
1140 exec_argv = scm_i_allocate_string_pointers (args);
7f03f970 1141
8ab3d8a0
KR
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);
1bbd0b84 1148 SCM_SYSERROR;
7f03f970 1149
02b754d3 1150 /* not reached. */
661ae7ab 1151 scm_dynwind_end ();
02b754d3 1152 return SCM_BOOL_F;
0f2d19dd 1153}
1bbd0b84 1154#undef FUNC_NAME
0f2d19dd 1155
a1ec6916 1156SCM_DEFINE (scm_execlp, "execlp", 1, 0, 1,
1bbd0b84 1157 (SCM filename, SCM args),
b380b885
MD
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"
6bcd01fc 1162 "This procedure is currently implemented using the @code{execvp} system\n"
b380b885 1163 "call, but we call it @code{execlp} because of its Scheme calling interface.")
1bbd0b84 1164#define FUNC_NAME s_scm_execlp
0f2d19dd 1165{
7f03f970
MV
1166 char *exec_file;
1167 char **exec_argv;
1168
661ae7ab 1169 scm_dynwind_begin (0);
7f03f970
MV
1170
1171 exec_file = scm_to_locale_string (filename);
661ae7ab 1172 scm_dynwind_free (exec_file);
7f03f970
MV
1173
1174 exec_argv = scm_i_allocate_string_pointers (args);
7f03f970 1175
8ab3d8a0
KR
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);
1bbd0b84 1182 SCM_SYSERROR;
7f03f970 1183
02b754d3 1184 /* not reached. */
661ae7ab 1185 scm_dynwind_end ();
02b754d3 1186 return SCM_BOOL_F;
0f2d19dd 1187}
1bbd0b84 1188#undef FUNC_NAME
0f2d19dd 1189
6afcd3b2 1190
807f353f
KR
1191/* OPTIMIZE-ME: scm_execle doesn't need malloced copies of the environment
1192 list strings the way environ_list_to_c gives. */
1193
a1ec6916 1194SCM_DEFINE (scm_execle, "execle", 2, 0, 1,
1bbd0b84 1195 (SCM filename, SCM env, SCM args),
b380b885
MD
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.")
1bbd0b84 1201#define FUNC_NAME s_scm_execle
6afcd3b2 1202{
7f03f970 1203 char **exec_argv;
6afcd3b2 1204 char **exec_env;
7f03f970 1205 char *exec_file;
6afcd3b2 1206
661ae7ab 1207 scm_dynwind_begin (0);
7f03f970
MV
1208
1209 exec_file = scm_to_locale_string (filename);
661ae7ab 1210 scm_dynwind_free (exec_file);
7f03f970
MV
1211
1212 exec_argv = scm_i_allocate_string_pointers (args);
7f03f970 1213 exec_env = scm_i_allocate_string_pointers (env);
7f03f970 1214
8ab3d8a0
KR
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);
1bbd0b84 1226 SCM_SYSERROR;
7f03f970 1227
6afcd3b2 1228 /* not reached. */
661ae7ab 1229 scm_dynwind_end ();
6afcd3b2
GH
1230 return SCM_BOOL_F;
1231}
1bbd0b84 1232#undef FUNC_NAME
6afcd3b2 1233
82893676 1234#ifdef HAVE_FORK
a1ec6916 1235SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
1bbd0b84 1236 (),
b380b885
MD
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.")
1bbd0b84 1242#define FUNC_NAME s_scm_fork
0f2d19dd 1243{
bab0f4e5 1244 int pid;
0f2d19dd
JB
1245 pid = fork ();
1246 if (pid == -1)
1bbd0b84 1247 SCM_SYSERROR;
e11e83f3 1248 return scm_from_int (pid);
0f2d19dd 1249}
1bbd0b84 1250#undef FUNC_NAME
82893676 1251#endif /* HAVE_FORK */
0f2d19dd 1252
4f68365d
MV
1253#ifdef __MINGW32__
1254# include "win32-uname.h"
1255#endif
1256
1257#if defined (HAVE_UNAME) || defined (__MINGW32__)
a1ec6916 1258SCM_DEFINE (scm_uname, "uname", 0, 0, 0,
1bbd0b84 1259 (),
1e6808ea
MG
1260 "Return an object with some information about the computer\n"
1261 "system the program is running on.")
1bbd0b84 1262#define FUNC_NAME s_scm_uname
0f2d19dd 1263{
0f2d19dd 1264 struct utsname buf;
1d1559ce 1265 SCM result = scm_c_make_vector (5, SCM_UNSPECIFIED);
e1a191a8 1266 if (uname (&buf) < 0)
1bbd0b84 1267 SCM_SYSERROR;
4057a3e0
MV
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));
0f2d19dd 1273/*
02b754d3 1274 a linux special?
4057a3e0 1275 SCM_SIMPLE_VECTOR_SET(result, 5, scm_from_locale_string (buf.domainname));
0f2d19dd 1276*/
1d1559ce 1277 return result;
0f2d19dd 1278}
1bbd0b84 1279#undef FUNC_NAME
f25f761d 1280#endif /* HAVE_UNAME */
0f2d19dd 1281
a1ec6916 1282SCM_DEFINE (scm_environ, "environ", 0, 1, 0,
1bbd0b84 1283 (SCM env),
1e6808ea
MG
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.")
1bbd0b84 1291#define FUNC_NAME s_scm_environ
0f2d19dd
JB
1292{
1293 if (SCM_UNBNDP (env))
1294 return scm_makfromstrs (-1, environ);
1295 else
1296 {
2a776823 1297 environ = scm_i_allocate_string_pointers (env);
0f2d19dd
JB
1298 return SCM_UNSPECIFIED;
1299 }
1300}
1bbd0b84 1301#undef FUNC_NAME
0f2d19dd 1302
9ee5fce4
MD
1303#ifdef L_tmpnam
1304
a1ec6916 1305SCM_DEFINE (scm_tmpnam, "tmpnam", 0, 0, 0,
1bbd0b84 1306 (),
1e6808ea
MG
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.")
1bbd0b84 1312#define FUNC_NAME s_scm_tmpnam
9ee5fce4
MD
1313{
1314 char name[L_tmpnam];
6d163216
GH
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);
cc95e00a 1321 return scm_from_locale_string (name);
9ee5fce4 1322}
0f981281 1323#undef FUNC_NAME
0f2d19dd 1324
1bbd0b84 1325#endif
1cc91f1b 1326
4f68365d
MV
1327#ifndef HAVE_MKSTEMP
1328extern int mkstemp (char *);
1329#endif
1330
6d163216
GH
1331SCM_DEFINE (scm_mkstemp, "mkstemp!", 1, 0, 0,
1332 (SCM tmpl),
23f2b9a3 1333 "Create a new unique file in the file system and return a new\n"
1e6808ea 1334 "buffered port open for reading and writing to the file.\n"
2c4cdcb0 1335 "\n"
1e6808ea 1336 "@var{tmpl} is a string specifying where the file should be\n"
23f2b9a3
KR
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"
2c4cdcb0 1340 "\n"
23f2b9a3
KR
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")
6d163216
GH
1352#define FUNC_NAME s_scm_mkstemp
1353{
1354 char *c_tmpl;
71978ac9 1355 int rv;
6d163216 1356
661ae7ab 1357 scm_dynwind_begin (0);
892065da
MV
1358
1359 c_tmpl = scm_to_locale_string (tmpl);
661ae7ab 1360 scm_dynwind_free (c_tmpl);
892065da 1361
6d163216
GH
1362 SCM_SYSCALL (rv = mkstemp (c_tmpl));
1363 if (rv == -1)
1364 SCM_SYSERROR;
892065da
MV
1365
1366 scm_substring_move_x (scm_from_locale_string (c_tmpl),
1367 SCM_INUM0, scm_string_length (tmpl),
1368 tmpl, SCM_INUM0);
1369
661ae7ab 1370 scm_dynwind_end ();
6d163216
GH
1371 return scm_fdes_to_port (rv, "w+", tmpl);
1372}
1373#undef FUNC_NAME
1374
06bfe276
AW
1375SCM_DEFINE (scm_utime, "utime", 1, 5, 0,
1376 (SCM pathname, SCM actime, SCM modtime, SCM actimens, SCM modtimens,
1377 SCM flags),
1e6808ea
MG
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"
06bfe276
AW
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"
1e6808ea 1387 "@lisp\n"
b380b885 1388 "(utime \"foo\" (- (current-time) 3600))\n"
1e6808ea
MG
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.")
1bbd0b84 1392#define FUNC_NAME s_scm_utime
0f2d19dd
JB
1393{
1394 int rv;
06bfe276
AW
1395 time_t atim_sec, mtim_sec;
1396 long atim_nsec, mtim_nsec;
1397 int f;
1398
0f2d19dd 1399 if (SCM_UNBNDP (actime))
06bfe276 1400 {
adfb4284 1401#ifdef HAVE_UTIMENSAT
06bfe276
AW
1402 atim_sec = 0;
1403 atim_nsec = UTIME_NOW;
1404#else
1405 SCM_SYSCALL (time (&atim_sec));
1406 atim_nsec = 0;
1407#endif
1408 }
0f2d19dd 1409 else
06bfe276
AW
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
0f2d19dd 1418 if (SCM_UNBNDP (modtime))
06bfe276 1419 {
adfb4284 1420#ifdef HAVE_UTIMENSAT
06bfe276
AW
1421 mtim_sec = 0;
1422 mtim_nsec = UTIME_NOW;
1423#else
1424 SCM_SYSCALL (time (&mtim_sec));
1425 mtim_nsec = 0;
1426#endif
1427 }
0f2d19dd 1428 else
06bfe276
AW
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
adfb4284 1442#ifdef HAVE_UTIMENSAT
06bfe276
AW
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,
adfb4284 1451 rv = utimensat (AT_FDCWD, c_pathname, times, f));
06bfe276
AW
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
0f2d19dd 1463
02b754d3 1464 if (rv != 0)
1bbd0b84 1465 SCM_SYSERROR;
02b754d3 1466 return SCM_UNSPECIFIED;
0f2d19dd 1467}
1bbd0b84 1468#undef FUNC_NAME
0f2d19dd 1469
a1ec6916 1470SCM_DEFINE (scm_access, "access?", 2, 0, 0,
1bbd0b84 1471 (SCM path, SCM how),
20e0b166
KR
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"
1e6808ea 1476 "\n"
20e0b166
KR
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"
1e6808ea 1479 "\n"
b380b885 1480 "@defvar R_OK\n"
20e0b166 1481 "Test for read permission.\n"
b380b885
MD
1482 "@end defvar\n"
1483 "@defvar W_OK\n"
20e0b166 1484 "Test for write permission.\n"
b380b885
MD
1485 "@end defvar\n"
1486 "@defvar X_OK\n"
20e0b166 1487 "Test for execute permission.\n"
b380b885
MD
1488 "@end defvar\n"
1489 "@defvar F_OK\n"
20e0b166
KR
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.")
1bbd0b84 1512#define FUNC_NAME s_scm_access
0f2d19dd
JB
1513{
1514 int rv;
1515
f015614a
MV
1516 WITH_STRING (path, c_path,
1517 rv = access (c_path, scm_to_int (how)));
7888309b 1518 return scm_from_bool (!rv);
0f2d19dd 1519}
1bbd0b84 1520#undef FUNC_NAME
0f2d19dd 1521
a1ec6916 1522SCM_DEFINE (scm_getpid, "getpid", 0, 0, 0,
1bbd0b84 1523 (),
1e6808ea 1524 "Return an integer representing the current process ID.")
1bbd0b84 1525#define FUNC_NAME s_scm_getpid
0f2d19dd 1526{
e11e83f3 1527 return scm_from_ulong (getpid ());
0f2d19dd 1528}
1bbd0b84 1529#undef FUNC_NAME
0f2d19dd 1530
a1ec6916 1531SCM_DEFINE (scm_putenv, "putenv", 1, 0, 0,
1bbd0b84 1532 (SCM str),
b380b885
MD
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.")
1bbd0b84 1542#define FUNC_NAME s_scm_putenv
0f2d19dd 1543{
f158788f 1544 int rv;
f015614a 1545 char *c_str = scm_to_locale_string (str);
002409fe 1546
3731192f 1547 /* Leave C_STR in the environment. */
fcc5d734 1548
3731192f
LC
1549 /* Gnulib's `putenv' module honors the semantics described above. */
1550 rv = putenv (c_str);
1551 if (rv < 0)
1552 SCM_SYSERROR;
f015614a 1553
f93ddd39 1554 return SCM_UNSPECIFIED;
0f2d19dd 1555}
1bbd0b84 1556#undef FUNC_NAME
0f2d19dd 1557
b89c4943 1558/* This mutex is used to serialize invocations of `setlocale ()' on non-GNU
a2f00b9b
LC
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. */
1562scm_i_pthread_mutex_t scm_i_locale_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER;
b89c4943 1563
f25f761d 1564#ifdef HAVE_SETLOCALE
b89c4943 1565
a1ec6916 1566SCM_DEFINE (scm_setlocale, "setlocale", 1, 1, 0,
1bbd0b84 1567 (SCM category, SCM locale),
1e6808ea
MG
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"
889975e5
MG
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")
1bbd0b84 1581#define FUNC_NAME s_scm_setlocale
0f2d19dd 1582{
a2f00b9b 1583 int c_category;
0f2d19dd
JB
1584 char *clocale;
1585 char *rv;
889975e5 1586 const char *enc;
0f2d19dd 1587
661ae7ab 1588 scm_dynwind_begin (0);
f015614a 1589
0f2d19dd
JB
1590 if (SCM_UNBNDP (locale))
1591 {
1592 clocale = NULL;
1593 }
1594 else
1595 {
f015614a 1596 clocale = scm_to_locale_string (locale);
661ae7ab 1597 scm_dynwind_free (clocale);
0f2d19dd
JB
1598 }
1599
a2f00b9b
LC
1600 c_category = scm_i_to_lc_category (category, 1);
1601
b89c4943 1602 scm_i_pthread_mutex_lock (&scm_i_locale_mutex);
a2f00b9b 1603 rv = setlocale (c_category, clocale);
b89c4943 1604 scm_i_pthread_mutex_unlock (&scm_i_locale_mutex);
b89c4943 1605
02b754d3 1606 if (rv == NULL)
41b74b7d
KR
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 }
f015614a 1614
889975e5
MG
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);
a17d2654 1622
661ae7ab 1623 scm_dynwind_end ();
f015614a 1624 return scm_from_locale_string (rv);
0f2d19dd 1625}
1bbd0b84 1626#undef FUNC_NAME
f25f761d 1627#endif /* HAVE_SETLOCALE */
0f2d19dd 1628
f25f761d 1629#ifdef HAVE_MKNOD
a1ec6916 1630SCM_DEFINE (scm_mknod, "mknod", 4, 0, 0,
1bbd0b84 1631 (SCM path, SCM type, SCM perms, SCM dev),
b380b885
MD
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"
1e6808ea 1641 "@lisp\n"
09831f94 1642 "(mknod \"/dev/fd0\" 'block-special #o660 (+ (* 2 256) 2))\n"
1e6808ea 1643 "@end lisp\n\n"
a3c8b9fc 1644 "The return value is unspecified.")
1bbd0b84 1645#define FUNC_NAME s_scm_mknod
0f2d19dd 1646{
0f2d19dd 1647 int val;
cc95e00a 1648 const char *p;
82a76bdf 1649 int ctype = 0;
19468eff 1650
a6d9e5ab 1651 SCM_VALIDATE_STRING (1, path);
34d19ef6 1652 SCM_VALIDATE_SYMBOL (2, type);
19468eff 1653
cc95e00a 1654 p = scm_i_symbol_chars (type);
19468eff
GH
1655 if (strcmp (p, "regular") == 0)
1656 ctype = S_IFREG;
1657 else if (strcmp (p, "directory") == 0)
1658 ctype = S_IFDIR;
23f2b9a3
KR
1659#ifdef S_IFLNK
1660 /* systems without symlinks probably don't have S_IFLNK defined */
19468eff
GH
1661 else if (strcmp (p, "symlink") == 0)
1662 ctype = S_IFLNK;
23f2b9a3 1663#endif
19468eff
GH
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;
e655d034 1670#ifdef S_IFSOCK
19468eff
GH
1671 else if (strcmp (p, "socket") == 0)
1672 ctype = S_IFSOCK;
e655d034 1673#endif
19468eff 1674 else
34d19ef6 1675 SCM_OUT_OF_RANGE (2, type);
19468eff 1676
f015614a
MV
1677 STRING_SYSCALL (path, c_path,
1678 val = mknod (c_path,
1679 ctype | scm_to_int (perms),
1680 scm_to_int (dev)));
02b754d3 1681 if (val != 0)
1bbd0b84 1682 SCM_SYSERROR;
02b754d3 1683 return SCM_UNSPECIFIED;
0f2d19dd 1684}
1bbd0b84 1685#undef FUNC_NAME
f25f761d 1686#endif /* HAVE_MKNOD */
0f2d19dd 1687
f25f761d 1688#ifdef HAVE_NICE
a1ec6916 1689SCM_DEFINE (scm_nice, "nice", 1, 0, 0,
1bbd0b84 1690 (SCM incr),
b380b885
MD
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.")
1bbd0b84 1694#define FUNC_NAME s_scm_nice
0f2d19dd 1695{
634aa8de
LC
1696 int nice_value;
1697
f1c82f55
KR
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;
634aa8de 1701 nice_value = nice (scm_to_int (incr));
f1c82f55 1702 if (errno != 0)
1bbd0b84 1703 SCM_SYSERROR;
634aa8de 1704
02b754d3 1705 return SCM_UNSPECIFIED;
0f2d19dd 1706}
1bbd0b84 1707#undef FUNC_NAME
f25f761d 1708#endif /* HAVE_NICE */
0f2d19dd 1709
f25f761d 1710#ifdef HAVE_SYNC
a1ec6916 1711SCM_DEFINE (scm_sync, "sync", 0, 0, 0,
1bbd0b84 1712 (),
b380b885
MD
1713 "Flush the operating system disk buffers.\n"
1714 "The return value is unspecified.")
1bbd0b84 1715#define FUNC_NAME s_scm_sync
0f2d19dd 1716{
0f2d19dd 1717 sync();
127ec750 1718 return SCM_UNSPECIFIED;
0f2d19dd 1719}
1bbd0b84 1720#undef FUNC_NAME
f25f761d 1721#endif /* HAVE_SYNC */
0f2d19dd 1722
33bea692
KR
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
b9a7b725 1741#if HAVE_CRYPT
33bea692 1742SCM_DEFINE (scm_crypt, "crypt", 2, 0, 0,
94e6d793
MG
1743 (SCM key, SCM salt),
1744 "Encrypt @var{key} using @var{salt} as the salt value to the\n"
9401323e 1745 "crypt(3) library call.")
94e6d793
MG
1746#define FUNC_NAME s_scm_crypt
1747{
33bea692 1748 SCM ret;
23d72566 1749 char *c_key, *c_salt, *c_ret;
94e6d793 1750
661ae7ab
MV
1751 scm_dynwind_begin (0);
1752 scm_i_dynwind_pthread_mutex_lock (&scm_i_misc_mutex);
33bea692 1753
f015614a 1754 c_key = scm_to_locale_string (key);
661ae7ab 1755 scm_dynwind_free (c_key);
f015614a 1756 c_salt = scm_to_locale_string (salt);
661ae7ab 1757 scm_dynwind_free (c_salt);
f015614a 1758
23d72566
KR
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;
33bea692 1765
23d72566 1766 ret = scm_from_locale_string (c_ret);
661ae7ab 1767 scm_dynwind_end ();
33bea692 1768 return ret;
94e6d793
MG
1769}
1770#undef FUNC_NAME
b9a7b725 1771#endif /* HAVE_CRYPT */
94e6d793
MG
1772
1773#if HAVE_CHROOT
1774SCM_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{
f015614a 1783 int rv;
94e6d793 1784
f015614a
MV
1785 WITH_STRING (path, c_path,
1786 rv = chroot (c_path));
1787 if (rv == -1)
94e6d793
MG
1788 SCM_SYSERROR;
1789 return SCM_UNSPECIFIED;
1790}
1791#undef FUNC_NAME
1792#endif /* HAVE_CHROOT */
1793
7beabedb
MG
1794
1795#ifdef __MINGW32__
1796/* Wrapper function to supplying `getlogin()' under Windows. */
1797static 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
4f68365d 1809#if defined (HAVE_GETLOGIN) || defined (__MINGW32__)
94e6d793
MG
1810SCM_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;
cc95e00a 1822 return scm_from_locale_string (p);
94e6d793
MG
1823}
1824#undef FUNC_NAME
1825#endif /* HAVE_GETLOGIN */
1826
1827#if HAVE_CUSERID
5f380d71
LC
1828
1829# if !HAVE_DECL_CUSERID
1830extern char *cuserid (char *);
1831# endif
1832
94e6d793
MG
1833SCM_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{
1b317eb1 1840 char buf[L_cuserid];
94e6d793
MG
1841 char * p;
1842
1b317eb1 1843 p = cuserid (buf);
94e6d793
MG
1844 if (!p || !*p)
1845 return SCM_BOOL_F;
cc95e00a 1846 return scm_from_locale_string (p);
94e6d793
MG
1847}
1848#undef FUNC_NAME
1849#endif /* HAVE_CUSERID */
1850
1851#if HAVE_GETPRIORITY
1852SCM_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
a55c2b68
MV
1868 cwhich = scm_to_int (which);
1869 cwho = scm_to_int (who);
94e6d793
MG
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;
a55c2b68 1877 return scm_from_int (ret);
94e6d793
MG
1878}
1879#undef FUNC_NAME
1880#endif /* HAVE_GETPRIORITY */
1881
1882#if HAVE_SETPRIORITY
1883SCM_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
a55c2b68
MV
1902 cwhich = scm_to_int (which);
1903 cwho = scm_to_int (who);
1904 cprio = scm_to_int (prio);
94e6d793
MG
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
1914SCM_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);
94e6d793 1929
f015614a
MV
1930 WITH_STRING (prompt, c_prompt,
1931 p = getpass(c_prompt));
1932 passwd = scm_from_locale_string (p);
94e6d793
MG
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
94e6d793
MG
1942SCM_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"
0b91f1db
KR
1946 "\n"
1947 "@defvar LOCK_SH\n"
94e6d793
MG
1948 "Shared lock. More than one process may hold a shared lock\n"
1949 "for a given file at a given time.\n"
0b91f1db
KR
1950 "@end defvar\n"
1951 "@defvar LOCK_EX\n"
94e6d793
MG
1952 "Exclusive lock. Only one process may hold an exclusive lock\n"
1953 "for a given file at a given time.\n"
0b91f1db
KR
1954 "@end defvar\n"
1955 "@defvar LOCK_UN\n"
94e6d793 1956 "Unlock the file.\n"
0b91f1db
KR
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"
94e6d793 1964 "The return value is not specified. @var{file} may be an open\n"
0b91f1db
KR
1965 "file descriptor or an open file descriptor port.\n"
1966 "\n"
1967 "Note that @code{flock} does not lock files across NFS.")
94e6d793
MG
1968#define FUNC_NAME s_scm_flock
1969{
a55c2b68 1970 int fdes;
94e6d793 1971
a55c2b68
MV
1972 if (scm_is_integer (file))
1973 fdes = scm_to_int (file);
94e6d793
MG
1974 else
1975 {
1976 SCM_VALIDATE_OPFPORT (2, file);
1977
1978 fdes = SCM_FPORT_FDES (file);
1979 }
a55c2b68 1980 if (flock (fdes, scm_to_int (operation)) == -1)
94e6d793
MG
1981 SCM_SYSERROR;
1982 return SCM_UNSPECIFIED;
1983}
1984#undef FUNC_NAME
94e6d793
MG
1985
1986#if HAVE_SETHOSTNAME
1987SCM_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{
f015614a 1994 int rv;
94e6d793 1995
f015614a
MV
1996 WITH_STRING (name, c_name,
1997 rv = sethostname (c_name, strlen(c_name)));
1998 if (rv == -1)
94e6d793
MG
1999 SCM_SYSERROR;
2000 return SCM_UNSPECIFIED;
2001}
2002#undef FUNC_NAME
2003#endif /* HAVE_SETHOSTNAME */
2004
b28f5b3c 2005
94e6d793
MG
2006#if HAVE_GETHOSTNAME
2007SCM_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{
b28f5b3c
DH
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
661ae7ab
MV
2020 scm_dynwind_begin (0);
2021 scm_dynwind_unwind_handler (free, p, 0);
b28f5b3c
DH
2022
2023#else
94e6d793 2024
0eaf1055 2025 /* Default 256 is for Solaris, under Linux ENAMETOOLONG is returned if not
b28f5b3c
DH
2026 * large enough. SUSv2 specifies 255 maximum too, apparently. */
2027 int len = 256;
2028 int res;
2029 char *p;
0eaf1055 2030
b28f5b3c 2031# if HAVE_SYSCONF && defined (_SC_HOST_NAME_MAX)
0eaf1055
KR
2032
2033 /* POSIX specifies the HOST_NAME_MAX system parameter for the max size,
b28f5b3c
DH
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. */
0eaf1055 2037 {
b28f5b3c 2038 const long int n = sysconf (_SC_HOST_NAME_MAX);
0eaf1055
KR
2039 if (n != -1L)
2040 len = n;
2041 }
b28f5b3c
DH
2042
2043# endif
2044
2045 p = scm_malloc (len);
2046
661ae7ab
MV
2047 scm_dynwind_begin (0);
2048 scm_dynwind_unwind_handler (free, p, 0);
0eaf1055 2049
94e6d793
MG
2050 res = gethostname (p, len);
2051 while (res == -1 && errno == ENAMETOOLONG)
2052 {
94e6d793 2053 len *= 2;
b28f5b3c
DH
2054
2055 /* scm_realloc may throw an exception. */
2056 p = scm_realloc (p, len);
94e6d793
MG
2057 res = gethostname (p, len);
2058 }
b28f5b3c
DH
2059
2060#endif
2061
94e6d793
MG
2062 if (res == -1)
2063 {
b28f5b3c
DH
2064 const int save_errno = errno;
2065
2b829bbb 2066 /* No guile exceptions can occur before we have freed p's memory. */
661ae7ab 2067 scm_dynwind_end ();
4c9419ac 2068 free (p);
b28f5b3c 2069
22865124 2070 errno = save_errno;
94e6d793
MG
2071 SCM_SYSERROR;
2072 }
b28f5b3c
DH
2073 else
2074 {
cc95e00a
MV
2075 /* scm_from_locale_string may throw an exception. */
2076 const SCM name = scm_from_locale_string (p);
b28f5b3c 2077
2b829bbb 2078 /* No guile exceptions can occur before we have freed p's memory. */
661ae7ab 2079 scm_dynwind_end ();
b28f5b3c
DH
2080 free (p);
2081
2082 return name;
2083 }
94e6d793
MG
2084}
2085#undef FUNC_NAME
2086#endif /* HAVE_GETHOSTNAME */
2087
b28f5b3c 2088
b89c4943 2089void
0f2d19dd 2090scm_init_posix ()
0f2d19dd
JB
2091{
2092 scm_add_feature ("posix");
2093#ifdef HAVE_GETEUID
2094 scm_add_feature ("EIDs");
2095#endif
2096#ifdef WAIT_ANY
e11e83f3 2097 scm_c_define ("WAIT_ANY", scm_from_int (WAIT_ANY));
0f2d19dd
JB
2098#endif
2099#ifdef WAIT_MYPGRP
e11e83f3 2100 scm_c_define ("WAIT_MYPGRP", scm_from_int (WAIT_MYPGRP));
0f2d19dd
JB
2101#endif
2102#ifdef WNOHANG
e11e83f3 2103 scm_c_define ("WNOHANG", scm_from_int (WNOHANG));
0f2d19dd
JB
2104#endif
2105#ifdef WUNTRACED
e11e83f3 2106 scm_c_define ("WUNTRACED", scm_from_int (WUNTRACED));
0f2d19dd
JB
2107#endif
2108
0f2d19dd 2109 /* access() symbols. */
e11e83f3
MV
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));
0f2d19dd
JB
2114
2115#ifdef LC_COLLATE
e11e83f3 2116 scm_c_define ("LC_COLLATE", scm_from_int (LC_COLLATE));
0f2d19dd
JB
2117#endif
2118#ifdef LC_CTYPE
e11e83f3 2119 scm_c_define ("LC_CTYPE", scm_from_int (LC_CTYPE));
0f2d19dd
JB
2120#endif
2121#ifdef LC_MONETARY
e11e83f3 2122 scm_c_define ("LC_MONETARY", scm_from_int (LC_MONETARY));
0f2d19dd
JB
2123#endif
2124#ifdef LC_NUMERIC
e11e83f3 2125 scm_c_define ("LC_NUMERIC", scm_from_int (LC_NUMERIC));
0f2d19dd
JB
2126#endif
2127#ifdef LC_TIME
e11e83f3 2128 scm_c_define ("LC_TIME", scm_from_int (LC_TIME));
0f2d19dd
JB
2129#endif
2130#ifdef LC_MESSAGES
e11e83f3 2131 scm_c_define ("LC_MESSAGES", scm_from_int (LC_MESSAGES));
0f2d19dd
JB
2132#endif
2133#ifdef LC_ALL
e11e83f3 2134 scm_c_define ("LC_ALL", scm_from_int (LC_ALL));
0f2d19dd 2135#endif
9361f762
MV
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
bd9e24b3 2154#ifdef PIPE_BUF
b9bd8526 2155 scm_c_define ("PIPE_BUF", scm_from_long (PIPE_BUF));
bd9e24b3
GH
2156#endif
2157
94e6d793 2158#ifdef PRIO_PROCESS
e11e83f3 2159 scm_c_define ("PRIO_PROCESS", scm_from_int (PRIO_PROCESS));
94e6d793
MG
2160#endif
2161#ifdef PRIO_PGRP
e11e83f3 2162 scm_c_define ("PRIO_PGRP", scm_from_int (PRIO_PGRP));
94e6d793
MG
2163#endif
2164#ifdef PRIO_USER
e11e83f3 2165 scm_c_define ("PRIO_USER", scm_from_int (PRIO_USER));
94e6d793
MG
2166#endif
2167
2168#ifdef LOCK_SH
e11e83f3 2169 scm_c_define ("LOCK_SH", scm_from_int (LOCK_SH));
94e6d793
MG
2170#endif
2171#ifdef LOCK_EX
e11e83f3 2172 scm_c_define ("LOCK_EX", scm_from_int (LOCK_EX));
94e6d793
MG
2173#endif
2174#ifdef LOCK_UN
e11e83f3 2175 scm_c_define ("LOCK_UN", scm_from_int (LOCK_UN));
94e6d793
MG
2176#endif
2177#ifdef LOCK_NB
e11e83f3 2178 scm_c_define ("LOCK_NB", scm_from_int (LOCK_NB));
94e6d793
MG
2179#endif
2180
a0599745
MD
2181#include "libguile/cpp_sig_symbols.c"
2182#include "libguile/posix.x"
0f2d19dd 2183}
89e00824
ML
2184
2185/*
2186 Local Variables:
2187 c-file-style: "gnu"
2188 End:
2189*/