1
1
/* sysutils.c - system helpers
2
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
2
* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004,
3
* 2007, 2008 Free Software Foundation, Inc.
4
5
* This file is part of GnuPG.
6
7
* GnuPG is free software; you can redistribute it and/or modify
7
8
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* the Free Software Foundation; either version 3 of the License, or
9
10
* (at your option) any later version.
11
12
* GnuPG is distributed in the hope that it will be useful,
14
15
* GNU General Public License for more details.
16
17
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18
* along with this program; if not, see <http://www.gnu.org/licenses/>.
21
21
#include <config.h>
23
#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth. */
23
29
#include <stdlib.h>
24
30
#include <string.h>
25
31
#include <unistd.h>
34
# include <sys/stat.h>
30
36
#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
31
#include <asm/sysinfo.h>
32
#include <asm/unistd.h>
37
# include <asm/sysinfo.h>
38
# include <asm/unistd.h>
34
40
#ifdef HAVE_SETRLIMIT
37
#include <sys/resource.h>
42
# include <sys/time.h>
43
# include <sys/resource.h>
45
#ifdef HAVE_W32_SYSTEM
46
# define WINVER 0x0500 /* Required for AllowSetForegroundWindow. */
42
57
#include "sysutils.h"
59
#define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
44
62
#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
45
63
#warning using trap_unaligned
251
/* Wrapper around the usual sleep fucntion. This one won't wake up
252
before the sleep time has really elapsed. When build with Pth it
253
merely calls pth_sleep and thus suspends only the current
256
gnupg_sleep (unsigned int seconds)
259
/* With Pth we force a regular sleep for seconds == 0 so that also
260
the process will give up its timeslot. */
263
# ifdef HAVE_W32_SYSTEM
271
/* Fixme: make sure that a sleep won't wake up to early. */
272
# ifdef HAVE_W32_SYSTEM
273
Sleep (seconds*1000);
281
/* This function is a NOP for POSIX systems but required under Windows
282
as the file handles as returned by OS calls (like CreateFile) are
283
different from the libc file descriptors (like open). This function
284
translates system file handles to libc file handles. FOR_WRITE
285
gives the direction of the handle. */
287
translate_sys2libc_fd (gnupg_fd_t fd, int for_write)
289
#ifdef HAVE_W32_SYSTEM
292
if (fd == GNUPG_INVALID_FD)
295
/* Note that _open_osfhandle is currently defined to take and return
297
x = _open_osfhandle ((long)fd, for_write ? 1 : 0);
299
log_error ("failed to translate osfhandle %p\n", (void *) fd);
301
#else /*!HAVE_W32_SYSTEM */
306
/* This is the same as translate_sys2libc_fd but takes an integer
307
which is assumed to be such an system handle. */
309
translate_sys2libc_fd_int (int fd, int for_write)
311
#ifdef HAVE_W32_SYSTEM
313
return fd; /* Do not do this for error, stdin, stdout, stderr. */
315
return translate_sys2libc_fd ((void*)fd, for_write);
323
/* Replacement for tmpfile(). This is required because the tmpfile
324
function of Windows' runtime library is broken, insecure, ignores
325
TMPDIR and so on. In addition we create a file with an inheritable
330
#ifdef HAVE_W32_SYSTEM
332
char buffer[MAX_PATH+7+12+1];
335
int pid = GetCurrentProcessId ();
338
SECURITY_ATTRIBUTES sec_attr;
340
memset (&sec_attr, 0, sizeof sec_attr );
341
sec_attr.nLength = sizeof sec_attr;
342
sec_attr.bInheritHandle = TRUE;
344
n = GetTempPath (MAX_PATH+1, buffer);
345
if (!n || n > MAX_PATH || strlen (buffer) > MAX_PATH)
350
p = buffer + strlen (buffer);
351
p = stpcpy (p, "_gnupg");
352
/* We try to create the directory but don't care about an error as
353
it may already exist and the CreateFile would throw an error
355
CreateDirectory (buffer, NULL);
358
for (attempts=0; attempts < 10; attempts++)
361
value = (GetTickCount () ^ ((pid<<16) & 0xffff0000));
362
for (i=0; i < 8; i++)
364
*p++ = tohex (((value >> 28) & 0x0f));
368
file = CreateFile (buffer,
369
GENERIC_READ | GENERIC_WRITE,
373
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
375
if (file != INVALID_HANDLE_VALUE)
378
int fd = _open_osfhandle ((long)file, 0);
384
fp = fdopen (fd, "w+b");
394
Sleep (1); /* One ms as this is the granularity of GetTickCount. */
398
#else /*!HAVE_W32_SYSTEM*/
400
#endif /*!HAVE_W32_SYSTEM*/
404
/* Make sure that the standard file descriptors are opened. Obviously
405
some folks close them before an exec and the next file we open will
406
get one of them assigned and thus any output (i.e. diagnostics) end
407
up in that file (e.g. the trustdb). Not actually a gpg problem as
408
this will hapen with almost all utilities when called in a wrong
409
way. However we try to minimize the damage here and raise
410
awareness of the problem.
412
Must be called before we open any files! */
414
gnupg_reopen_std (const char *pgmname)
416
#if defined(HAVE_STAT) && !defined(HAVE_W32_SYSTEM)
423
if (fstat (STDIN_FILENO, &statbuf) == -1 && errno ==EBADF)
425
if (open ("/dev/null",O_RDONLY) == STDIN_FILENO)
431
if (fstat (STDOUT_FILENO, &statbuf) == -1 && errno == EBADF)
433
if (open ("/dev/null",O_WRONLY) == STDOUT_FILENO)
439
if (fstat (STDERR_FILENO, &statbuf)==-1 && errno==EBADF)
441
if (open ("/dev/null", O_WRONLY) == STDERR_FILENO)
447
/* It's hard to log this sort of thing since the filehandle we would
448
complain to may be closed... */
451
else if (!did_stdout)
459
fprintf (complain, "%s: WARNING: standard input reopened\n", pgmname);
461
fprintf (complain, "%s: WARNING: standard output reopened\n", pgmname);
463
fprintf (complain, "%s: WARNING: standard error reopened\n", pgmname);
465
if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
466
fprintf(complain,"%s: fatal: unable to reopen standard input,"
467
" output, or error\n", pgmname);
470
if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2)
472
#endif /* HAVE_STAT && !HAVE_W32_SYSTEM */
476
/* Hack required for Windows. */
478
gnupg_allow_set_foregound_window (pid_t pid)
480
if (!pid || pid == (pid_t)(-1))
481
log_info ("%s called with invalid pid %lu\n",
482
"gnupg_allow_set_foregound_window", (unsigned long)pid);
483
#ifdef HAVE_W32_SYSTEM
484
else if (!AllowSetForegroundWindow (pid))
485
log_info ("AllowSetForegroundWindow(%lu) failed: %s\n",
486
(unsigned long)pid, w32_strerror (-1));