mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 13:35:47 +00:00
Add a shared "port" directory for POSIX functions needed by multiple host tools (getopt/mkstemps) and import the one and only getopt from glibc.
This finally fixes our duplicated getopt functions from different sources and gives us an up to date and the most compatible implementation. isohybrid actually relies on a glibc-specific getopt behavior that we previously hacked into the reactos_support_code.c implementation derived from BSD/mingw-w64. widl also needs getopt and previously used an even older BSD-derived code.
This commit is contained in:
parent
c02257ef57
commit
2c11c41115
18 changed files with 1305 additions and 1615 deletions
142
sdk/tools/port/mkstemps.c
Normal file
142
sdk/tools/port/mkstemps.c
Normal file
|
@ -0,0 +1,142 @@
|
|||
/* Copyright (C) 1991, 1992, 1996, 1998 Free Software Foundation, Inc.
|
||||
This file is derived from mkstemp.c from the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#include <process.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
/* We need to provide a type for gcc_uint64_t. */
|
||||
#ifdef __GNUC__
|
||||
__extension__ typedef unsigned long long gcc_uint64_t;
|
||||
#else
|
||||
typedef unsigned long gcc_uint64_t;
|
||||
#endif
|
||||
|
||||
#ifndef TMP_MAX
|
||||
#define TMP_MAX 16384
|
||||
#endif
|
||||
|
||||
/* if O_BINARY is not defined, the system is probably not expecting any such flag */
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@deftypefn Replacement int mkstemps (char *@var{template}, int @var{suffix_len})
|
||||
|
||||
Generate a unique temporary file name from @var{template}.
|
||||
@var{template} has the form:
|
||||
|
||||
@example
|
||||
@var{path}/ccXXXXXX@var{suffix}
|
||||
@end example
|
||||
|
||||
@var{suffix_len} tells us how long @var{suffix} is (it can be zero
|
||||
length). The last six characters of @var{template} before @var{suffix}
|
||||
must be @samp{XXXXXX}; they are replaced with a string that makes the
|
||||
filename unique. Returns a file descriptor open on the file for
|
||||
reading and writing.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
*/
|
||||
|
||||
int
|
||||
mkstemps (
|
||||
char *template,
|
||||
int suffix_len)
|
||||
{
|
||||
static const char letters[]
|
||||
= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
static gcc_uint64_t value;
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
struct timeval tv;
|
||||
#endif
|
||||
char *XXXXXX;
|
||||
size_t len;
|
||||
int count;
|
||||
|
||||
len = strlen (template);
|
||||
|
||||
if ((int) len < 6 + suffix_len
|
||||
|| strncmp (&template[len - 6 - suffix_len], "XXXXXX", 6))
|
||||
{
|
||||
printf("wrong parameter\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
XXXXXX = &template[len - 6 - suffix_len];
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
/* Get some more or less random data. */
|
||||
gettimeofday (&tv, NULL);
|
||||
value += ((gcc_uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid ();
|
||||
#else
|
||||
value += getpid ();
|
||||
#endif
|
||||
|
||||
for (count = 0; count < TMP_MAX; ++count)
|
||||
{
|
||||
gcc_uint64_t v = value;
|
||||
int fd;
|
||||
|
||||
/* Fill in the random bits. */
|
||||
XXXXXX[0] = letters[v % 62];
|
||||
v /= 62;
|
||||
XXXXXX[1] = letters[v % 62];
|
||||
v /= 62;
|
||||
XXXXXX[2] = letters[v % 62];
|
||||
v /= 62;
|
||||
XXXXXX[3] = letters[v % 62];
|
||||
v /= 62;
|
||||
XXXXXX[4] = letters[v % 62];
|
||||
v /= 62;
|
||||
XXXXXX[5] = letters[v % 62];
|
||||
|
||||
#ifdef VMS
|
||||
fd = open (template, O_RDWR|O_CREAT|O_EXCL, 0600, "fop=tmd");
|
||||
#else
|
||||
fd = open (template, O_RDWR|O_CREAT|O_EXCL|O_BINARY, 0600);
|
||||
#endif
|
||||
if (fd >= 0)
|
||||
/* The file does not exist. */
|
||||
return fd;
|
||||
|
||||
/* This is a random value. It is only necessary that the next
|
||||
TMP_MAX values generated by adding 7777 to VALUE are different
|
||||
with (module 2^32). */
|
||||
value += 7777;
|
||||
}
|
||||
|
||||
/* We return the null string if we can't find a unique file name. */
|
||||
template[0] = '\0';
|
||||
return -1;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue