diff options
Diffstat (limited to 'common/sysutils.c')
-rw-r--r-- | common/sysutils.c | 121 |
1 files changed, 114 insertions, 7 deletions
diff --git a/common/sysutils.c b/common/sysutils.c index f8e6d86fc..fc60af49c 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -558,17 +558,15 @@ translate_sys2libc_fd (gnupg_fd_t fd, int for_write) } /* This is the same as translate_sys2libc_fd but takes an integer - which is assumed to be such an system handle. On WindowsCE the - passed FD is a rendezvous ID and the function finishes the pipe - creation. */ + which is assumed to be such an system handle. */ int translate_sys2libc_fd_int (int fd, int for_write) { #ifdef HAVE_W32_SYSTEM if (fd <= 2) - return fd; /* Do not do this for error, stdin, stdout, stderr. */ + return fd; /* Do not do this for stdin, stdout, and stderr. */ - return translate_sys2libc_fd ((void*)fd, for_write); + return translate_sys2libc_fd ((void*)(intptr_t)fd, for_write); #else (void)for_write; return fd; @@ -576,6 +574,70 @@ translate_sys2libc_fd_int (int fd, int for_write) } +/* + * Parse the string representation of a file reference (file handle on + * Windows or file descriptor on POSIX) in FDSTR. The string + * representation may be either of folllowing: + + * (1) 0, 1, or 2 which means stdin, stdout, and stderr, respectively. + * (2) Integer representation (by %d of printf). + * (3) Hex representation which starts as "0x". + * + * Then, fill R_SYSHD, according to the value of a file reference. + * + */ +gpg_error_t +gnupg_parse_fdstr (const char *fdstr, es_syshd_t *r_syshd) +{ + int fd = -1; +#ifdef HAVE_W32_SYSTEM + gnupg_fd_t hd; + char *endptr; + int base; + + if (!strcmp (fdstr, "0")) + fd = 0; + else if (!strcmp (fdstr, "1")) + fd = 1; + else if (!strcmp (fdstr, "2")) + fd = 2; + + if (fd >= 0) + { + r_syshd->type = ES_SYSHD_FD; + r_syshd->u.fd = fd; + return 0; + } + + if (!strncmp (fdstr, "0x", 2)) + { + base = 16; + fdstr += 2; + } + else + base = 10; + + gpg_err_set_errno (0); +#ifdef _WIN64 + hd = (gnupg_fd_t)strtoll (fdstr, &endptr, base); +#else + hd = (gnupg_fd_t)strtol (fdstr, &endptr, base); +#endif + if (errno != 0 || endptr == fdstr || *endptr != '\0') + return gpg_error (GPG_ERR_INV_ARG); + + r_syshd->type = ES_SYSHD_HANDLE; + r_syshd->u.handle = hd; + return 0; +#else + fd = atoi (fdstr); + r_syshd->type = ES_SYSHD_FD; + r_syshd->u.fd = fd; + return 0; +#endif +} + + /* Check whether FNAME has the form "-&nnnn", where N is a non-zero * number. Returns this number or -1 if it is not the case. If the * caller wants to use the file descriptor for writing FOR_WRITE shall @@ -593,8 +655,27 @@ check_special_filename (const char *fname, int for_write, int notranslate) for (i=0; digitp (fname+i); i++ ) ; if (!fname[i]) - return notranslate? atoi (fname) - /**/ : translate_sys2libc_fd_int (atoi (fname), for_write); + { + if (notranslate) + return atoi (fname); + else + { + es_syshd_t syshd; + + if (gnupg_parse_fdstr (fname, &syshd)) + return -1; + +#ifdef HAVE_W32_SYSTEM + if (syshd.type == ES_SYSHD_FD) + return syshd.u.fd; + else + return translate_sys2libc_fd ((gnupg_fd_t)syshd.u.handle, for_write); +#else + (void)for_write; + return syshd.u.fd; +#endif + } + } } return -1; } @@ -1152,6 +1233,19 @@ gnupg_setenv (const char *name, const char *value, int overwrite) return setenv (name, value, overwrite); #else /*!HAVE_SETENV*/ if (! getenv (name) || overwrite) +#if defined(HAVE_W32_SYSTEM) && defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES) + { + int e = _putenv_s (name, value); + + if (e) + { + gpg_err_set_errno (e); + return -1; + } + else + return 0; + } +#else { char *buf; @@ -1169,6 +1263,7 @@ gnupg_setenv (const char *name, const char *value, int overwrite) # endif return putenv (buf); } +#endif /*!HAVE_W32_SYSTEM*/ return 0; #endif /*!HAVE_SETENV*/ } @@ -1193,6 +1288,18 @@ gnupg_unsetenv (const char *name) #ifdef HAVE_UNSETENV return unsetenv (name); +#elif defined(HAVE_W32_SYSTEM) && defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES) + { + int e = _putenv_s (name, ""); + + if (e) + { + gpg_err_set_errno (e); + return -1; + } + else + return 0; + } #else /*!HAVE_UNSETENV*/ { char *buf; |