* child_info.h: Add specific exec class.
* cygheap.h: New file. Contains declarations for cygwin heap.
* cygheap.cc: New file. Implements cygwin heap functions.
* dcrt0.cc (quoted): Simplify due to new method for passing arguments between
cygwin programs.
(alloc_stack_hard_way): Attempt to handle overlapped stack.
(dll_crt0_1): Move child_info processing here. Accomodate new method for
passing arguments between cygwin programs. Initialize cygwin heap. Establish
__argc and __argv variables.
(_dll_crt0): Move most of child_info processing to dll_crt0_1.
(cygwin_dll_init): Remove duplication.
* dtable.cc (dtable::extend): Allocate dtable using cygwin heap.
(dtable::build_fhandler): Ditto for fhandler type being constructed.
(dtable::dup_worker): Free new fhandler from cygwin heap on error.
(dtable::select_*): Don't assume that this == fdtab.
(dtable::linearize_fd_array): Delete.
(dtable::delinearize_fd_array): Delete.
(dtable::fixup_after_exec): New file.
(dtable::vfork_child_dup): Use cygwin heap.
(dtable::vfork_parent_restore): Ditto.
* dtable.h: Remove obsolete methods. Add new method.
* environ.cc (posify): Eliminate already_posix parameter and logic.
(envsize): New function.
(_addenv): Use envsize.
(environ_init): Accept an argument pointing to an existing environment list.
If supplied, allocate space for this in the the program's heap.
* fhandler.cc (fhandler_base::operator =): Move here from fhandler.h. Use
cygwin heap to allocate filenames.
(fhandler_base::set_name): Allocate/free names from cygwin heap.
(fhandler_base::linearize): Delete.
(fhandler_base::de_linearize): Delete.
(fhandler_base::operator delete): Free from cygwin heap.
(fhandler_base::~fhandler_base): Ditto.
* fhandler.h: Accomodate elimination of *linearize and other changes above.
* fhandler_console.cc (fhandler_console::fixup_after_exec): Rename from
de_linearize.
* heap.h: New file.
* fhandler_tty.cc (fhandler_tty_slave::fhandler_tty_slave): Use cygwin heap for
name. fhandler_tty::fixup_after_exec): Rename from de_linearize.
* fork.cc (fork): Call cygheap_fixup_in_child.
* heap.cc: Use declarations in heap.h.
* malloc.cc: Sprinkle assertions throughout to catch attempts to free/realloc
something from the cygwin heap.
* path.cc: Throughout, eliminate use of per-thread cache for cwd. Use cwd_*
functions rather than cwd_* variables to access cwd_win32 and cwd_posix.
(cwd_win32): New function.
(cwd_posix): New function.
(cwd_hash): New function.
(cwd_fixup_after_exec): New function.
* path.h: Accomodate path.cc changes.
* pinfo.cc (pinfo_init): Accept a pointer to an environment table. Pass this
to environ_init. Eliminate old 'title' tests.
* pinfo.h: Accomodate above change in argument.
* spawn.cc (struct av): New method for building argv list.
(av::unshift): New method.
(spawn_guts): Allocate everything that the child process needs in the cygwin
heap and pass a pointer to this to the child. Build argv list using new
method. Eliminate delinearize stuff.
* thread.h: Eliminate _cwd_win32 and _cwd_posix buffers.
* winsup.h: Eliminate obsolete functions. Add envsize() declaration.
+Sun Sep 3 00:07:32 2000 Christopher Faylor <cgf@cygnus.com>
+
+ * Makefile.in: Add cygheap.o.
+ * child_info.h: Add specific exec class.
+ * cygheap.h: New file. Contains declarations for cygwin heap.
+ * cygheap.cc: New file. Implements cygwin heap functions.
+ * dcrt0.cc (quoted): Simplify due to new method for passing arguments
+ between cygwin programs.
+ (alloc_stack_hard_way): Attempt to handle overlapped stack.
+ (dll_crt0_1): Move child_info processing here. Accomodate new method
+ for passing arguments between cygwin programs. Initialize cygwin heap.
+ Establish __argc and __argv variables.
+ (_dll_crt0): Move most of child_info processing to dll_crt0_1.
+ (cygwin_dll_init): Remove duplication.
+ * dtable.cc (dtable::extend): Allocate dtable using cygwin heap.
+ (dtable::build_fhandler): Ditto for fhandler type being constructed.
+ (dtable::dup_worker): Free new fhandler from cygwin heap on error.
+ (dtable::select_*): Don't assume that this == fdtab.
+ (dtable::linearize_fd_array): Delete.
+ (dtable::delinearize_fd_array): Delete.
+ (dtable::fixup_after_exec): New file.
+ (dtable::vfork_child_dup): Use cygwin heap.
+ (dtable::vfork_parent_restore): Ditto.
+ * dtable.h: Remove obsolete methods. Add new method.
+ * environ.cc (posify): Eliminate already_posix parameter and logic.
+ (envsize): New function.
+ (_addenv): Use envsize.
+ (environ_init): Accept an argument pointing to an existing environment
+ list. If supplied, allocate space for this in the the program's heap.
+ * fhandler.cc (fhandler_base::operator =): Move here from fhandler.h.
+ Use cygwin heap to allocate filenames.
+ (fhandler_base::set_name): Allocate/free names from cygwin heap.
+ (fhandler_base::linearize): Delete.
+ (fhandler_base::de_linearize): Delete.
+ (fhandler_base::operator delete): Free from cygwin heap.
+ (fhandler_base::~fhandler_base): Ditto.
+ * fhandler.h: Accomodate elimination of *linearize and other changes
+ above.
+ * fhandler_console.cc (fhandler_console::fixup_after_exec): Rename from
+ de_linearize.
+ * heap.h: New file.
+ * fhandler_tty.cc (fhandler_tty_slave::fhandler_tty_slave): Use cygwin
+ heap for name. fhandler_tty::fixup_after_exec): Rename from
+ de_linearize.
+ * fork.cc (fork): Call cygheap_fixup_in_child.
+ * heap.cc: Use declarations in heap.h.
+ * malloc.cc: Sprinkle assertions throughout to catch attempts to
+ free/realloc something from the cygwin heap.
+ * path.cc: Throughout, eliminate use of per-thread cache for cwd. Use
+ cwd_* functions rather than cwd_* variables to access cwd_win32 and
+ cwd_posix.
+ (cwd_win32): New function.
+ (cwd_posix): New function.
+ (cwd_hash): New function.
+ (cwd_fixup_after_exec): New function.
+ * path.h: Accomodate path.cc changes.
+ * pinfo.cc (pinfo_init): Accept a pointer to an environment table.
+ Pass this to environ_init. Eliminate old 'title' tests.
+ * pinfo.h: Accomodate above change in argument.
+ * spawn.cc (struct av): New method for building argv list.
+ (av::unshift): New method.
+ (spawn_guts): Allocate everything that the child process needs in the
+ cygwin heap and pass a pointer to this to the child. Build argv list
+ using new method. Eliminate delinearize stuff.
+ * thread.h: Eliminate _cwd_win32 and _cwd_posix buffers.
+ * winsup.h: Eliminate obsolete functions. Add envsize() declaration.
+
2000-09-02 Egor Duda <deo@logos-m.ru>
* Makefile.in: Remove "make check" support. It is now in
CC:=@CC@
# FIXME: Which is it, CC or CC_FOR_TARGET?
CC_FOR_TARGET:=$(CC)
-CFLAGS:=@CFLAGS@ -MD
+CFLAGS:=@CFLAGS@ -MD -fno-implement-inlines
CXXFLAGS:=@CXXFLAGS@
# For linking mount, etc. crt0.o isn't accessable in a fresh build.
DLL_IMPORTS:=$(w32api_lib)/libkernel32.a
-DLL_OFILES:=assert.o dcrt0.o debug.o delqueue.o dir.o dlfcn.o dll_init.o \
- dtable.o environ.o errno.o exceptions.o exec.o external.o fcntl.o \
- fhandler.o fhandler_console.o fhandler_floppy.o fhandler_random.o \
- fhandler_raw.o fhandler_serial.o fhandler_tape.o fhandler_termios.o \
- fhandler_tty.o fhandler_windows.o fhandler_zero.o fork.o glob.o grp.o \
- heap.o init.o ioctl.o localtime.o malloc.o mmap.o net.o ntea.o passwd.o \
- path.o pinfo.o pipe.o poll.o regexp.o regerror.o regsub.o registry.o \
- resource.o scandir.o security.o select.o shared.o signal.o sigproc.o \
- smallprint.o spawn.o strace.o strsep.o sync.o syscalls.o sysconf.o \
- syslog.o termios.o times.o tty.o uinfo.o uname.o wait.o window.o \
+DLL_OFILES:=assert.o cygheap.o dcrt0.o debug.o delqueue.o dir.o dlfcn.o \
+ dll_init.o dtable.o environ.o errno.o exceptions.o exec.o external.o \
+ fcntl.o fhandler.o fhandler_console.o fhandler_floppy.o \
+ fhandler_random.o fhandler_raw.o fhandler_serial.o fhandler_tape.o \
+ fhandler_termios.o fhandler_tty.o fhandler_windows.o fhandler_zero.o \
+ fork.o glob.o grp.o heap.o init.o ioctl.o localtime.o malloc.o mmap.o \
+ net.o ntea.o passwd.o path.o pinfo.o pipe.o poll.o regexp.o regerror.o \
+ regsub.o registry.o resource.o scandir.o security.o select.o shared.o \
+ signal.o sigproc.o smallprint.o spawn.o strace.o strsep.o sync.o \
+ syscalls.o sysconf.o syslog.o termios.o times.o tty.o uinfo.o uname.o \
+ wait.o window.o \
$(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MT_SAFE_OBJECTS)
GMON_OFILES:= gmon.o mcount.o profil.o
{
CloseHandle (h);
small_printf ("assertion \"%s\" failed: file \"%s\", line %d\n",
- failedexpr, file, line);
+ failedexpr, file, line);
}
- abort ();
+ abort (); // FIXME: Someday this should work.
/* NOTREACHED */
}
PROC_FORK = PROC_MAGIC + 1,
PROC_EXEC = PROC_MAGIC + 2,
PROC_SPAWN = PROC_MAGIC + 3,
- PROC_FORK1 = PROC_MAGIC + 4 // Newer versions provide stack
+ PROC_FORK1 = PROC_MAGIC + 4, // Newer versions provide stack
// location information
+ PROC_SPAWN1 = PROC_MAGIC + 5
};
#define PROC_MAGIC_MASK 0xff00f000
HANDLE shared_h;
HANDLE console_h;
HANDLE parent_alive; // handle of thread used to track children
- HANDLE myself_pinfo;
- ~child_info ()
- {
- if (myself_pinfo)
- CloseHandle (myself_pinfo);
- }
};
class child_info_fork: public child_info
void *stackbottom; // location of bottom of parent stack
};
+class fhandler_base;
+
+class cygheap_exec_info
+{
+public:
+ char *old_title;
+ fhandler_base **fds;
+ size_t nfds;
+ int argc;
+ char **argv;
+ char **environ;
+ HANDLE myself_pinfo;
+ char *cwd_posix;
+ char *cwd_win32;
+ DWORD cwd_hash;
+};
+
+class child_info_spawn: public child_info
+{
+public:
+ HANDLE parent;
+ void *cygheap;
+ void *cygheap_max;
+ cygheap_exec_info *moreinfo;
+
+ child_info_spawn (): parent (NULL), cygheap (NULL),
+ cygheap_max (NULL), moreinfo (NULL) {}
+ ~child_info_spawn ()
+ {
+ if (parent)
+ CloseHandle (parent);
+ if (moreinfo)
+ {
+ if (moreinfo->old_title)
+ cfree (moreinfo->old_title);
+ if (moreinfo->environ)
+ {
+ for (char **e = moreinfo->environ; *e; e++)
+ cfree (*e);
+ cfree (moreinfo->environ);
+ }
+ CloseHandle (moreinfo->myself_pinfo);
+ cfree (moreinfo);
+ }
+ }
+};
+
void __stdcall init_child_info (DWORD, child_info *, int, HANDLE);
extern child_info_fork *child_proc_info;
-
-/* non-NULL if this process is a child of a cygwin process */
-extern HANDLE parent_alive;
--- /dev/null
+/* cygheap.cc: Cygwin heap manager.
+
+ Copyright 2000 Cygnus Solutions.
+
+ This file is part of Cygwin.
+
+ This software is a copyrighted work licensed under the terms of the
+ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+ details. */
+
+#include "winsup.h"
+#include <errno.h>
+#include <fhandler.h>
+#include <assert.h>
+#include "cygheap.h"
+#include "heap.h"
+#include "cygerrno.h"
+
+#define HEAP_START ((void *) 0x12010000)
+inline static void
+init_cheap ()
+{
+ if (!VirtualAlloc (HEAP_START, CYGHEAPSIZE, MEM_RESERVE, PAGE_NOACCESS))
+ api_fatal ("Couldn't reserve space for child's heap, %E");
+ cygheap = cygheap_max = HEAP_START;
+}
+
+#define pagetrunc(x) ((void *) (((DWORD) (x)) & ~(4096 - 1)))
+static void *__stdcall
+_csbrk (int sbs)
+{
+ void *lastheap;
+ if (!cygheap)
+ init_cheap ();
+ lastheap = cygheap_max;
+ (char *) cygheap_max += sbs;
+ void *heapalign = (void *) pagetrunc (lastheap);
+ int needalloc = sbs && ((heapalign == lastheap) || heapalign != pagetrunc (cygheap_max));
+ if (needalloc && !VirtualAlloc (lastheap, (DWORD) sbs, MEM_COMMIT, PAGE_READWRITE))
+ api_fatal ("couldn't commit memory for cygwin heap, %E");
+
+ return lastheap;
+}
+
+/* Copyright (C) 1997, 2000 DJ Delorie */
+
+char *buckets[32] = {0};
+int bucket2size[32] = {0};
+
+static inline int
+size2bucket (int size)
+{
+ int rv = 0x1f;
+ int bit = ~0x10;
+ int i;
+
+ if (size < 4)
+ size = 4;
+ size = (size + 3) & ~3;
+
+ for (i = 0; i < 5; i++)
+ {
+ if (bucket2size[rv & bit] >= size)
+ rv &= bit;
+ bit >>= 1;
+ }
+ return rv;
+}
+
+static inline void
+init_buckets ()
+{
+ unsigned b;
+ for (b = 0; b < 32; b++)
+ bucket2size[b] = (1 << b);
+}
+
+static void *__stdcall
+_cmalloc (int size)
+{
+ char *rv;
+ int b;
+
+ if (bucket2size[0] == 0)
+ init_buckets ();
+
+ b = size2bucket (size);
+ if (buckets[b])
+ {
+ rv = buckets[b];
+ buckets[b] = *(char **) rv;
+ return rv;
+ }
+
+ size = bucket2size[b] + 4;
+ rv = (char *) _csbrk (size);
+
+ *(int *) rv = b;
+ rv += 4;
+ return rv;
+}
+
+static void __stdcall
+_cfree (void *ptr)
+{
+ int b = *(int *) ((char *) ptr - 4);
+ *(char **) ptr = buckets[b];
+ buckets[b] = (char *) ptr;
+}
+
+static void *__stdcall
+_crealloc (void *ptr, int size)
+{
+ char *newptr;
+ int oldsize = bucket2size[*(int *) ((char *) ptr - 4)];
+ if (size <= oldsize)
+ return ptr;
+ newptr = (char *) _cmalloc (size);
+ memcpy (newptr, ptr, oldsize);
+ _cfree (ptr);
+ return newptr;
+}
+
+/* End Copyright (C) 1997 DJ Delorie */
+
+void *cygheap = NULL;
+void *cygheap_max = NULL;
+
+#define sizeof_cygheap(n) ((n) + sizeof(cygheap_entry))
+
+struct cygheap_entry
+ {
+ cygheap_types type;
+ char data[0];
+ };
+
+#define N ((cygheap_entry *) NULL)
+#define tocygheap(s) ((cygheap_entry *) (((char *) (s)) - (int) (N->data)))
+
+void
+cygheap_init ()
+{
+ if (!cygheap)
+ init_cheap ();
+}
+
+extern "C" void __stdcall
+cygheap_fixup_in_child (HANDLE parent)
+{
+ DWORD m, n;
+ n = (DWORD) cygheap_max - (DWORD) cygheap;
+ if (!VirtualAlloc (cygheap, CYGHEAPSIZE, MEM_RESERVE, PAGE_NOACCESS))
+ api_fatal ("Couldn't reserve space for child's heap, %E");
+
+ if (!VirtualAlloc (cygheap, n, MEM_COMMIT, PAGE_READWRITE))
+ api_fatal ("Couldn't allocate space for child's heap %p, size %d, %E",
+ cygheap, n);
+ m = 0;
+ n = (DWORD) pagetrunc (n + 4095);
+ if (!ReadProcessMemory (parent, cygheap, cygheap, n, &m) ||
+ m != n)
+ api_fatal ("Couldn't read parent's cygwin heap %d bytes != %d, %E",
+ n, m);
+}
+
+static void *__stdcall
+creturn (cygheap_types x, cygheap_entry * c, int len)
+{
+ if (!c)
+ {
+ __seterrno ();
+ return NULL;
+ }
+ c->type = x;
+ if (cygheap_max < ((char *) c + len))
+ cygheap_max = (char *) c + len;
+ return (void *) c->data;
+}
+
+extern "C" void *__stdcall
+cmalloc (cygheap_types x, DWORD n)
+{
+ cygheap_entry *c;
+ c = (cygheap_entry *) _cmalloc (sizeof_cygheap (n));
+ if (!c)
+ system_printf ("cmalloc returned NULL");
+ return creturn (x, c, n);
+}
+
+extern "C" void *__stdcall
+crealloc (void *s, DWORD n)
+{
+ if (s == NULL)
+ return cmalloc (HEAP_STR, n); // kludge
+
+ assert (!inheap (s));
+ cygheap_entry *c = tocygheap (s);
+ cygheap_types t = c->type;
+ c = (cygheap_entry *) _crealloc (c, sizeof_cygheap (n));
+ if (!c)
+ system_printf ("crealloc returned NULL");
+ return creturn (t, c, n);
+}
+
+extern "C" void __stdcall
+cfree (void *s)
+{
+ assert (!inheap (s));
+ (void) _cfree (tocygheap (s));
+}
+
+extern "C" void *__stdcall
+ccalloc (cygheap_types x, DWORD n, DWORD size)
+{
+ cygheap_entry *c;
+ c = (cygheap_entry *) _cmalloc (sizeof_cygheap (n * size));
+ if (c)
+ memset (c->data, 0, size);
+ if (!c)
+ system_printf ("ccalloc returned NULL");
+ return creturn (x, c, n);
+}
+
+extern "C" char *__stdcall
+cstrdup (const char *s)
+{
+ char *p = (char *) cmalloc (HEAP_STR, strlen (s) + 1);
+ if (!p)
+ return NULL;
+ strcpy (p, s);
+ return p;
+}
--- /dev/null
+/* cygheap.h: Cygwin heap manager.
+
+ Copyright 2000 Cygnus Solutions.
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#undef cfree
+
+enum cygheap_types
+{
+ HEAP_FHANDLER,
+ HEAP_STR,
+ HEAP_ARGV,
+ HEAP_EXEC,
+ HEAP_BUF
+};
+
+#define CYGHEAPSIZE ((1000 * sizeof (fhandler_union)) + (2 * 65536))
+
+extern HANDLE cygheap;
+extern HANDLE cygheap_max;
+
+#define incygheap(s) (cygheap && ((char *) (s) >= (char *) cygheap) && ((char *) (s) <= ((char *) cygheap) + CYGHEAPSIZE))
+
+void cygheap_init ();
+extern "C" {
+void __stdcall cfree (void *);
+void __stdcall cygheap_fixup_in_child (HANDLE);
+void *__stdcall cmalloc (cygheap_types, DWORD);
+void *__stdcall crealloc (void *, DWORD);
+void *__stdcall ccalloc (cygheap_types, DWORD, DWORD);
+char *__stdcall cstrdup (const char *);
+}
#include "sigproc.h"
#include "perthread.h"
#include "pinfo.h"
+#include "cygheap.h"
+#include "heap.h"
#include "cygerrno.h"
#include "fhandler.h"
#include "child_info.h"
if (!force)
{
if (user_data->forkee || user_data->run_ctors_p)
- return; // inherit constructed stuff from parent pid
+ return; // inherit constructed stuff from parent pid
user_data->run_ctors_p = 1;
}
char *p;
char quote = *cmd;
- /* If this is being run from a Windows shell then we have
- to preserve quotes for globify to play with later. */
- if (winshell)
+ if (!winshell)
{
- while (*++cmd)
- if ((p = strchr (cmd, quote)) == NULL)
- {
- cmd = strchr (cmd, '\0'); // no closing quote
- break;
- }
- else if (p[1] == quote && p[-1] != '\\')
- {
- *p = '\\';
- cmd = ++p; // a quoted quote
- }
- else
- {
- cmd = p + 1; // point to after end
- break;
- }
- return cmd;
+ char *p;
+ strcpy (cmd, cmd + 1);
+ if ((p = strchr (cmd, quote)) != NULL)
+ strcpy (p, p + 1);
+ return p + 1;
}
- /* When running as a child of a cygwin process, the quoted
- characters should have been placed here by spawn_guts, so
- we'll just pinch them out of the command string unless
- they're quoted with a preceding \ */
- p = cmd + 1;
- while (*p)
- {
- if (*p == '\\' && p[1] == '\\')
- {
- strcpy (p, p + 1);
- p++;
- }
- else if (*p != quote)
- p++;
- else if (p[-1] == '\\')
- strcpy (p - 1, p);
- else if (p[1] == quote)
- {
- strcpy (p, p + 1);
- p++;
- }
- else
- {
- strcpy (p, p + 1);
- break;
- }
- }
- strcpy (cmd, cmd + 1);
- return p - 1;
+ /* This must have been run from a Windows shell, so preserve
+ quotes for globify to play with later. */
+ while (*++cmd)
+ if ((p = strpbrk (cmd, "\\\"")) == NULL)
+ {
+ cmd = strchr (cmd, '\0'); // no closing quote
+ break;
+ }
+ else if (quote == '\'')
+ continue;
+ else if (*p == '\\')
+ cmd = ++p;
+ else if (p[1] == quote)
+ {
+ *p = '\\';
+ cmd = ++p; // a quoted quote
+ }
+ else
+ {
+ cmd = p + 1; // point to after end
+ break;
+ }
+ return cmd;
}
/* Perform a glob on word if it contains wildcard characters.
}
argv[argc] = NULL;
- debug_printf ("argv[%d] = '%s'\n", argc, argv[argc]);
+
+ debug_printf ("argc %d", argc);
}
/* sanity and sync check */
}
static NO_COPY STARTUPINFO si;
-# define ciresrv ((struct child_info_fork *)(si.lpReserved2))
+# define fork_info ((struct child_info_fork *)(si.lpReserved2))
+# define spawn_info ((struct child_info_spawn *)(si.lpReserved2))
child_info_fork NO_COPY *child_proc_info = NULL;
static MEMORY_BASIC_INFORMATION sm;
-#define EBP 6
-#define ESP 7
-
-extern __inline__ void
+// __inline__ void
+extern void
alloc_stack_hard_way (child_info_fork *ci, volatile char *b)
{
void *new_stack_pointer;
MEMORY_BASIC_INFORMATION m;
+ void *newbase;
+ int newlen;
+ LPBYTE curbot = (LPBYTE) sm.BaseAddress + sm.RegionSize;
+ bool noguard;
- if (!VirtualAlloc (ci->stacktop,
- (DWORD) ci->stackbottom - (DWORD) ci->stacktop,
- MEM_RESERVE, PAGE_NOACCESS))
+ if (ci->stacktop > (LPBYTE) sm.AllocationBase && ci->stacktop < curbot)
+ {
+ newbase = curbot;
+ newlen = (LPBYTE) ci->stackbottom - (LPBYTE) curbot;
+ noguard = 1;
+ }
+ else
+ {
+ newbase = ci->stacktop;
+ newlen = (DWORD) ci->stackbottom - (DWORD) ci->stacktop;
+ noguard = 0;
+ }
+ if (!VirtualAlloc (newbase, newlen, MEM_RESERVE, PAGE_NOACCESS))
api_fatal ("fork: can't reserve memory for stack %p - %p, %E",
ci->stacktop, ci->stackbottom);
new_stack_pointer, ci->stacksize);
if (!VirtualQuery ((LPCVOID) new_stack_pointer, &m, sizeof m))
api_fatal ("fork: couldn't get new stack info, %E");
- m.BaseAddress = (LPVOID)((DWORD)m.BaseAddress - 1);
- if (!VirtualAlloc ((LPVOID) m.BaseAddress, 1, MEM_COMMIT,
- PAGE_EXECUTE_READWRITE|PAGE_GUARD))
- api_fatal ("fork: couldn't allocate new stack guard page %p, %E",
- m.BaseAddress);
+ if (!noguard)
+ {
+ m.BaseAddress = (LPVOID)((DWORD)m.BaseAddress - 1);
+ if (!VirtualAlloc ((LPVOID) m.BaseAddress, 1, MEM_COMMIT,
+ PAGE_EXECUTE_READWRITE|PAGE_GUARD))
+ api_fatal ("fork: couldn't allocate new stack guard page %p, %E",
+ m.BaseAddress);
+ }
if (!VirtualQuery ((LPCVOID) m.BaseAddress, &m, sizeof m))
api_fatal ("fork: couldn't get new stack info, %E");
ci->stacktop = m.BaseAddress;
/* extend the stack prior to fork longjmp */
-extern __inline__ void
+static void
alloc_stack (child_info_fork *ci)
{
/* FIXME: adding 16384 seems to avoid a stack copy problem during
return;
}
-/* These must be static due to the way we have to deal with forked
- processes. */
-static NO_COPY LPBYTE info = NULL;
static NO_COPY int mypid = 0;
-static int argc = 0;
-static char **argv = NULL;
+int _declspec(dllexport) __argc = 0;
+char _declspec(dllexport) **__argv = NULL;
void
sigthread::init (const char *s)
static void
dll_crt0_1 ()
{
-#ifdef DEBUGGING
- if (child_proc_info)
- switch (child_proc_info->type)
- {
- case PROC_FORK:
- case PROC_FORK1:
- ProtectHandle (child_proc_info->forker_finished);
- case PROC_EXEC:
- ProtectHandle (child_proc_info->subproc_ready);
- }
- ProtectHandle (hMainProc);
- ProtectHandle (hMainThread);
-#endif
+ /* According to onno@stack.urc.tue.nl, the exception handler record must
+ be on the stack. */
+ /* FIXME: Verify forked children get their exception handler set up ok. */
+ exception_list cygwin_except_entry;
- regthread ("main", GetCurrentThreadId ());
+ /* Initialize SIGSEGV handling, etc... Because the exception handler
+ references data in the shared area, this must be done after
+ shared_init. */
+ init_exceptions (&cygwin_except_entry);
+ do_global_ctors (&__CTOR_LIST__, 1);
+
+ /* Set the os_being_run global. */
+ set_os_type ();
check_sanity_and_sync (user_data);
/* Nasty static stuff needed by newlib -- point to a local copy of
_impure_ptr = &reent_data;
-#ifdef _MT_SAFE
- user_data->resourcelocks->Init();
- user_data->threadinterface->Init0();
-#endif
+ user_data->resourcelocks->Init ();
+ user_data->threadinterface->Init0 ();
+ regthread ("main", GetCurrentThreadId ());
+
+ char **envp = NULL;
+
+ if (child_proc_info)
+ {
+ switch (child_proc_info->type)
+ {
+ case PROC_FORK:
+ case PROC_FORK1:
+ alloc_stack (fork_info);
+ set_myself (mypid);
+ user_data->forkee = child_proc_info->cygpid;
+ user_data->heaptop = child_proc_info->heaptop;
+ user_data->heapbase = child_proc_info->heapbase;
+ user_data->heapptr = child_proc_info->heapptr;
+ ProtectHandle (child_proc_info->forker_finished);
+ break;
+ case PROC_EXEC:
+ case PROC_SPAWN:
+ HANDLE h;
+ cygheap = spawn_info->cygheap;
+ cygheap_max = spawn_info->cygheap_max;
+ cygheap_fixup_in_child (spawn_info->parent);
+ if (!spawn_info->moreinfo->myself_pinfo ||
+ !DuplicateHandle (hMainProc, spawn_info->moreinfo->myself_pinfo,
+ hMainProc, &h, 0, 0,
+ DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
+ h = NULL;
+ set_myself (mypid, h);
+ __argc = spawn_info->moreinfo->argc;
+ __argv = spawn_info->moreinfo->argv;
+ envp = spawn_info->moreinfo->environ;
+ cwd_fixup_after_exec (spawn_info->moreinfo->cwd_win32,
+ spawn_info->moreinfo->cwd_posix,
+ spawn_info->moreinfo->cwd_hash);
+ fdtab.fixup_after_exec (spawn_info->parent, spawn_info->moreinfo->nfds,
+ spawn_info->moreinfo->fds);
+ CloseHandle (spawn_info->parent);
+ if (spawn_info->moreinfo->old_title)
+ {
+ old_title = strcpy (title_buf, spawn_info->moreinfo->old_title);
+ cfree (spawn_info->moreinfo->old_title);
+ }
+ ProtectHandle (child_proc_info->subproc_ready);
+ break;
+ }
+ }
+ ProtectHandle (hMainProc);
+ ProtectHandle (hMainThread);
/* Initialize the host dependent constants object. */
host_dependent.init ();
mainthread.init ("mainthread"); // For use in determining if signals
// should be blocked.
- if (mypid)
- set_myself ((pid_t) mypid, NULL);
-
(void) SetErrorMode (SEM_FAILCRITICALERRORS);
/* Initialize the heap. */
NOTE: Don't do anything that involves the stack until you've completed
this step. */
- if (ciresrv->stacksize)
+ if (fork_info->stacksize)
{
- asm ("movl %0,%%fs:4" : : "r" (ciresrv->stackbottom));
- asm ("movl %0,%%fs:8" : : "r" (ciresrv->stacktop));
+ asm ("movl %0,%%fs:4" : : "r" (fork_info->stackbottom));
+ asm ("movl %0,%%fs:8" : : "r" (fork_info->stacktop));
}
- longjmp (ciresrv->jmp, ciresrv->cygpid);
+ longjmp (fork_info->jmp, fork_info->cygpid);
}
- /* Initialize our process table entry. Don't use the parent info for
- dynamically loaded case. */
- pinfo_init ((dynamically_loaded) ? NULL : info);
+ cygheap_init (); /* Initialize cygwin's heap */
+ cwd_init ();
+
+ /* Initialize our process table entry. */
+ pinfo_init (envp);
if (!old_title && GetConsoleTitle (title_buf, TITLESIZE))
old_title = title_buf;
/* Set up standard fds in file descriptor table. */
stdio_init ();
- if (user_data->premain[0])
- for (unsigned int i = 0; i < PREMAIN_LEN / 2; i++)
- user_data->premain[i] (argc, argv);
-
- /* Scan the command line and build argv. Expand wildcards if not
- called from another cygwin process. */
- build_argv (line, argv, argc,
- NOTSTATE (myself, PID_CYGPARENT) && allow_glob);
-
- /* Convert argv[0] to posix rules if it's currently blatantly
- win32 style. */
- if ((strchr (argv[0], ':')) || (strchr (argv[0], '\\')))
+ if (!__argc)
{
- char *new_argv0 = (char *) alloca (MAX_PATH);
- cygwin_conv_to_posix_path (argv[0], new_argv0);
- argv[0] = new_argv0;
+ /* Scan the command line and build argv. Expand wildcards if not
+ called from another cygwin process. */
+ build_argv (line, __argv, __argc,
+ NOTSTATE (myself, PID_CYGPARENT) && allow_glob);
+
+ /* Convert argv[0] to posix rules if it's currently blatantly
+ win32 style. */
+ if ((strchr (__argv[0], ':')) || (strchr (__argv[0], '\\')))
+ {
+ char *new_argv0 = (char *) alloca (MAX_PATH);
+ cygwin_conv_to_posix_path (__argv[0], new_argv0);
+ char *p = strchr (new_argv0, '\0') - 4;
+ if (p > new_argv0 && strcasematch (p, ".exe"))
+ *p = '\0';
+ __argv[0] = new_argv0;
+ }
}
+ if (user_data->premain[0])
+ for (unsigned int i = 0; i < PREMAIN_LEN / 2; i++)
+ user_data->premain[i] (__argc, __argv);
+
/* Set up __progname for getopt error call. */
- __progname = argv[0];
+ __progname = __argv[0];
cygwin_finished_initializing = 1;
/* Call init of loaded dlls. */
/* Execute any specified "premain" functions */
if (user_data->premain[PREMAIN_LEN / 2])
for (unsigned int i = PREMAIN_LEN / 2; i < PREMAIN_LEN; i++)
- user_data->premain[i] (argc, argv);
+ user_data->premain[i] (__argc, __argv);
debug_printf ("user_data->main %p", user_data->main);
set_errno (0);
+ MALLOC_CHECK;
if (user_data->main)
- exit (user_data->main (argc, argv, *user_data->envptr));
+ exit (user_data->main (__argc, __argv, *user_data->envptr));
}
/* Wrap the real one, otherwise gdb gets confused about
extern "C" void __stdcall
_dll_crt0 ()
{
- char zeros[sizeof (ciresrv->zero)] = {0};
- /* According to onno@stack.urc.tue.nl, the exception handler record must
- be on the stack. */
- /* FIXME: Verify forked children get their exception handler set up ok. */
- exception_list cygwin_except_entry;
- /* Initialize SIGSEGV handling, etc... Because the exception handler
- references data in the shared area, this must be done after
- shared_init. */
- init_exceptions (&cygwin_except_entry);
- do_global_ctors (&__CTOR_LIST__, 1);
+ char zeros[sizeof (fork_info->zero)] = {0};
/* Set the os_being_run global. */
set_os_type ();
DuplicateHandle (hMainProc, GetCurrentThread (), hMainProc,
&hMainThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
- HANDLE h;
GetStartupInfo (&si);
if (si.cbReserved2 >= EXEC_MAGIC_SIZE &&
- memcmp (ciresrv->zero, zeros, sizeof (zeros)) == 0)
+ memcmp (fork_info->zero, zeros, sizeof (zeros)) == 0)
{
- switch (ciresrv->type)
+ switch (fork_info->type)
{
case PROC_EXEC:
case PROC_SPAWN:
case PROC_FORK:
case PROC_FORK1:
{
- HANDLE me = hMainProc;
- child_proc_info = ciresrv;
+ child_proc_info = fork_info;
mypid = child_proc_info->cygpid;
cygwin_shared_h = child_proc_info->shared_h;
console_shared_h = child_proc_info->console_h;
/* We don't want subprocesses to inherit this */
- if (!dynamically_loaded)
- {
- if (!DuplicateHandle (me, child_proc_info->parent_alive,
- me, &parent_alive, 0, 0,
+ if (dynamically_loaded)
+ parent_alive = NULL;
+ else if (!DuplicateHandle (hMainProc, child_proc_info->parent_alive,
+ hMainProc, &parent_alive, 0, 0,
DUPLICATE_SAME_ACCESS
| DUPLICATE_CLOSE_SOURCE))
- system_printf ("parent_alive DuplicateHandle failed, %E");
- }
- else if (parent_alive)
- parent_alive = NULL;
+ system_printf ("parent_alive DuplicateHandle failed, %E");
- switch (child_proc_info->type)
- {
- case PROC_EXEC:
- case PROC_SPAWN:
- info = si.lpReserved2 + ciresrv->cb;
- if (child_proc_info->myself_pinfo &&
- DuplicateHandle (hMainProc, child_proc_info->myself_pinfo,
- hMainProc, &h, 0, 0,
- DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
- {
- set_myself (mypid, h);
- mypid = 0;
- }
- break;
- case PROC_FORK:
- case PROC_FORK1:
- user_data->forkee = child_proc_info->cygpid;
- user_data->heaptop = child_proc_info->heaptop;
- user_data->heapbase = child_proc_info->heapbase;
- user_data->heapptr = child_proc_info->heapptr;
- alloc_stack (ciresrv); // may never return
- }
break;
}
default:
- if ((ciresrv->type & PROC_MAGIC_MASK) == PROC_MAGIC_GENERIC)
+ if ((fork_info->type & PROC_MAGIC_MASK) == PROC_MAGIC_GENERIC)
api_fatal ("conflicting versions of cygwin1.dll detected. Use only the most recent version.\n");
}
}
{
static char **envp;
static int _fmode;
- /* According to onno@stack.urc.tue.nl, the exception handler record must
- be on the stack. */
- /* FIXME: Verify forked children get their exception handler set up ok. */
- exception_list cygwin_except_entry;
- /* Initialize SIGSEGV handling, etc... Because the exception handler
- references data in the shared area, this must be done after
- shared_init. */
- init_exceptions (&cygwin_except_entry);
- do_global_ctors (&__CTOR_LIST__, 1);
-
- /* Set the os_being_run global. */
- set_os_type ();
-
user_data->heapbase = user_data->heapptr = user_data->heaptop = NULL;
if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (),
int res = GetLastError ();
empty = 0;
if (res == ERROR_SHARING_VIOLATION ||
- (os_being_run != winNT && res == ERROR_ACCESS_DENIED))
+ (os_being_run != winNT && res == ERROR_ACCESS_DENIED))
{
/* File still inuse, that's ok */
syscall_printf ("Still using %s", name[i]);
else
{
syscall_printf ("Hmm, don't know what to do with '%s', %E", name[i]);
- inuse[i] = 0;
+ inuse[i] = 0;
}
}
}
}
if (stat (myself->rootlen ? dirname : real_dirname.get_win32 (),
- &statbuf) == -1)
+ &statbuf) == -1)
goto failed;
if (!(statbuf.st_mode & S_IFDIR))
if (CreateDirectoryA (real_dir.get_win32 (), 0))
{
set_file_attribute (real_dir.has_acls (), real_dir.get_win32 (),
- S_IFDIR | ((mode & 0777) & ~myself->umask));
+ S_IFDIR | ((mode & 0777) & ~myself->umask));
res = 0;
}
else
if (RemoveDirectoryA (real_dir.get_win32 ()))
{
/* RemoveDirectory on a samba drive doesn't return an error if the
- directory can't be removed because it's not empty. Checking for
- existence afterwards keeps us informed about success. */
+ directory can't be removed because it's not empty. Checking for
+ existence afterwards keeps us informed about success. */
if (GetFileAttributesA (real_dir.get_win32 ()) != (DWORD) -1)
- set_errno (ENOTEMPTY);
+ set_errno (ENOTEMPTY);
else
- res = 0;
+ res = 0;
}
else if (GetLastError() == ERROR_ACCESS_DENIED)
{
/* Under Windows 9X or on a samba share, ERROR_ACCESS_DENIED is
- returned if you try to remove a file. On 9X the same error is
- returned if you try to remove a non-empty directory. */
+ returned if you try to remove a file. On 9X the same error is
+ returned if you try to remove a non-empty directory. */
if (real_dir.file_attributes () != (DWORD) -1 &&
!(real_dir.file_attributes () & FILE_ATTRIBUTE_DIRECTORY))
set_errno (ENOTDIR);
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
+#include "cygheap.h"
#include "cygerrno.h"
#include "fhandler.h"
#include "path.h"
/* Try to allocate more space for fd table. We can't call realloc()
here to preserve old table if memory allocation fails */
- if (!(newfds = (fhandler_base **) calloc (new_size, sizeof newfds[0])))
+ if (!(newfds = (fhandler_base **) ccalloc (HEAP_ARGV, new_size, sizeof newfds[0])))
{
debug_printf ("calloc failed");
return 0;
if (fds)
{
memcpy (newfds, fds, size * sizeof (fds[0]));
- free (fds);
+ cfree (fds);
}
size = new_size;
{
if (!not_open (fd))
{
- delete (fds[fd]);
+ delete fds[fd]; /* CGF FIXME */
fds[fd] = NULL;
}
}
dtable::build_fhandler (int fd, DWORD dev, const char *name, int unit)
{
fhandler_base *fh;
- void *buf = calloc (1, sizeof (fhandler_union) + 100);
+ void *buf = ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_union) + 100);
dev &= FH_DEVMASK;
switch (dev)
newfh->set_io_handle (NULL);
if (oldfh->dup (newfh))
{
- free (newfh);
+ cfree (newfh);
newfh = NULL;
return NULL;
}
}
SetResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"dup");
- if ((size_t) newfd >= fdtab.size)
- {
- int inc_size = NOFILE_INCR * ((newfd + NOFILE_INCR - 1) / NOFILE_INCR) -
- fdtab.size;
- fdtab.extend (inc_size);
- }
+
if ((size_t) newfd >= fdtab.size || newfd < 0)
{
syscall_printf ("new fd out of bounds: %d", newfd);
set_errno (EBADF);
goto done;
}
+
+ if ((size_t) newfd >= fdtab.size)
+ {
+ int inc_size = NOFILE_INCR * ((newfd + NOFILE_INCR - 1) / NOFILE_INCR) -
+ fdtab.size;
+ fdtab.extend (inc_size);
+ }
+
if (!not_open (newfd))
_close (newfd);
fds[newfd] = newfh;
select_record *
dtable::select_read (int fd, select_record *s)
{
- if (fdtab.not_open (fd))
+ if (not_open (fd))
{
set_errno (EBADF);
return NULL;
}
- fhandler_base *fh = fdtab[fd];
+ fhandler_base *fh = fds[fd];
s = fh->select_read (s);
s->fd = fd;
s->fh = fh;
select_record *
dtable::select_write (int fd, select_record *s)
{
- if (fdtab.not_open (fd))
+ if (not_open (fd))
{
set_errno (EBADF);
return NULL;
}
- fhandler_base *fh = fdtab[fd];
+ fhandler_base *fh = fds[fd];
s = fh->select_write (s);
s->fd = fd;
s->fh = fh;
select_record *
dtable::select_except (int fd, select_record *s)
{
- if (fdtab.not_open (fd))
+ if (not_open (fd))
{
set_errno (EBADF);
return NULL;
}
- fhandler_base *fh = fdtab[fd];
+ fhandler_base *fh = fds[fd];
s = fh->select_except (s);
s->fd = fd;
s->fh = fh;
return s;
}
-/*
- * Function to take an existant dtable array
- * and linearize it into a memory buffer.
- * If memory buffer is NULL, it returns the size
- * of memory buffer needed to do the linearization.
- * On error returns -1.
- */
-
-int
-dtable::linearize_fd_array (unsigned char *in_buf, int buflen)
+/* Function to walk the fd table after an exec and perform
+ per-fhandler type fixups. */
+void
+dtable::fixup_after_exec (HANDLE parent, size_t sz, fhandler_base **f)
{
- /* If buf == NULL, just precalculate length */
- if (in_buf == NULL)
- {
- buflen = sizeof (size_t);
- for (int i = 0, max_used_fd = -1; i < (int)size; i++)
- if (!not_open (i) && !fds[i]->get_close_on_exec ())
- {
- buflen += i - (max_used_fd + 1);
- buflen += fds[i]->cb + strlen (fds[i]->get_name ()) + 1
- + strlen (fds[i]->get_win32_name ()) + 1;
- max_used_fd = i;
- }
- debug_printf ("needed buflen %d", buflen);
- return buflen;
- }
-
- debug_printf ("in_buf = %x, buflen = %d", in_buf, buflen);
-
- /*
- * Now linearize each open fd (write a 0xff byte for a closed fd).
- * Write the name of the open fd first (null terminated). This
- * allows the de_linearizeing code to determine what kind of fhandler_xxx
- * to create.
- */
-
- size_t i;
- int len, total_size;
-
- total_size = sizeof (size_t);
- if (total_size > buflen)
- {
- system_printf ("FATAL: linearize_fd_array exceeded buffer size");
- return -1;
- }
-
- unsigned char *buf = in_buf;
- buf += sizeof (size_t); /* skip over length which is added later */
-
- for (i = 0, total_size = sizeof (size_t); total_size < buflen; i++)
- {
- if (not_open (i) || fds[i]->get_close_on_exec ())
- {
- debug_printf ("linearizing closed fd %d",i);
- *buf = 0xff; /* place holder */
- len = 1;
- }
+ size = sz;
+ fds = f;
+ first_fd_for_open = 0;
+ for (size_t i = 0; i < size; i++)
+ if (fds[i])
+ if (fds[i]->get_close_on_exec ())
+ release (i);
else
{
- len = fds[i]->linearize (buf);
- debug_printf ("fd %d, len %d, name %s, device %p", i, len, buf,
- fds[i]->get_device ());
- }
-
- total_size += len;
- buf += len;
- }
-
- i--;
- memcpy (in_buf, &i, sizeof (size_t));
- if (total_size != buflen)
- system_printf ("out of sync %d != %d", total_size, buflen);
- return total_size;
-}
-
-/*
- * Function to take a linearized dtable array in a memory buffer and
- * re-create the original dtable array.
- */
-
-LPBYTE
-dtable::de_linearize_fd_array (LPBYTE buf)
-{
- int len, max_used_fd;
- size_t inc_size;
-
- debug_printf ("buf %x", buf);
-
- /* First get the number of fd's - use this to set the fdtabsize.
- NB. This is the only place in the code this should be done !!
- */
-
- memcpy ((char *) &max_used_fd, buf, sizeof (int));
- buf += sizeof (size_t);
-
- inc_size = NOFILE_INCR * ((max_used_fd + NOFILE_INCR - 1) / NOFILE_INCR) -
- size;
- debug_printf ("max_used_fd %d, inc size %d", max_used_fd, inc_size);
- if (inc_size > 0 && !extend (inc_size))
- {
- system_printf ("out of memory");
- return NULL;
- }
-
- for (int i = 0; i <= max_used_fd; i++)
- {
- /* 0xFF means closed */
- if (*buf == 0xff)
- {
- fds[i] = NULL;
- buf++;
- debug_printf ("closed fd %d", i);
- continue;
+ fds[i]->clear_readahead ();
+ fds[i]->fixup_after_exec (parent);
}
- /* fd was open - de_linearize it */
- /* Get the null-terminated name. It is followed by an image of
- the actual fhandler_* structure. Use the status field from
- this to build a new fhandler type. */
-
- DWORD status;
- LPBYTE obuf = buf;
- char *win32;
- win32 = strchr ((char *)obuf, '\0') + 1;
- buf = (LPBYTE)strchr ((char *)win32, '\0') + 1;
- memcpy ((char *)&status, buf + FHSTATOFF, sizeof(DWORD));
- debug_printf ("fd %d, name %s, win32 name %s, status %p",
- i, obuf, win32, status);
- len = build_fhandler (i, status, (const char *) NULL)->
- de_linearize ((char *) buf, (char *) obuf, win32);
- set_std_handle (i);
- buf += len;
- debug_printf ("len %d", buf - obuf);
- }
- first_fd_for_open = 0;
- return buf;
}
void
dtable::fixup_after_fork (HANDLE parent)
{
SetResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"dup");
+ fhandler_base *fh;
for (size_t i = 0; i < size; i++)
- if (!not_open (i))
+ if ((fh = fds[i]) != NULL)
{
- fhandler_base *fh = fds[i];
if (fh->get_close_on_exec () || fh->get_need_fork_fixup ())
{
debug_printf ("fd %d(%s)", i, fh->get_name ());
dtable::vfork_child_dup ()
{
fhandler_base **newtable;
- newtable = (fhandler_base **) calloc (size, sizeof(fds[0]));
+ newtable = (fhandler_base **) ccalloc (HEAP_ARGV, size, sizeof(fds[0]));
int res = 1;
SetResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"dup");
set_errno (EBADF);
goto out;
}
+
fds_on_hold = fds;
fds = newtable;
out:
fhandler_base **deleteme = fds;
fds = fds_on_hold;
fds_on_hold = NULL;
- free (deleteme);
+ cfree (deleteme);
ReleaseResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"dup");
return;
void release (int fd);
void init_std_file_from_handle (int fd, HANDLE handle, DWORD access, const char *name);
int dup2 (int oldfd, int newfd);
- int linearize_fd_array (unsigned char *buf, int buflen);
- LPBYTE de_linearize_fd_array (LPBYTE buf);
+ void fixup_after_exec (HANDLE, size_t, fhandler_base **);
fhandler_base *operator [](int fd) { return fds[fd]; }
select_record *select_read (int fd, select_record *s);
select_record *select_write (int fd, select_record *s);
BOOL reset_com = TRUE;
static BOOL envcache = TRUE;
+static char **lastenviron = NULL;
+
/* List of names which are converted from dos to unix
* on the way in and back again on the way out.
*
/* Convert windows path specs to POSIX, if appropriate.
*/
static void __stdcall
-posify (int already_posix, char **here, const char *value)
+posify (char **here, const char *value)
{
char *src = *here;
win_env *conv;
if (!(conv = getwinenv (src)))
return;
- if (already_posix)
- conv->add_cache (value, NULL);
- else
- {
- /* Turn all the items from c:<foo>;<bar> into their
- mounted equivalents - if there is one. */
+ /* Turn all the items from c:<foo>;<bar> into their
+ mounted equivalents - if there is one. */
- char *outenv = (char *) malloc (1 + len + conv->posix_len (value));
- memcpy (outenv, src, len);
- conv->toposix (value, outenv + len);
- conv->add_cache (outenv + len, value);
+ char *outenv = (char *) malloc (1 + len + conv->posix_len (value));
+ memcpy (outenv, src, len);
+ conv->toposix (value, outenv + len);
+ conv->add_cache (outenv + len, value);
- debug_printf ("env var converted to %s", outenv);
- *here = outenv;
- free (src);
- }
+ debug_printf ("env var converted to %s", outenv);
+ *here = outenv;
+ free (src);
}
/*
return my_findenv (name, &offset);
}
+extern int __stdcall
+envsize (const char * const *in_envp, int debug_print)
+{
+ const char * const *envp;
+ for (envp = in_envp; *envp; envp++)
+ if (debug_print)
+ debug_printf ("%s", *envp);
+ return (1 + envp - in_envp) * sizeof (const char *);
+}
+
/* Takes similar arguments to setenv except that overwrite is
either -1, 0, or 1. 0 or 1 signify that the function should
perform similarly to setenv. Otherwise putenv is assumed. */
}
else
{ /* Create new slot. */
- char **env;
-
- /* Search for the end of the environment. */
- for (env = cur_environ (); *env; env++)
- continue;
+ int sz = envsize (cur_environ ());
+ int allocsz = sz + sizeof (char *);
- offset = env - cur_environ (); /* Number of elements currently in environ. */
+ offset = (sz - 1) / sizeof (char *);
/* Allocate space for additional element plus terminating NULL. */
- __cygwin_environ = (char **) realloc (cur_environ (), (sizeof (char *) *
- (offset + 2)));
+ if (__cygwin_environ == lastenviron)
+ lastenviron = __cygwin_environ = (char **) realloc (cur_environ (),
+ allocsz);
+ else if ((lastenviron = (char **) malloc (allocsz)) != NULL)
+ __cygwin_environ = (char **) memcpy ((char **) lastenviron,
+ __cygwin_environ, sz);
+
if (!__cygwin_environ)
return -1; /* Oops. No more memory. */
if ((res = check_null_empty_path (str)))
{
if (res == ENOENT)
- return 0;
+ return 0;
set_errno (res);
return -1;
}
if ((res = check_null_empty_path (name)))
{
if (res == ENOENT)
- return 0;
+ return 0;
set_errno (res);
return -1;
}
* environment variable and set appropriate options from it.
*/
void
-environ_init (int already_posix)
+environ_init (char **envp)
{
- char *rawenv = GetEnvironmentStrings ();
- int envsize, i;
+ char *rawenv;
+ int sz, i;
char *p;
- char *newp, **envp;
+ char *newp;
int sawTERM = 0;
static char cygterm[] = "TERM=cygwin";
- /* Allocate space for environment + trailing NULL + CYGWIN env. */
- envp = (char **) malloc ((4 + (envsize = 100)) * sizeof (char *));
-
regopt ("default");
if (myself->progname[0])
regopt (myself->progname);
allow_ntsec = TRUE;
#endif
+ if (envp)
+ {
+ sz = envsize (envp, 1);
+ char **newenv = (char **) malloc (sz);
+ envp = (char **) memcpy (newenv, envp, sz);
+ cfree (envp);
+ goto out;
+ }
+
+ /* Allocate space for environment + trailing NULL + CYGWIN env. */
+ lastenviron = envp = (char **) malloc ((4 + (sz = 100)) * sizeof (char *));
+ rawenv = GetEnvironmentStrings ();
+
/* Current directory information is recorded as variables of the
form "=X:=X:\foo\bar; these must be changed into something legal
(we could just ignore them but maybe an application will
for (i = 0, p = rawenv; *p != '\0'; p = strchr (p, '\0') + 1, i++)
{
newp = strdup (p);
- if (i >= envsize)
- envp = (char **) realloc (envp, (4 + (envsize += 100)) *
+ if (i >= sz)
+ envp = (char **) realloc (envp, (4 + (sz += 100)) *
sizeof (char *));
envp[i] = newp;
if (*newp == '=')
if (strncmp (newp, "CYGWIN=", sizeof("CYGWIN=") - 1) == 0)
parse_options (newp + sizeof("CYGWIN=") - 1);
if (*eq)
- posify (already_posix, envp + i, *++eq ? eq : --eq);
+ posify (envp + i, *++eq ? eq : --eq);
debug_printf ("%s", envp[i]);
}
if (!sawTERM)
envp[i++] = cygterm;
envp[i] = NULL;
+ FreeEnvironmentStrings (rawenv);
+
+out:
__cygwin_environ = envp;
update_envptrs ();
parse_options (NULL);
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
+#include "cygheap.h"
#include <string.h>
#include "cygerrno.h"
#include "fhandler.h"
DWORD binmode = 0;
+inline fhandler_base&
+fhandler_base::operator =(fhandler_base &x)
+{
+ memcpy (this, &x, sizeof *this);
+ unix_path_name_ = x.unix_path_name_ ? cstrdup (x.unix_path_name_) : NULL;
+ win32_path_name_ = x.win32_path_name_ ? cstrdup (x.win32_path_name_) : NULL;
+ rabuf = NULL;
+ ralen = 0;
+ raixget = 0;
+ raixput = 0;
+ rabuflen = 0;
+ return *this;
+}
+
int
fhandler_base::puts_readahead (const char *s, size_t len = (size_t) -1)
{
int success = 1;
while ((*s || (len != (size_t) -1 && len--))
- && (success = put_readahead (*s++) > 0))
+ && (success = put_readahead (*s++) > 0))
continue;
return success;
}
if (!no_free_names ())
{
if (unix_path_name_ != NULL && unix_path_name_ != fhandler_disk_dummy_name)
- free (unix_path_name_);
+ cfree (unix_path_name_);
if (win32_path_name_ != NULL && unix_path_name_ != fhandler_disk_dummy_name)
- free (win32_path_name_);
+ cfree (win32_path_name_);
}
unix_path_name_ = win32_path_name_ = NULL;
if (unix_path == NULL || !*unix_path)
return;
- unix_path_name_ = strdup (unix_path);
+ unix_path_name_ = cstrdup (unix_path);
if (unix_path_name_ == NULL)
{
system_printf ("fatal error. strdup failed");
}
if (win32_path)
- win32_path_name_ = strdup (win32_path);
+ win32_path_name_ = cstrdup (win32_path);
else
{
const char *fmt = get_native_name ();
- win32_path_name_ = (char *) malloc (strlen(fmt) + 16);
+ win32_path_name_ = (char *) cmalloc (HEAP_STR, strlen(fmt) + 16);
__small_sprintf (win32_path_name_, fmt, unit);
}
break;
default:
syscall_printf ("ReadFile %s failed, %E", unix_path_name_);
- __seterrno_from_win_error (errcode);
+ __seterrno_from_win_error (errcode);
return -1;
break;
}
return bytes_read;
}
-int
-fhandler_base::linearize (unsigned char *buf)
-{
- unsigned char *orig_buf = buf;
-#define cbuf ((char *)buf)
- strcpy (cbuf, get_name() ?: "");
- char *p = strcpy (strchr (cbuf, '\0') + 1, get_win32_name ());
- buf = (unsigned char *)memcpy (strchr (p, '\0') + 1, this, cb);
- debug_printf ("access_ %p, status %p, io_handle %p, output_handle %p",
- access_, status, get_io_handle (), get_output_handle ());
- return (buf + cb) - orig_buf;
-#undef cbuf
-}
-
-int
-fhandler_base::de_linearize (const char *buf, const char *unix_name,
- const char *win32_name)
-{
- int thiscb = cb;
- memcpy(this, buf, cb);
- unix_path_name_ = win32_path_name_ = NULL;
- set_name (unix_name, win32_name);
- debug_printf ("access_ %p, status %p, io_handle %p, output_handle %p",
- access_, status, get_io_handle (), get_output_handle ());
- if (thiscb != cb)
- system_printf ("mismatch in linearize/delinearize %d != %d", thiscb, cb);
- raixput = raixget = ralen = rabuflen = 0;
- rabuf = NULL;
- return cb;
-}
-
/* Cover function to WriteFile to provide Posix interface and semantics
(as much as possible). */
int
directory. This is used, to set S_ISVTX, if needed. */
if (local.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
buf->st_mode |= S_IFDIR;
- if (! get_file_attribute (has_acls (),
- get_win32_name (),
- &buf->st_mode,
- &buf->st_uid,
- &buf->st_gid))
+ if (!get_file_attribute (has_acls (),
+ get_win32_name (),
+ &buf->st_mode,
+ &buf->st_uid,
+ &buf->st_gid))
{
/* If read-only attribute is set, modify ntsec return value */
if (local.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
buf->st_mode = 0;
buf->st_mode |= STD_RBITS;
- if (! (local.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
+ if (!(local.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
buf->st_mode |= STD_WBITS;
/* | S_IWGRP | S_IWOTH; we don't give write to group etc */
return -1;
}
+void
+fhandler_base::operator delete (void *p)
+{
+ cfree (p);
+ return;
+}
+
/* Normal I/O constructor */
fhandler_base::fhandler_base (DWORD devtype, const char *name, int unit):
access_ (0),
if (!no_free_names ())
{
if (unix_path_name_ != NULL && unix_path_name_ != fhandler_disk_dummy_name)
- free (unix_path_name_);
+ cfree (unix_path_name_);
if (win32_path_name_ != NULL && win32_path_name_ != fhandler_disk_dummy_name)
- free (win32_path_name_);
+ cfree (win32_path_name_);
}
+ if (rabuf)
+ free (rabuf);
unix_path_name_ = win32_path_name_ = NULL;
}
void set_name (const char * unix_path, const char * win32_path = NULL,
int unit = 0);
- virtual fhandler_base& operator =(fhandler_base &x)
- {
- memcpy (this, &x, sizeof *this);
- unix_path_name_ = x.unix_path_name_ ? strdup (x.unix_path_name_) : NULL;
- win32_path_name_ = x.win32_path_name_ ? strdup (x.win32_path_name_) : NULL;
- return *this;
- };
+ virtual fhandler_base& operator =(fhandler_base &x);
fhandler_base (DWORD dev, const char *name = 0, int unit = 0);
virtual ~fhandler_base ();
unsigned long get_namehash () { return namehash_; }
virtual void hclose (HANDLE h) {CloseHandle (h);}
- virtual void set_inheritance (HANDLE &h, int not_inheriting, const char *name = NULL);
+ virtual void set_inheritance (HANDLE &h, int not_inheriting,
+ const char *name = NULL);
/* fixup fd possibly non-inherited handles after fork */
void fork_fixup (HANDLE parent, HANDLE &h, const char *name);
virtual int raw_read (void *ptr, size_t ulen);
virtual int raw_write (const void *ptr, size_t ulen);
- /* Function to save state of a fhandler_base into memory. */
- virtual int linearize (unsigned char *);
- /* Function to de-linearize into a fd */
- virtual int de_linearize (const char *, const char *, const char *);
+ virtual void fixup_after_exec (HANDLE) {}
/* Virtual accessor functions to hide the fact
that some fd's have two handles. */
return windows_device_names[FHDEVN (status)];
}
virtual int bg_check (int) {return 1;}
+ void clear_readahead ()
+ {
+ raixput = raixget = ralen = rabuflen = 0;
+ rabuf = NULL;
+ }
+ void operator delete (void *);
};
class fhandler_socket: public fhandler_base
public:
~fhandler_dev_raw (void);
- /* Function to de-linearize into a fd */
- int de_linearize (const char *, const char *, const char *);
-
int open (const char *path, int flags, mode_t mode = 0);
int close (void);
void dump ();
int is_tty () { return 1; }
void fixup_after_fork (HANDLE parent);
- int de_linearize (const char *, const char *, const char *);
+ void fixup_after_exec (HANDLE);
/* We maintain a pgrp so that tcsetpgrp and tcgetpgrp work, but we
don't use it for permissions checking. fhandler_tty_slave does
select_record *select_write (select_record *s);
select_record *select_except (select_record *s);
int ready_for_read (int fd, DWORD howlong, int ignra);
- int de_linearize (const char *, const char *, const char *);
+ void fixup_after_exec (HANDLE);
void set_close_on_exec (int val);
void fixup_after_fork (HANDLE parent);
void set_input_state ()
int init (int);
int init_console ();
void fixup_after_fork (HANDLE parent);
- int de_linearize (const char *, const char *, const char *);
+ void fixup_after_exec (HANDLE);
};
class fhandler_dev_null: public fhandler_base
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
-/* FIXMES:
- Should the constructor call tcinit() explicitly rather than having
- it sprinkled throughout here? */
-
#include "winsup.h"
#include <sys/termios.h>
#include <stdio.h>
#include <unistd.h>
#include <wingdi.h>
#include <winuser.h>
+#include <wincon.h>
#include <ctype.h>
#include "cygerrno.h"
#include "fhandler.h"
debug_printf ("title '%s'", buf);
}
-int
-fhandler_console::de_linearize (const char *buf, const char *unix_name,
- const char *win32_name)
+void
+fhandler_console::fixup_after_exec (HANDLE)
{
- int res = fhandler_base::de_linearize (buf, unix_name, win32_name);
HANDLE h = get_handle ();
HANDLE oh = get_output_handle ();
CloseHandle (h);
CloseHandle (oh);
- return res;
+ return;
}
#define URANDOM 9
#define PSEUDO_MULTIPLIER (6364136223846793005LL)
-#define PSEUDO_SHIFTVAL (21)
+#define PSEUDO_SHIFTVAL (21)
fhandler_dev_random::fhandler_dev_random (const char *name, int nunit)
: fhandler_base (FH_RANDOM, name),
{
if (!crypt_prov
&& !CryptAcquireContext (&crypt_prov, NULL, MS_DEF_PROV, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)
+ CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)
&& !CryptAcquireContext (&crypt_prov, NULL, MS_DEF_PROV, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET
- | CRYPT_NEWKEYSET))
+ CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET
+ | CRYPT_NEWKEYSET))
{
debug_printf ("%E = CryptAquireContext()");
return FALSE;
{
if (crypt_prov)
while (!CryptReleaseContext (crypt_prov, 0)
- && GetLastError () == ERROR_BUSY)
+ && GetLastError () == ERROR_BUSY)
Sleep(10);
return 0;
}
#include <cygwin/rdevio.h>
#include <sys/mtio.h>
+#include "cygheap.h"
#include "cygerrno.h"
#include "fhandler.h"
#include "path.h"
also related to the used tape device. */
static BOOL write_file (HANDLE fh, const void *buf, DWORD to_write,
- DWORD *written, int *err)
+ DWORD *written, int *err)
{
BOOL ret;
if (!(ret = WriteFile (fh, buf, to_write, written, 0)))
{
if ((*err = GetLastError ()) == ERROR_MEDIA_CHANGED
- || *err == ERROR_BUS_RESET)
- {
- *err = 0;
- if (!(ret = WriteFile (fh, buf, to_write, written, 0)))
- *err = GetLastError ();
- }
+ || *err == ERROR_BUS_RESET)
+ {
+ *err = 0;
+ if (!(ret = WriteFile (fh, buf, to_write, written, 0)))
+ *err = GetLastError ();
+ }
}
syscall_printf ("%d (err %d) = WriteFile (%d, %d, write %d, written %d, 0)",
- ret, *err, fh, buf, to_write, *written);
+ ret, *err, fh, buf, to_write, *written);
return ret;
}
static BOOL read_file (HANDLE fh, void *buf, DWORD to_read,
- DWORD *read, int *err)
+ DWORD *read, int *err)
{
BOOL ret;
if (!(ret = ReadFile(fh, buf, to_read, read, 0)))
{
if ((*err = GetLastError ()) == ERROR_MEDIA_CHANGED
- || *err == ERROR_BUS_RESET)
- {
- *err = 0;
- if (!(ret = ReadFile (fh, buf, to_read, read, 0)))
- *err = GetLastError ();
- }
+ || *err == ERROR_BUS_RESET)
+ {
+ *err = 0;
+ if (!(ret = ReadFile (fh, buf, to_read, read, 0)))
+ *err = GetLastError ();
+ }
}
syscall_printf ("%d (err %d) = ReadFile (%d, %d, to_read %d, read %d, 0)",
- ret, *err, fh, buf, to_read, *read);
+ ret, *err, fh, buf, to_read, *read);
return ret;
}
memset (devbuf + devbufend, 0, devbufsiz - devbufend);
if (get_device () != FH_TAPE)
- to_write = ((devbufend - 1) / 512 + 1) * 512;
+ to_write = ((devbufend - 1) / 512 + 1) * 512;
else if (varblkop)
- to_write = devbufend;
+ to_write = devbufend;
else
- to_write = devbufsiz;
+ to_write = devbufsiz;
if (!write_file (get_handle (), devbuf, to_write, &written, &ret)
- && is_eom (ret))
+ && is_eom (ret))
eom_detected = 1;
if (written)
has_written = 1;
fhandler_dev_raw::~fhandler_dev_raw (void)
{
- delete[]devbuf;
+ if (devbufsiz >= 1L)
+ cfree (devbuf);
clear ();
}
int
-fhandler_dev_raw::de_linearize (const char *buf, const char *unix_name,
- const char *win32_name)
-{
- int ret = fhandler_base::de_linearize (buf, unix_name, win32_name);
- if (devbufsiz > 1L)
- {
- devbuf = new char[devbufsiz];
- devbufstart = devbufend = 0;
- }
- return ret;
-}
-
-int
fhandler_dev_raw::open (const char *path, int flags, mode_t)
{
path_conv real_path (path, PC_SYM_IGNORE);
if (ret)
{
if (devbufsiz > 1L)
- devbuf = new char[devbufsiz];
+ devbuf = (char *) cmalloc (HEAP_BUF, devbufsiz);
}
else
devbufsiz = 0;
memset (buf, 0, sizeof *buf);
buf->st_mode = S_IFCHR |
- S_IRUSR | S_IWUSR |
- S_IRGRP | S_IWGRP |
- S_IROTH | S_IWOTH;
+ S_IRUSR | S_IWUSR |
+ S_IRGRP | S_IWGRP |
+ S_IROTH | S_IWOTH;
buf->st_nlink = 1;
buf->st_blksize = devbuf ? devbufsiz : 1;
buf->st_dev = buf->st_rdev = get_device () << 8 | (unit & 0xff);
{
if (!varblkop && len >= devbufsiz)
{
- if (get_device () == FH_TAPE)
+ if (get_device () == FH_TAPE)
bytes_to_read = (len / devbufsiz) * devbufsiz;
- else
+ else
bytes_to_read = (len / 512) * 512;
tgt = (char *) ptr;
debug_printf ("read %d bytes direct from file",bytes_to_read);
{
bytes_to_read = devbufsiz;
tgt = devbuf;
- if (varblkop)
+ if (varblkop)
debug_printf ("read variable bytes from file into buffer");
- else
+ else
debug_printf ("read %d bytes from file into buffer",
bytes_to_read);
}
{
if (!is_eof (ret) && !is_eom (ret))
{
- debug_printf ("return -1, set errno to EACCES");
+ debug_printf ("return -1, set errno to EACCES");
set_errno (EACCES);
return -1;
}
{
if (!bytes_read && is_eom (ret))
{
- debug_printf ("return -1, set errno to ENOSPC");
+ debug_printf ("return -1, set errno to ENOSPC");
set_errno (ENOSPC);
return -1;
}
{
if (!is_eof (ret) && !is_eom (ret))
{
- debug_printf ("return -1, set errno to EACCES");
+ debug_printf ("return -1, set errno to EACCES");
set_errno (EACCES);
return -1;
}
}
else if (is_eom (ret))
{
- debug_printf ("return -1, set errno to ENOSPC");
+ debug_printf ("return -1, set errno to ENOSPC");
set_errno (ENOSPC);
return -1;
}
while (len > 0)
{
if (!varblkop &&
- (len < devbufsiz || devbufend > 0) && devbufend < devbufsiz)
+ (len < devbufsiz || devbufend > 0) && devbufend < devbufsiz)
{
bytes_to_write = min (len, devbufsiz - devbufend);
memcpy (devbuf + devbufend, p, bytes_to_write);
fhc->devbufsiz = devbufsiz;
if (devbufsiz > 1L)
{
- fhc->devbuf = new char[devbufsiz];
+ fhc->devbuf = (char *) cmalloc (HEAP_BUF, devbufsiz);
memcpy (fhc->devbuf, devbuf, devbufend);
}
fhc->devbufstart = devbufstart;
ret = ERROR_INVALID_PARAMETER;
else if (!devbuf || op->rd_parm != devbufsiz)
{
- char *buf = new char[op->rd_parm];
+ char *buf = (char *) cmalloc (HEAP_BUF, op->rd_parm);
if (devbuf)
{
memcpy (buf, devbuf + devbufstart, devbufend - devbufstart);
devbufend -= devbufstart;
- delete[]devbuf;
+ cfree (devbuf);
}
else
devbufend = 0;
state.Parity = NOPARITY;
state.fBinary = TRUE; /* Binary transfer */
- state.EofChar = 0; /* No end-of-data in binary mode */
+ state.EofChar = 0; /* No end-of-data in binary mode */
state.fNull = FALSE; /* Don't discard nulls in binary mode */
/* -------------- Parity errors ------------------ */
debug_printf ("io_status.hEvent %p", io_status.hEvent);
}
-int
-fhandler_serial::de_linearize (const char *buf, const char *unix_name,
- const char *win32_name)
+void
+fhandler_serial::fixup_after_exec (HANDLE)
{
- int res = fhandler_base::de_linearize (buf, unix_name, win32_name);
overlapped_setup ();
debug_printf ("io_status.hEvent %p", io_status.hEvent);
- return res;
+ return;
}
int
struct mtpos pos;
if (! ioctl (MTIOCGET, &get))
- /* Tape drive supports and is set to variable block size. */
- if (get.mt_dsreg == 0)
- devbufsiz = get.mt_maxblksize;
- else
+ /* Tape drive supports and is set to variable block size. */
+ if (get.mt_dsreg == 0)
+ devbufsiz = get.mt_maxblksize;
+ else
devbufsiz = get.mt_dsreg;
- varblkop = get.mt_dsreg == 0;
+ varblkop = get.mt_dsreg == 0;
if (devbufsiz > 1L)
devbuf = new char [ devbufsiz ];
break;
}
if ((op->mt_count == 0
- && !tape_get_feature (TAPE_DRIVE_VARIABLE_BLOCK))
- || (op->mt_count > 0
- && (op->mt_count < min || op->mt_count > max)))
+ && !tape_get_feature (TAPE_DRIVE_VARIABLE_BLOCK))
+ || (op->mt_count > 0
+ && (op->mt_count < min || op->mt_count > max)))
{
ret = ERROR_INVALID_PARAMETER;
break;
}
if (devbuf && op->mt_count > 0
- && (size_t) op->mt_count < devbufend - devbufstart)
+ && (size_t) op->mt_count < devbufend - devbufstart)
{
ret = ERROR_MORE_DATA;
break;
}
if (! (ret = tape_set_blocksize (op->mt_count)))
{
- size_t size = 0;
- if (op->mt_count == 0)
- {
- struct mtget get;
- if ((ret = tape_status (&get)) != NO_ERROR)
- break;
- size = get.mt_maxblksize;
- ret = NO_ERROR;
- }
+ size_t size = 0;
+ if (op->mt_count == 0)
+ {
+ struct mtget get;
+ if ((ret = tape_status (&get)) != NO_ERROR)
+ break;
+ size = get.mt_maxblksize;
+ ret = NO_ERROR;
+ }
char *buf = new char [ size ];
- if (!buf)
- {
- ret = ERROR_OUTOFMEMORY;
- break;
- }
+ if (!buf)
+ {
+ ret = ERROR_OUTOFMEMORY;
+ break;
+ }
if (devbuf)
{
memcpy(buf,devbuf + devbufstart, devbufend - devbufstart);
devbufstart = 0;
devbuf = buf;
devbufsiz = size;
- varblkop = op->mt_count == 0;
+ varblkop = op->mt_count == 0;
}
}
break;
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
+#include "cygheap.h"
/* Tty master stuff */
ttynum = num;
/* FIXME: This is wasteful. We should rewrite the set_name path to eliminate the
need for double allocates. */
- unix_path_name_ = (char *) realloc (unix_path_name_, strlen(win32_path_name_) + 1);
+ unix_path_name_ = (char *) crealloc (unix_path_name_, strlen(win32_path_name_) + 1);
strcpy (unix_path_name_, win32_path_name_);
unix_path_name_[0] = unix_path_name_[4] = '/';
debug_printf ("unix '%s', win32 '%s'", unix_path_name_, win32_path_name_);
console->fixup_after_fork (child);
}
-int
-fhandler_tty_master::de_linearize (const char *buf, const char *unix_name,
- const char *win32_name)
+void
+fhandler_tty_master::fixup_after_exec (HANDLE)
{
- int res = fhandler_base::de_linearize (buf, unix_name, win32_name);
console->close ();
init_console ();
- return res;
+ return;
}
int
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
+#include "cygheap.h"
#include "child_info.h"
#include "perthread.h"
void
per_thread::set (void *s)
- {
- if (s == PER_THREAD_FORK_CLEAR)
- {
- tls = TlsAlloc ();
- s = NULL;
- }
- TlsSetValue (get_tls (), s);
- }
+{
+ if (s == PER_THREAD_FORK_CLEAR)
+ {
+ tls = TlsAlloc ();
+ s = NULL;
+ }
+ TlsSetValue (get_tls (), s);
+}
static void
stack_base (child_info_fork &ch)
hParent = NULL;
if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hParent, 0, 1,
- DUPLICATE_SAME_ACCESS))
+ DUPLICATE_SAME_ACCESS))
{
system_printf ("couldn't create handle to myself for child, %E");
goto cleanup;
/* Remove impersonation */
uid_t uid = geteuid();
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
- seteuid (myself->orig_uid);
+ seteuid (myself->orig_uid);
char sa_buf[1024];
rc = CreateProcessA (myself->progname, /* image to run */
myself->progname, /* what we send in arg0 */
- allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
- allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
+ allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
+ allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
TRUE, /* inherit handles from parent */
c_flags,
NULL, /* environment filled in later */
ForceCloseHandle(subproc_ready);
ForceCloseHandle(forker_finished);
subproc_ready = forker_finished = NULL;
- /* Restore impersonation */
- if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
- seteuid (uid);
+ /* Restore impersonation */
+ if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
+ seteuid (uid);
return -1;
}
/* Restore impersonation */
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
- seteuid (uid);
+ seteuid (uid);
ProtectHandle (pi.hThread);
/* Protect the handle but name it similarly to the way it will
if (last_fork_proc)
CloseHandle (last_fork_proc);
if (!DuplicateHandle (hMainProc, pi.hProcess, hMainProc, &last_fork_proc,
- 0, FALSE, DUPLICATE_SAME_ACCESS))
+ 0, FALSE, DUPLICATE_SAME_ACCESS))
system_printf ("couldn't create last_fork_proc, %E");
}
debug_printf ("pid %d, ppid %d", x, myself->ppid);
/* Restore the inheritance state as in parent
- Don't call setuid here! The flags are already set. */
+ Don't call setuid here! The flags are already set. */
if (myself->impersonated)
- {
- debug_printf ("Impersonation of child, token: %d", myself->token);
- if (myself->token == INVALID_HANDLE_VALUE)
- RevertToSelf (); // probably not needed
- else if (!ImpersonateLoggedOnUser (myself->token))
- system_printf ("Impersonate for forked child failed: %E");
- }
+ {
+ debug_printf ("Impersonation of child, token: %d", myself->token);
+ if (myself->token == INVALID_HANDLE_VALUE)
+ RevertToSelf (); // probably not needed
+ else if (!ImpersonateLoggedOnUser (myself->token))
+ system_printf ("Impersonate for forked child failed: %E");
+ }
sync_with_parent ("after longjmp.", TRUE);
ProtectHandle (hParent);
MALLOC_CHECK;
+ cygheap_fixup_in_child (hParent);
fdtab.fixup_after_fork (hParent);
signal_fixup_after_fork ();
exec_fixup_after_fork ();
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
+#include "heap.h"
-#define brksize ((char *) user_data->heaptop - (char *) user_data->heapbase)
-#define brk (user_data->heapptr)
-#define brkbase (user_data->heapbase)
-#define brktop (user_data->heaptop)
-#define brkchunk (cygwin_shared->heap_chunk_size ())
#define assert(x)
static unsigned page_const = 0;
--- /dev/null
+/* heap.h: Cygwin heap manager definitions.
+
+ Copyright 2000 Cygnus Solutions.
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+/* Heap management. */
+void heap_init (void);
+void malloc_init (void);
+
+#define inheap(s) (brk && ((char *) (s) >= (char *) brkbase) && ((char *) (s) <= (char *) brktop))
+
+#define brksize ((char *) user_data->heaptop - (char *) user_data->heapbase)
+#define brk (user_data->heapptr)
+#define brkbase (user_data->heapbase)
+#define brktop (user_data->heaptop)
+#define brkchunk (cygwin_shared->heap_chunk_size ())
+
if (user_data->threadinterface)
{
if ( !TlsSetValue(user_data->threadinterface->reent_index,
- &user_data->threadinterface->reents))
+ &user_data->threadinterface->reents))
api_fatal("Sig proc MT init failed\n");
}
break;
#include "winsup.h"
#include <stdlib.h>
+#include <assert.h>
+#include "cygheap.h"
+#include "heap.h"
#include "sync.h"
/* we provide these stubs to call into a user's
_free_r (struct _reent *, void *p)
{
export_malloc_called = 1;
+ assert (!incygheap (p));
+ assert (inheap (p));
free (p);
}
#undef free
_realloc_r (struct _reent *, void *p, size_t size)
{
export_malloc_called = 1;
+ assert (!incygheap (p));
+ assert (inheap (p));
return realloc (p, size);
}
#undef realloc
res = user_data->calloc (nmemb, size);
return res;
}
+
+extern "C" char *
+strdup (const char *s)
+{
+ char *p;
+ size_t len = strlen (s) + 1;
+ if ((p = (char *) malloc (len)) != NULL)
+ memcpy (p, s, len);
+ return p;
+}
+
+extern "C" char *
+_strdup_r (struct _reent *, const char *s)
+{
+ return strdup (s);
+}
#endif
/* These routines are used by the application if it
return res;
}
-extern "C" char *
-strdup (const char *s)
-{
- char *p;
- size_t len = strlen (s) + 1;
- if ((p = (char *) malloc (len)) != NULL)
- memcpy (p, s, len);
- return p;
-}
-
-extern "C" char *
-_strdup_r (struct _reent *, const char *s)
-{
- return strdup (s);
-}
-
/* We use a critical section to lock access to the malloc data
structures. This permits malloc to be called from different
threads. Note that it does not make malloc reentrant, and it does
{
set_errno (EBADF);
syscall_printf ("-1 = mmap(): EBADF");
- ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
+ ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return (caddr_t) -1;
}
hFile = fdtab[fd]->get_handle ();
__seterrno ();
syscall_printf ("-1 = mmap(): MapViewOfFileEx failed with %E");
CloseHandle (h);
- ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
+ ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return (caddr_t) -1;
}
}
__seterrno ();
syscall_printf ("-1 = mmap(): MapViewOfFile failed with %E");
CloseHandle (h);
- ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
+ ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return (caddr_t) -1;
}
}
CloseHandle (h);
set_errno (ENOMEM);
syscall_printf ("-1 = mmap(): ENOMEM");
- ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
+ ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return (caddr_t) -1;
}
l = mmapped_areas->add_list (l, fd);
/* Delete the entry. */
l->erase (li);
syscall_printf ("0 = munmap(): %x", addr);
- ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," munmap");
+ ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," munmap");
return 0;
}
}
soc = socket (AF_INET, type, 0);
if (soc == INVALID_SOCKET)
- {
- set_winsock_errno ();
- goto done;
- }
+ {
+ set_winsock_errno ();
+ goto done;
+ }
soc = duplicate_socket (soc);
const char *name;
if (af == AF_INET)
- name = (type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp");
+ name = (type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp");
else
- name = (type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket");
+ name = (type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket");
fdsock (fd, name, soc);
res = fd;
int len = sizeof sin;
int fd;
- if (strlen (un_addr->sun_path) >= UNIX_PATH_LEN)
- {
- set_errno (ENAMETOOLONG);
- goto out;
- }
+ if (strlen (un_addr->sun_path) >= UNIX_PATH_LEN)
+ {
+ set_errno (ENAMETOOLONG);
+ goto out;
+ }
sin.sin_family = AF_INET;
sin.sin_port = 0;
sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
sin.sin_port = ntohs (sin.sin_port);
debug_printf ("AF_UNIX: socket bound to port %u", sin.sin_port);
- /* bind must fail if file system socket object already exists
- so _open() is called with O_EXCL flag. */
+ /* bind must fail if file system socket object already exists
+ so _open() is called with O_EXCL flag. */
fd = _open (un_addr->sun_path,
- O_WRONLY | O_CREAT | O_EXCL | O_BINARY,
- 0);
+ O_WRONLY | O_CREAT | O_EXCL | O_BINARY,
+ 0);
if (fd < 0)
- {
- if (get_errno () == EEXIST)
- set_errno (EADDRINUSE);
+ {
+ if (get_errno () == EEXIST)
+ set_errno (EADDRINUSE);
goto out;
- }
+ }
- char buf[sizeof (SOCKET_COOKIE) + 10];
- __small_sprintf (buf, "%s%u", SOCKET_COOKIE, sin.sin_port);
- len = strlen (buf) + 1;
+ char buf[sizeof (SOCKET_COOKIE) + 10];
+ __small_sprintf (buf, "%s%u", SOCKET_COOKIE, sin.sin_port);
+ len = strlen (buf) + 1;
- /* Note that the terminating nul is written. */
- if (_write (fd, buf, len) != len)
- {
+ /* Note that the terminating nul is written. */
+ if (_write (fd, buf, len) != len)
+ {
save_errno here;
- _close (fd);
- _unlink (un_addr->sun_path);
- }
- else
- {
- _close (fd);
- chmod (un_addr->sun_path,
- (S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO) & ~myself->umask);
+ _close (fd);
+ _unlink (un_addr->sun_path);
+ }
+ else
+ {
+ _close (fd);
+ chmod (un_addr->sun_path,
+ (S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO) & ~myself->umask);
res = 0;
- }
+ }
#undef un_addr
}
else if (bind (sock->get_socket (), my_addr, addrlen))
* \Device\<Netcard>, where netcard is the name of the net device.
* Then look under:
* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<NetCard>\
- * Parameters\Tcpip
+ * Parameters\Tcpip
* at the IPAddress, Subnetmask and DefaultGateway values for the
* required values.
*
case SIOCGIFNETMASK:
case SIOCGIFADDR:
{
- char buf[2048];
- struct ifconf ifc;
- ifc.ifc_len = sizeof(buf);
- ifc.ifc_buf = buf;
- struct ifreq *ifrp;
-
- struct ifreq *ifr = (struct ifreq *) p;
- if (ifr == 0)
- {
- debug_printf("ifr == NULL\n");
- set_errno (EINVAL);
- return -1;
- }
+ char buf[2048];
+ struct ifconf ifc;
+ ifc.ifc_len = sizeof(buf);
+ ifc.ifc_buf = buf;
+ struct ifreq *ifrp;
+
+ struct ifreq *ifr = (struct ifreq *) p;
+ if (ifr == 0)
+ {
+ debug_printf("ifr == NULL\n");
+ set_errno (EINVAL);
+ return -1;
+ }
res = get_ifconf (&ifc, cmd);
- if (res)
+ if (res)
{
debug_printf ("error in get_ifconf\n");
break;
}
- debug_printf(" name: %s\n", ifr->ifr_name);
- for (ifrp = ifc.ifc_req;
- (caddr_t) ifrp < ifc.ifc_buf + ifc.ifc_len;
- ++ifrp)
- {
- debug_printf("testname: %s\n", ifrp->ifr_name);
- if (! strcmp (ifrp->ifr_name, ifr->ifr_name))
- {
- switch (cmd)
+ debug_printf(" name: %s\n", ifr->ifr_name);
+ for (ifrp = ifc.ifc_req;
+ (caddr_t) ifrp < ifc.ifc_buf + ifc.ifc_len;
+ ++ifrp)
+ {
+ debug_printf("testname: %s\n", ifrp->ifr_name);
+ if (! strcmp (ifrp->ifr_name, ifr->ifr_name))
+ {
+ switch (cmd)
{
case SIOCGIFADDR:
ifr->ifr_addr = ifrp->ifr_addr;
ifr->ifr_netmask = ifrp->ifr_netmask;
break;
}
- break;
- }
- }
- if ((caddr_t) ifrp >= ifc.ifc_buf + ifc.ifc_len)
- {
- set_errno (EINVAL);
- return -1;
- }
- break;
+ break;
+ }
+ }
+ if ((caddr_t) ifrp >= ifc.ifc_buf + ifc.ifc_len)
+ {
+ set_errno (EINVAL);
+ return -1;
+ }
+ break;
}
case FIOASYNC:
res = WSAAsyncSelect (get_socket (), gethwnd (), WM_ASYNCIO,
}
fclose (f);
- passwd_state = loaded;
+ passwd_state = loaded;
}
else
{
- debug_printf ("Emulating /etc/passwd");
- char user_name [ MAX_USER_NAME ];
- DWORD user_name_len = MAX_USER_NAME;
- if (! GetUserNameA (user_name, &user_name_len))
- {
- strncpy (user_name, "Administrator", MAX_USER_NAME);
- debug_printf ("Failed to get current user name. %E");
- }
- snprintf (linebuf, sizeof (linebuf), "%s::%u:%u::%s:/bin/sh", user_name,
+ debug_printf ("Emulating /etc/passwd");
+ char user_name [ MAX_USER_NAME ];
+ DWORD user_name_len = MAX_USER_NAME;
+ if (! GetUserNameA (user_name, &user_name_len))
+ {
+ strncpy (user_name, "Administrator", MAX_USER_NAME);
+ debug_printf ("Failed to get current user name. %E");
+ }
+ snprintf (linebuf, sizeof (linebuf), "%s::%u:%u::%s:/bin/sh", user_name,
DEFAULT_UID, DEFAULT_GID, getenv ("HOME") ?: "/");
- add_pwd_line (linebuf);
- passwd_state = emulated;
+ add_pwd_line (linebuf);
+ passwd_state = emulated;
}
}
{
res = passwd_buf + i;
if (res->pw_uid == DEFAULT_UID)
- default_pw = res;
+ default_pw = res;
/* on Windows NT user names are case-insensitive */
if (name)
{
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
+#include "cygheap.h"
static int normalize_win32_path (const char *cwd, const char *src, char *dst);
static char *getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot);
/* Cache getcwd value. FIXME: We need a lock for these in order to
support multiple threads. */
-#ifdef _MT_SAFE
-#define cwd_win32 _reent_winsup()->_cwd_win32
-#define cwd_posix _reent_winsup()->_cwd_posix
-#define cwd_hash _reent_winsup()->_cwd_hash
-#else
-static char *cwd_win32;
-static char *cwd_posix;
-static unsigned long cwd_hash;
-#endif
+#define TMPCWD ((char *) alloca (MAX_PATH + 1))
+
+struct cwdstuff
+{
+ char *posix;
+ char *win32;
+ DWORD hash;
+ muto *lock;
+};
+
+cwdstuff cwd;
+
+char * __stdcall
+cwd_win32 (char *buf)
+{
+ char *ret;
+ cwd.lock->acquire ();
+ if (cwd.win32 == NULL)
+ ret = NULL;
+ else if (buf == NULL)
+ ret = cwd.win32;
+ else
+ ret = strcpy (buf, cwd.win32);
+ cwd.lock->release ();
+ return ret;
+}
+
+char * __stdcall
+cwd_posix (char *buf)
+{
+ char *ret;
+ cwd.lock->acquire ();
+ if (cwd.posix == NULL)
+ ret = NULL;
+ else if (buf == NULL)
+ ret = cwd.posix;
+ else
+ ret = strcpy (buf, cwd.posix);
+ cwd.lock->release ();
+ return ret;
+}
+
+DWORD __stdcall
+cwd_hash ()
+{
+ DWORD hashnow;
+ cwd.lock->acquire ();
+ hashnow = cwd.hash;
+ cwd.lock->release ();
+ return hashnow;
+}
+
+void __stdcall
+cwd_init ()
+{
+ cwd.lock = new_muto (FALSE, "cwd");
+}
+
+void __stdcall
+cwd_fixup_after_exec (char *win32, char *posix, DWORD hash)
+{
+ cwd.win32 = win32;
+ cwd.posix = posix;
+ cwd.hash = hash;
+}
#define ischrootpath(path) \
(myself->rootlen && \
if (strpbrk (src_path, ":\\") != NULL)
{
debug_printf ("%s already win32", src_path);
- rc = normalize_win32_path (cwd_win32, src_path, dst);
+ rc = normalize_win32_path (cwd_win32 (TMPCWD), src_path, dst);
if (rc)
{
debug_printf ("normalize_win32_path failed, rc %d", rc);
/* Compute relative path if asked to and able to. */
unsigned cwdlen;
cwdlen = 0; /* avoid a (hopefully) bogus compiler warning */
+ char *cwd_win32_now;
+ cwd_win32_now = cwd_win32 (TMPCWD);
if (win32_path == NULL)
/* nothing to do */;
else if (isrelpath &&
- path_prefix_p (cwd_win32, dst, cwdlen = strlen (cwd_win32)))
+ path_prefix_p (cwd_win32_now, dst, cwdlen = strlen (cwd_win32_now)))
{
size_t n = strlen (dst);
if (n < cwdlen)
if (n == cwdlen)
dst += cwdlen;
else
- dst += isdirsep (cwd_win32[cwdlen - 1]) ? cwdlen : cwdlen + 1;
+ dst += isdirsep (cwd_win32_now[cwdlen - 1]) ? cwdlen : cwdlen + 1;
memmove (win32_path, dst, strlen (dst) + 1);
if (!*win32_path)
Otherwise the inodes same will differ depending on whether a file is
referenced with an absolute value or relatively. */
- if (*name != '\\' && (cwd_win32 == NULL ||
- get_cwd_win32 ()))
+ if (*name != '\\' && (cwd_win32 (TMPCWD) == NULL || get_cwd_win32 ()))
{
- hash = cwd_hash;
+ hash = cwd_hash ();
if (name[0] == '.' && name[1] == '\0')
return hash;
hash = hash_path_name (hash, "\\");
{
DWORD dlen, len;
+ cwd.lock->acquire ();
for (dlen = 256; ; dlen *= 2)
{
- cwd_win32 = (char *) realloc (cwd_win32, dlen + 2);
- if ((len = GetCurrentDirectoryA (dlen, cwd_win32)) < dlen)
+ cwd.win32 = (char *) crealloc (cwd.win32, dlen + 2);
+ if ((len = GetCurrentDirectoryA (dlen, cwd.win32)) < dlen)
break;
}
if (len == 0)
__seterrno ();
else
- cwd_hash = hash_path_name (0, cwd_win32);
+ cwd.hash = hash_path_name (0, cwd.win32);
+ cwd.lock->release ();
return len;
}
char *resbuf = NULL;
size_t len = ulen;
- if (cwd_win32 == NULL && !get_cwd_win32 ())
+ if (cwd_win32 (TMPCWD) == NULL && !get_cwd_win32 ())
return NULL;
+ char *cwd_win32_now = cwd_win32 (TMPCWD);
+ char *cwd_posix_now = cwd_posix (TMPCWD);
if (!posix_p)
{
- if (strlen (cwd_win32) >= len)
+ if (strlen (cwd_win32_now) >= len)
set_errno (ERANGE);
else
{
- strcpy (buf, cwd_win32);
+ strcpy (buf, cwd_win32_now);
resbuf = buf;
}
resbuf, resbuf ? resbuf : "", buf, len);
return resbuf;
}
- else if (cwd_posix != NULL)
+ else if (cwd_posix_now != NULL)
{
- debug_printf("myself->root: %s, cwd_posix: %s", myself->root, cwd_posix);
- if (strlen (cwd_posix) >= len)
+ debug_printf("myself->root: %s, cwd_posix: %s", myself->root, cwd_posix_now);
+ if (strlen (cwd_posix_now) >= len)
set_errno (ERANGE);
- else if (with_chroot && ischrootpath(cwd_posix))
+ else if (with_chroot && ischrootpath(cwd_posix_now))
{
- strcpy (buf, cwd_posix + myself->rootlen);
+ strcpy (buf, cwd_posix_now + myself->rootlen);
if (!buf[0])
strcpy (buf, "/");
resbuf = buf;
}
else
{
- strcpy (buf, cwd_posix);
+ strcpy (buf, cwd_posix_now);
resbuf = buf;
}
char temp[MAX_PATH];
/* Turn from Win32 style to our style. */
- cygwin_shared->mount.conv_to_posix_path (cwd_win32, temp, 0);
+ cygwin_shared->mount.conv_to_posix_path (cwd_win32_now, temp, 0);
size_t tlen = strlen (temp);
if (with_chroot && ischrootpath (temp))
tlen -= myself->rootlen;
- cwd_posix = (char *) realloc (
- cwd_posix, tlen + 1);
- if (cwd_posix != NULL)
+ cwd.lock->acquire ();
+ cwd.posix = (char *) crealloc (cwd.posix, tlen + 1);
+ if (cwd.posix != NULL)
if (with_chroot && ischrootpath (temp))
{
- strcpy (cwd_posix, temp + myself->rootlen);
+ strcpy (cwd.posix, temp + myself->rootlen);
if (!buf[0])
strcpy (buf, "/");
}
else
- strcpy (cwd_posix, temp);
+ strcpy (cwd.posix, temp);
+
+ cwd.lock->release ();
if (tlen >= ulen)
- {
- /* len was too small */
- set_errno (ERANGE);
- }
+ set_errno (ERANGE); /* len was too small */
else
{
strcpy (buf, temp);
__seterrno ();
else
{
+ cwd.lock->acquire ();
/* Store new cache information */
- free (cwd_win32);
- cwd_win32 = strdup (path);
+ cfree (cwd.win32);
+ cwd.win32 = cstrdup (path);
char pathbuf[MAX_PATH];
- (void) normalize_posix_path (cwd_posix, dir, pathbuf);
+ (void) normalize_posix_path (cwd.posix, dir, pathbuf);
/* Look for trailing path component consisting entirely of dots. This
is needed only in case of chdir since Windows simply ignores count
of dots > 2 here instead of returning an error code. Counts of dots
char *last_slash = strrchr (pathbuf, '/');
if (last_slash > pathbuf && strspn (last_slash + 1, ".") == strlen (last_slash + 1))
*last_slash = '\0';
- free (cwd_posix);
- cwd_posix = strdup (pathbuf);
+ cfree (cwd.posix);
+ cwd.posix = cstrdup (pathbuf);
+ cwd.lock->release ();
}
- syscall_printf ("%d = chdir() cwd_posix '%s' native '%s'", res, cwd_posix, native_dir);
+ syscall_printf ("%d = chdir() cwd.posix '%s' native '%s'", res, cwd.posix, native_dir);
return res;
}
const char * __stdcall find_exec (const char *name, path_conv& buf, const char *winenv = "PATH=",
int null_if_notfound = 0, const char **known_suffix = NULL);
+void __stdcall cwd_init ();
+char * __stdcall cwd_posix (char *);
+char * __stdcall cwd_win32 (char *);
+DWORD __stdcall cwd_hash ();
+void __stdcall cwd_fixup_after_exec (char *, char *, DWORD);
/* Common macros for checking for invalid path names */
/* Initialize the process table entry for the current task.
This is not called for fork'd tasks, only exec'd ones. */
void __stdcall
-pinfo_init (LPBYTE info)
+pinfo_init (char **envp)
{
- if (info != NULL)
+ if (envp)
{
- /* The process was execed. Reuse entry from the original
- owner of this pid. */
- environ_init (0); /* Needs myself but affects calls below */
-
+ environ_init (envp);
/* spawn has already set up a pid structure for us so we'll use that */
-
myself->process_state |= PID_CYGPARENT;
-
- /* Inherit file descriptor information from parent in info.
- */
- LPBYTE b = fdtab.de_linearize_fd_array (info);
- extern char title_buf[];
- if (b && *b)
- old_title = strcpy (title_buf, (char *)b);
}
else
{
myself->ctty = -1;
myself->uid = USHRT_MAX;
- environ_init (0); /* call after myself has been set up */
+ environ_init (NULL); /* call after myself has been set up */
}
debug_printf ("pid %d, pgid %d", myself->pid, myself->pgid);
to `set_impersonation_token()'. */
HANDLE token;
BOOL impersonated;
- uid_t orig_uid; /* Remains intact also after impersonation */
- uid_t orig_gid; /* Ditto */
- uid_t real_uid; /* Remains intact on seteuid, replaced by setuid */
- gid_t real_gid; /* Ditto */
+ uid_t orig_uid; /* Remains intact also after impersonation */
+ uid_t orig_gid; /* Ditto */
+ uid_t real_uid; /* Remains intact on seteuid, replaced by setuid */
+ gid_t real_gid; /* Ditto */
/* Filled when chroot() is called by the process or one of it's parents.
Saved without trailing backslash. */
return (pid_t) (os_being_run == winNT) ? pid : -(int) pid;
}
-void __stdcall pinfo_init (BYTE *);
+void __stdcall pinfo_init (char **);
void __stdcall set_myself (pid_t pid, HANDLE h = NULL);
extern pinfo myself;
for (unsigned int i = 0; i < nfds; ++i)
if (!fdtab.not_open (fds[i].fd))
{
- FD_SET (fds[i].fd, open_fds);
- if (fds[i].events & POLLIN)
- FD_SET (fds[i].fd, read_fds);
- if (fds[i].events & POLLOUT)
- FD_SET (fds[i].fd, write_fds);
- if (fds[i].events & POLLPRI)
- FD_SET (fds[i].fd, except_fds);
+ FD_SET (fds[i].fd, open_fds);
+ if (fds[i].events & POLLIN)
+ FD_SET (fds[i].fd, read_fds);
+ if (fds[i].events & POLLOUT)
+ FD_SET (fds[i].fd, write_fds);
+ if (fds[i].events & POLLPRI)
+ FD_SET (fds[i].fd, except_fds);
}
int ret = cygwin_select (max_fd + 1, read_fds, write_fds, except_fds,
- timeout < 0 ? NULL : &tv);
+ timeout < 0 ? NULL : &tv);
for (unsigned int i = 0; i < nfds; ++i)
{
if (!FD_ISSET (fds[i].fd, open_fds))
- fds[i].revents = POLLNVAL;
+ fds[i].revents = POLLNVAL;
else if (fdtab.not_open(fds[i].fd))
- fds[i].revents = POLLHUP;
+ fds[i].revents = POLLHUP;
else if (ret < 0)
- fds[i].revents = POLLERR;
+ fds[i].revents = POLLERR;
else
- {
- fds[i].revents = 0;
- if (FD_ISSET (fds[i].fd, read_fds))
- fds[i].revents |= POLLIN;
- if (FD_ISSET (fds[i].fd, write_fds))
- fds[i].revents |= POLLOUT;
- if (FD_ISSET (fds[i].fd, except_fds))
- fds[i].revents |= POLLPRI;
- }
+ {
+ fds[i].revents = 0;
+ if (FD_ISSET (fds[i].fd, read_fds))
+ fds[i].revents |= POLLIN;
+ if (FD_ISSET (fds[i].fd, write_fds))
+ fds[i].revents |= POLLOUT;
+ if (FD_ISSET (fds[i].fd, except_fds))
+ fds[i].revents |= POLLPRI;
+ }
}
return ret;
key[0] = '\0';
if (!RegQueryValueExA (hkey, "ProfileImagePath", 0, &type,
- (BYTE *)buf, (siz = 256, &siz)))
- ExpandEnvironmentStringsA (buf, key, 256);
+ (BYTE *)buf, (siz = 256, &siz)))
+ ExpandEnvironmentStringsA (buf, key, 256);
RegCloseKey (hkey);
if (key[0])
- return strcpy (path, key);
+ return strcpy (path, key);
}
return NULL;
}
return;
/* Check if user hive is already loaded. */
if (!RegOpenKeyExA (HKEY_USERS, convert_sid_to_string_sid (psid, sid),
- 0, KEY_READ, &hkey))
+ 0, KEY_READ, &hkey))
{
debug_printf ("User registry hive for %s already exists", sid);
RegCloseKey (hkey);
{
strcat (path, "\\NTUSER.DAT");
if ((ret = RegLoadKeyA (HKEY_USERS, sid, path)) != ERROR_SUCCESS)
- debug_printf ("Loading user registry hive for %s failed: %d", sid, ret);
+ debug_printf ("Loading user registry hive for %s failed: %d", sid, ret);
}
}
{
closedir (dirp);
if (nl)
- {
- while (count > 0)
- free (nl[--count]);
- free (nl);
- }
+ {
+ while (count > 0)
+ free (nl[--count]);
+ free (nl);
+ }
/* Ignore errors from closedir() and what not else. */
set_errno (prior_errno);
return -1;
BOOL allow_ntsec = FALSE;
SID_IDENTIFIER_AUTHORITY sid_auth[] = {
- {SECURITY_NULL_SID_AUTHORITY},
- {SECURITY_WORLD_SID_AUTHORITY},
- {SECURITY_LOCAL_SID_AUTHORITY},
- {SECURITY_CREATOR_SID_AUTHORITY},
- {SECURITY_NON_UNIQUE_AUTHORITY},
- {SECURITY_NT_AUTHORITY}
+ {SECURITY_NULL_SID_AUTHORITY},
+ {SECURITY_WORLD_SID_AUTHORITY},
+ {SECURITY_LOCAL_SID_AUTHORITY},
+ {SECURITY_CREATOR_SID_AUTHORITY},
+ {SECURITY_NON_UNIQUE_AUTHORITY},
+ {SECURITY_NT_AUTHORITY}
};
#define DONT_INHERIT (0)
int id = -1;
if (! search_grp)
- {
- if (passwd_sem > 0)
- return 0;
- ++passwd_sem;
-
- struct passwd *pw;
- while ((pw = getpwent ()) != NULL)
- {
- if (get_pw_sid (sid, pw) && EqualSid (psid, sid))
- {
- id = pw->pw_uid;
- break;
- }
- }
- endpwent ();
- --passwd_sem;
- if (id >= 0)
- {
- if (type)
- *type = USER;
- return id;
- }
- }
+ {
+ if (passwd_sem > 0)
+ return 0;
+ ++passwd_sem;
+
+ struct passwd *pw;
+ while ((pw = getpwent ()) != NULL)
+ {
+ if (get_pw_sid (sid, pw) && EqualSid (psid, sid))
+ {
+ id = pw->pw_uid;
+ break;
+ }
+ }
+ endpwent ();
+ --passwd_sem;
+ if (id >= 0)
+ {
+ if (type)
+ *type = USER;
+ return id;
+ }
+ }
if (search_grp || type)
- {
- if (group_sem > 0)
- return 0;
- ++group_sem;
-
- struct group *gr;
- while ((gr = getgrent ()) != NULL)
- {
- if (get_gr_sid (sid, gr) && EqualSid (psid, sid))
- {
- id = gr->gr_gid;
- break;
- }
- }
- endgrent ();
- --group_sem;
- if (id >= 0)
- {
- if (type)
- *type = GROUP;
- return id;
- }
- }
+ {
+ if (group_sem > 0)
+ return 0;
+ ++group_sem;
+
+ struct group *gr;
+ while ((gr = getgrent ()) != NULL)
+ {
+ if (get_gr_sid (sid, gr) && EqualSid (psid, sid))
+ {
+ id = gr->gr_gid;
+ break;
+ }
+ }
+ endgrent ();
+ --group_sem;
+ if (id >= 0)
+ {
+ if (type)
+ *type = GROUP;
+ return id;
+ }
+ }
}
/* We use the RID as default UID/GID */
SID_NAME_USE acc_type;
if (!LookupAccountSid (NULL, psid, account, &acc_len,
- domain, &dom_len, &acc_type))
+ domain, &dom_len, &acc_type))
{
__seterrno ();
return -1;
case SidTypeGroup:
case SidTypeAlias:
case SidTypeWellKnownGroup:
- if (type)
- *type = GROUP;
- if (id == -1)
- {
- struct group *gr = getgrnam (account);
- if (gr)
- id = gr->gr_gid;
- }
- break;
+ if (type)
+ *type = GROUP;
+ if (id == -1)
+ {
+ struct group *gr = getgrnam (account);
+ if (gr)
+ id = gr->gr_gid;
+ }
+ break;
case SidTypeUser:
- if (type)
- *type = USER;
- if (id == -1)
- {
- struct passwd *pw = getpwnam (account);
- if (pw)
- id = pw->pw_uid;
+ if (type)
+ *type = USER;
+ if (id == -1)
+ {
+ struct passwd *pw = getpwnam (account);
+ if (pw)
+ id = pw->pw_uid;
}
- break;
+ break;
default:
- break;
+ break;
}
}
if (id == -1)
legal_sid_type (SID_NAME_USE type)
{
return type == SidTypeUser || type == SidTypeGroup
- || SidTypeAlias || SidTypeWellKnownGroup;
+ || SidTypeAlias || SidTypeWellKnownGroup;
}
BOOL
struct passwd *pw = getpwuid (uid);
gid_t grps[NGROUPS_MAX];
int cnt = getgroups (NGROUPS_MAX, grps,
- pw ? pw->pw_gid : myself->gid,
- pw ? pw->pw_name : myself->username);
+ pw ? pw->pw_gid : myself->gid,
+ pw ? pw->pw_name : myself->username);
int i;
for (i = 0; i < cnt; ++i)
- if (grps[i] == gid)
- break;
+ if (grps[i] == gid)
+ break;
grp_member = (i < cnt);
}
return grp_member;
{
strcat (strcat (strcpy (domuser, myself->domain), "\\"), name);
if (LookupAccountName (NULL, domuser,
- sid, (sidlen = MAX_SID_LEN, &sidlen),
- dom, (domlen = MAX_COMPUTERNAME_LENGTH, &domlen),
- &acc_type)
- && legal_sid_type (acc_type))
- goto got_it;
+ sid, (sidlen = MAX_SID_LEN, &sidlen),
+ dom, (domlen = MAX_COMPUTERNAME_LENGTH, &domlen),
+ &acc_type)
+ && legal_sid_type (acc_type))
+ goto got_it;
if (logsrv && *logsrv
- && LookupAccountName (logsrv, domuser,
- sid, (sidlen = MAX_SID_LEN, &sidlen),
- dom, (domlen = MAX_COMPUTERNAME_LENGTH,&domlen),
- &acc_type)
- && legal_sid_type (acc_type))
- goto got_it;
+ && LookupAccountName (logsrv, domuser,
+ sid, (sidlen = MAX_SID_LEN, &sidlen),
+ dom, (domlen = MAX_COMPUTERNAME_LENGTH,&domlen),
+ &acc_type)
+ && legal_sid_type (acc_type))
+ goto got_it;
}
if (logsrv && *logsrv)
{
if (LookupAccountName (logsrv, name,
- sid, (sidlen = MAX_SID_LEN, &sidlen),
- dom, (domlen = MAX_COMPUTERNAME_LENGTH, &domlen),
- &acc_type)
- && legal_sid_type (acc_type))
- goto got_it;
+ sid, (sidlen = MAX_SID_LEN, &sidlen),
+ dom, (domlen = MAX_COMPUTERNAME_LENGTH, &domlen),
+ &acc_type)
+ && legal_sid_type (acc_type))
+ goto got_it;
if (acc_type == SidTypeDomain)
- {
- strcat (strcat (strcpy (domuser, dom), "\\"), name);
- if (LookupAccountName (logsrv, domuser,
- sid,(sidlen = MAX_SID_LEN, &sidlen),
- dom,(domlen = MAX_COMPUTERNAME_LENGTH,&domlen),
- &acc_type))
- goto got_it;
- }
+ {
+ strcat (strcat (strcpy (domuser, dom), "\\"), name);
+ if (LookupAccountName (logsrv, domuser,
+ sid,(sidlen = MAX_SID_LEN, &sidlen),
+ dom,(domlen = MAX_COMPUTERNAME_LENGTH,&domlen),
+ &acc_type))
+ goto got_it;
+ }
}
if (LookupAccountName (NULL, name,
- sid, (sidlen = MAX_SID_LEN, &sidlen),
- dom, (domlen = 100, &domlen),
- &acc_type)
+ sid, (sidlen = MAX_SID_LEN, &sidlen),
+ dom, (domlen = 100, &domlen),
+ &acc_type)
&& legal_sid_type (acc_type))
goto got_it;
if (acc_type == SidTypeDomain)
{
strcat (strcat (strcpy (domuser, dom), "\\"), name);
if (LookupAccountName (NULL, domuser,
- sid, (sidlen = MAX_SID_LEN, &sidlen),
- dom, (domlen = MAX_COMPUTERNAME_LENGTH, &domlen),
- &acc_type))
- goto got_it;
+ sid, (sidlen = MAX_SID_LEN, &sidlen),
+ dom, (domlen = MAX_COMPUTERNAME_LENGTH, &domlen),
+ &acc_type))
+ goto got_it;
}
debug_printf ("LookupAccountName(%s) %E", name);
__seterrno ();
got_it:
debug_printf ("sid : [%d]", *GetSidSubAuthority((PSID) sid,
- *GetSidSubAuthorityCount((PSID) sid) - 1));
+ *GetSidSubAuthorityCount((PSID) sid) - 1));
if (ret_sid)
memcpy (ret_sid, sid, sidlen);
if (myself->token != hToken)
{
if (myself->token != INVALID_HANDLE_VALUE)
- CloseHandle (myself->token);
+ CloseHandle (myself->token);
myself->token = hToken;
myself->impersonated = FALSE;
}
if (pw->pw_gecos)
{
if ((c = strstr (pw->pw_gecos, "U-")) != NULL &&
- (c == pw->pw_gecos || c[-1] == ','))
- {
- usernamebuf[0] = '\0';
- strncat (usernamebuf, c + 2, 255);
- if ((c = strchr (usernamebuf, ',')) != NULL)
- *c = '\0';
- }
+ (c == pw->pw_gecos || c[-1] == ','))
+ {
+ usernamebuf[0] = '\0';
+ strncat (usernamebuf, c + 2, 255);
+ if ((c = strchr (usernamebuf, ',')) != NULL)
+ *c = '\0';
+ }
}
nt_user = usernamebuf;
if ((c = strchr (nt_user, '\\')) != NULL)
nt_user = c + 1;
}
if (! LogonUserA (nt_user, nt_domain, (char *) password,
- LOGON32_LOGON_INTERACTIVE,
- LOGON32_PROVIDER_DEFAULT,
- &hToken)
+ LOGON32_LOGON_INTERACTIVE,
+ LOGON32_PROVIDER_DEFAULT,
+ &hToken)
|| !SetHandleInformation (hToken,
- HANDLE_FLAG_INHERIT,
- HANDLE_FLAG_INHERIT))
+ HANDLE_FLAG_INHERIT,
+ HANDLE_FLAG_INHERIT))
{
__seterrno ();
return INVALID_HANDLE_VALUE;
DWORD len = 0;
if (! GetFileSecurity (file,
- OWNER_SECURITY_INFORMATION
- | GROUP_SECURITY_INFORMATION
- | DACL_SECURITY_INFORMATION,
- sd_buf, *sd_size, &len))
+ OWNER_SECURITY_INFORMATION
+ | GROUP_SECURITY_INFORMATION
+ | DACL_SECURITY_INFORMATION,
+ sd_buf, *sd_size, &len))
{
__seterrno ();
return -1;
HANDLE fh;
fh = CreateFile (file,
- WRITE_OWNER | WRITE_DAC,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- &sec_none_nih,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
- NULL);
+ WRITE_OWNER | WRITE_DAC,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ &sec_none_nih,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
+ NULL);
if (fh == INVALID_HANDLE_VALUE)
{
&bytes_written, FALSE, TRUE, &context))
{
/* Samba returns ERROR_NOT_SUPPORTED.
- FAT returns ERROR_INVALID_SECURITY_DESCR.
- This shouldn't return as error, but better be ignored. */
+ FAT returns ERROR_INVALID_SECURITY_DESCR.
+ This shouldn't return as error, but better be ignored. */
DWORD ret = GetLastError ();
if (ret != ERROR_NOT_SUPPORTED && ret != ERROR_INVALID_SECURITY_DESCR)
{
static int
get_nt_attribute (const char *file, int *attribute,
- uid_t *uidret, gid_t *gidret)
+ uid_t *uidret, gid_t *gidret)
{
if (os_being_run != winNT)
return 0;
{
*attribute |= S_IRWXU | S_IRWXG | S_IRWXO;
syscall_printf ("file: %s No ACL = %x, uid %d, gid %d",
- file, *attribute, uid, gid);
+ file, *attribute, uid, gid);
return 0;
}
for (DWORD i = 0; i < acl->AceCount; ++i)
{
if (!GetAce (acl, i, (PVOID *) &ace))
- continue;
+ continue;
if (ace->Header.AceFlags & INHERIT_ONLY_ACE)
- continue;
+ continue;
switch (ace->Header.AceType)
- {
- case ACCESS_ALLOWED_ACE_TYPE:
- flags = &allow;
- anti = &deny;
- break;
- case ACCESS_DENIED_ACE_TYPE:
- flags = &deny;
- anti = &allow;
- break;
- default:
- continue;
- }
+ {
+ case ACCESS_ALLOWED_ACE_TYPE:
+ flags = &allow;
+ anti = &deny;
+ break;
+ case ACCESS_DENIED_ACE_TYPE:
+ flags = &deny;
+ anti = &allow;
+ break;
+ default:
+ continue;
+ }
PSID ace_sid = (PSID) &ace->SidStart;
if (owner_sid && EqualSid (ace_sid, owner_sid))
- {
- if (ace->Mask & FILE_READ_DATA)
- *flags |= S_IRUSR;
- if (ace->Mask & FILE_WRITE_DATA)
- *flags |= S_IWUSR;
- if (ace->Mask & FILE_EXECUTE)
- *flags |= S_IXUSR;
- }
+ {
+ if (ace->Mask & FILE_READ_DATA)
+ *flags |= S_IRUSR;
+ if (ace->Mask & FILE_WRITE_DATA)
+ *flags |= S_IWUSR;
+ if (ace->Mask & FILE_EXECUTE)
+ *flags |= S_IXUSR;
+ }
else if (group_sid && EqualSid (ace_sid, group_sid))
- {
- if (ace->Mask & FILE_READ_DATA)
- *flags |= S_IRGRP
- | ((grp_member && !(*anti & S_IRUSR)) ? S_IRUSR : 0);
- if (ace->Mask & FILE_WRITE_DATA)
- *flags |= S_IWGRP
- | ((grp_member && !(*anti & S_IWUSR)) ? S_IWUSR : 0);
- if (ace->Mask & FILE_EXECUTE)
- *flags |= S_IXGRP
- | ((grp_member && !(*anti & S_IXUSR)) ? S_IXUSR : 0);
- }
+ {
+ if (ace->Mask & FILE_READ_DATA)
+ *flags |= S_IRGRP
+ | ((grp_member && !(*anti & S_IRUSR)) ? S_IRUSR : 0);
+ if (ace->Mask & FILE_WRITE_DATA)
+ *flags |= S_IWGRP
+ | ((grp_member && !(*anti & S_IWUSR)) ? S_IWUSR : 0);
+ if (ace->Mask & FILE_EXECUTE)
+ *flags |= S_IXGRP
+ | ((grp_member && !(*anti & S_IXUSR)) ? S_IXUSR : 0);
+ }
else if (EqualSid (ace_sid, get_world_sid ()))
- {
- if (ace->Mask & FILE_READ_DATA)
- *flags |= S_IROTH
- | ((!(*anti & S_IRGRP)) ? S_IRGRP : 0)
- | ((!(*anti & S_IRUSR)) ? S_IRUSR : 0);
- if (ace->Mask & FILE_WRITE_DATA)
- *flags |= S_IWOTH
- | ((!(*anti & S_IWGRP)) ? S_IWGRP : 0)
- | ((!(*anti & S_IWUSR)) ? S_IWUSR : 0);
- if (ace->Mask & FILE_EXECUTE)
- {
- *flags |= S_IXOTH
- | ((!(*anti & S_IXGRP)) ? S_IXGRP : 0)
- | ((!(*anti & S_IXUSR)) ? S_IXUSR : 0);
- // Sticky bit for directories according to linux rules.
- // No sense for files.
- if (! (ace->Mask & FILE_DELETE_CHILD)
- && S_ISDIR(*attribute)
- && !(*anti & S_ISVTX))
- *flags |= S_ISVTX;
- }
- }
+ {
+ if (ace->Mask & FILE_READ_DATA)
+ *flags |= S_IROTH
+ | ((!(*anti & S_IRGRP)) ? S_IRGRP : 0)
+ | ((!(*anti & S_IRUSR)) ? S_IRUSR : 0);
+ if (ace->Mask & FILE_WRITE_DATA)
+ *flags |= S_IWOTH
+ | ((!(*anti & S_IWGRP)) ? S_IWGRP : 0)
+ | ((!(*anti & S_IWUSR)) ? S_IWUSR : 0);
+ if (ace->Mask & FILE_EXECUTE)
+ {
+ *flags |= S_IXOTH
+ | ((!(*anti & S_IXGRP)) ? S_IXGRP : 0)
+ | ((!(*anti & S_IXUSR)) ? S_IXUSR : 0);
+ // Sticky bit for directories according to linux rules.
+ // No sense for files.
+ if (! (ace->Mask & FILE_DELETE_CHILD)
+ && S_ISDIR(*attribute)
+ && !(*anti & S_ISVTX))
+ *flags |= S_ISVTX;
+ }
+ }
}
*attribute &= ~(S_IRWXU|S_IRWXG|S_IRWXO|S_ISVTX);
*attribute |= allow;
int
get_file_attribute (int use_ntsec, const char *file,
- int *attribute, uid_t *uidret, gid_t *gidret)
+ int *attribute, uid_t *uidret, gid_t *gidret)
{
if (use_ntsec && allow_ntsec)
return get_nt_attribute (file, attribute, uidret, gidret);
return 0;
int res = NTReadEA (file, ".UNIXATTR",
- (char *) attribute, sizeof (*attribute));
+ (char *) attribute, sizeof (*attribute));
// symlinks are anything for everyone!
if ((*attribute & S_IFLNK) == S_IFLNK)
}
BOOL add_access_allowed_ace (PACL acl, int offset, DWORD attributes,
- PSID sid, size_t &len_add, DWORD inherit)
+ PSID sid, size_t &len_add, DWORD inherit)
{
if (! AddAccessAllowedAce (acl, ACL_REVISION, attributes, sid))
{
if (GetAce(acl, offset, (PVOID *) &ace))
ace->Header.AceFlags |= inherit;
len_add += sizeof (ACCESS_DENIED_ACE) - sizeof (DWORD)
- + GetLengthSid (sid);
+ + GetLengthSid (sid);
return TRUE;
}
BOOL add_access_denied_ace (PACL acl, int offset, DWORD attributes,
- PSID sid, size_t &len_add, DWORD inherit)
+ PSID sid, size_t &len_add, DWORD inherit)
{
if (! AddAccessDeniedAce (acl, ACL_REVISION, attributes, sid))
{
if (GetAce(acl, offset, (PVOID *) &ace))
ace->Header.AceFlags |= inherit;
len_add += sizeof (ACCESS_DENIED_ACE) - sizeof (DWORD)
- + GetLengthSid (sid);
+ + GetLengthSid (sid);
return TRUE;
}
&& ! lookup_name (owner, logsrv, owner_sid))
return NULL;
debug_printf ("owner: %s [%d]", owner,
- *GetSidSubAuthority((PSID) owner_sid,
+ *GetSidSubAuthority((PSID) owner_sid,
*GetSidSubAuthorityCount((PSID) owner_sid) - 1));
// Get SID and name of new group
{
group_sid = (PSID) group_sid_buf;
if ((! grp || ! get_gr_sid (group_sid, grp))
- && ! lookup_name (grp->gr_name, logsrv, group_sid))
- return NULL;
+ && ! lookup_name (grp->gr_name, logsrv, group_sid))
+ return NULL;
}
else
debug_printf ("no group");
// Construct allow attribute for owner
DWORD owner_allow = (STANDARD_RIGHTS_ALL & ~DELETE)
- | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA;
+ | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA;
if (attribute & S_IRUSR)
owner_allow |= FILE_GENERIC_READ;
if (attribute & S_IWUSR)
// Construct allow attribute for group
DWORD group_allow = STANDARD_RIGHTS_READ
- | FILE_READ_ATTRIBUTES | FILE_READ_EA;
+ | FILE_READ_ATTRIBUTES | FILE_READ_EA;
if (attribute & S_IRGRP)
group_allow |= FILE_GENERIC_READ;
if (attribute & S_IWGRP)
// Construct allow attribute for everyone
DWORD other_allow = STANDARD_RIGHTS_READ
- | FILE_READ_ATTRIBUTES | FILE_READ_EA;
+ | FILE_READ_ATTRIBUTES | FILE_READ_EA;
if (attribute & S_IROTH)
other_allow |= FILE_GENERIC_READ;
if (attribute & S_IWOTH)
else
owner_deny = ~owner_allow & other_allow;
owner_deny &= ~(STANDARD_RIGHTS_READ
- | FILE_READ_ATTRIBUTES | FILE_READ_EA
- | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA);
+ | FILE_READ_ATTRIBUTES | FILE_READ_EA
+ | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA);
DWORD group_deny = ~group_allow & other_allow;
group_deny &= ~(STANDARD_RIGHTS_READ | FILE_READ_ATTRIBUTES | FILE_READ_EA);
// Set deny ACE for owner
if (owner_deny
&& ! add_access_denied_ace (acl, ace_off++, owner_deny,
- owner_sid, acl_len, inherit))
+ owner_sid, acl_len, inherit))
return NULL;
// Set allow ACE for owner
if (! add_access_allowed_ace (acl, ace_off++, owner_allow,
- owner_sid, acl_len, inherit))
+ owner_sid, acl_len, inherit))
return NULL;
// Set deny ACE for group
if (group_deny
&& ! add_access_denied_ace (acl, ace_off++, group_deny,
- group_sid, acl_len, inherit))
+ group_sid, acl_len, inherit))
return NULL;
// Set allow ACE for group
if (! add_access_allowed_ace (acl, ace_off++, group_allow,
- group_sid, acl_len, inherit))
+ group_sid, acl_len, inherit))
return NULL;
// Get owner and group from current security descriptor
&& acl_exists && oacl)
for (DWORD i = 0; i < oacl->AceCount; ++i)
if (GetAce (oacl, i, (PVOID *) &ace))
- {
- PSID ace_sid = (PSID) &ace->SidStart;
- // Check for related ACEs
- if ((cur_owner_sid && EqualSid (ace_sid, cur_owner_sid))
- || (owner_sid && EqualSid (ace_sid, owner_sid))
- || (cur_group_sid && EqualSid (ace_sid, cur_group_sid))
- || (group_sid && EqualSid (ace_sid, group_sid))
- || (EqualSid (ace_sid, get_world_sid ())))
- continue;
- // Add unrelated ACCESS_DENIED_ACE to the beginning but
- // behind the owner_deny, ACCESS_ALLOWED_ACE to the end
- // but in front of the `everyone' ACE.
- if (! AddAce(acl, ACL_REVISION,
- ace->Header.AceType == ACCESS_DENIED_ACE_TYPE ?
- (owner_deny ? 1 : 0) : MAXDWORD,
- (LPVOID) ace, ace->Header.AceSize))
- {
- __seterrno ();
- return NULL;
- }
- acl_len += ace->Header.AceSize;
- ++ace_off;
- }
+ {
+ PSID ace_sid = (PSID) &ace->SidStart;
+ // Check for related ACEs
+ if ((cur_owner_sid && EqualSid (ace_sid, cur_owner_sid))
+ || (owner_sid && EqualSid (ace_sid, owner_sid))
+ || (cur_group_sid && EqualSid (ace_sid, cur_group_sid))
+ || (group_sid && EqualSid (ace_sid, group_sid))
+ || (EqualSid (ace_sid, get_world_sid ())))
+ continue;
+ // Add unrelated ACCESS_DENIED_ACE to the beginning but
+ // behind the owner_deny, ACCESS_ALLOWED_ACE to the end
+ // but in front of the `everyone' ACE.
+ if (! AddAce(acl, ACL_REVISION,
+ ace->Header.AceType == ACCESS_DENIED_ACE_TYPE ?
+ (owner_deny ? 1 : 0) : MAXDWORD,
+ (LPVOID) ace, ace->Header.AceSize))
+ {
+ __seterrno ();
+ return NULL;
+ }
+ acl_len += ace->Header.AceSize;
+ ++ace_off;
+ }
// Set allow ACE for everyone
if (! add_access_allowed_ace (acl, ace_off++, other_allow,
- get_world_sid (), acl_len, inherit))
+ get_world_sid (), acl_len, inherit))
return NULL;
// Set AclSize to computed value
static int
set_nt_attribute (const char *file, uid_t uid, gid_t gid,
- const char *logsrv, int attribute)
+ const char *logsrv, int attribute)
{
if (os_being_run != winNT)
return 0;
int
set_file_attribute (int use_ntsec, const char *file,
- uid_t uid, gid_t gid,
- int attribute, const char *logsrv)
+ uid_t uid, gid_t gid,
+ int attribute, const char *logsrv)
{
// symlinks are anything for everyone!
if ((attribute & S_IFLNK) == S_IFLNK)
if (!use_ntsec || !allow_ntsec)
{
if (! NTWriteEA (file, ".UNIXATTR",
- (char *) &attribute, sizeof (attribute)))
+ (char *) &attribute, sizeof (attribute)))
{
__seterrno ();
return -1;
set_file_attribute (int use_ntsec, const char *file, int attribute)
{
return set_file_attribute (use_ntsec, file,
- myself->uid, myself->gid,
- attribute, myself->logsrv);
+ myself->uid, myself->gid,
+ attribute, myself->logsrv);
}
static int
for (i = 0; i < nentries; ++i)
if ((aclp[i].a_type == type && (id < 0 || aclp[i].a_id == id))
- || !aclp[i].a_type)
+ || !aclp[i].a_type)
return i;
return -1;
}
for (int i = 0; i < nentries; ++i)
{
DWORD allow = STANDARD_RIGHTS_READ
- | FILE_READ_ATTRIBUTES | FILE_READ_EA;
+ | FILE_READ_ATTRIBUTES | FILE_READ_EA;
if (aclbufp[i].a_perm & S_IROTH)
- allow |= FILE_GENERIC_READ;
+ allow |= FILE_GENERIC_READ;
if (aclbufp[i].a_perm & S_IWOTH)
- allow |= STANDARD_RIGHTS_ALL | FILE_GENERIC_WRITE
- | DELETE | FILE_DELETE_CHILD;
+ allow |= STANDARD_RIGHTS_ALL | FILE_GENERIC_WRITE
+ | DELETE | FILE_DELETE_CHILD;
if (aclbufp[i].a_perm & S_IXOTH)
- allow |= FILE_GENERIC_EXECUTE;
+ allow |= FILE_GENERIC_EXECUTE;
// Set inherit property
DWORD inheritance = (aclbufp[i].a_type & ACL_DEFAULT)
- ? INHERIT_ONLY : DONT_INHERIT;
+ ? INHERIT_ONLY : DONT_INHERIT;
// If a specific acl contains a corresponding default entry with
// identical permissions, only one Windows ACE with proper
// inheritance bits is created.
if (!(aclbufp[i].a_type & ACL_DEFAULT)
- && (pos = searchace (aclbufp, nentries,
- aclbufp[i].a_type | ACL_DEFAULT,
- (aclbufp[i].a_type & (USER|GROUP))
- ? aclbufp[i].a_id : -1)) >= 0
- && pos < nentries
- && aclbufp[i].a_perm == aclbufp[pos].a_perm)
- {
- inheritance = INHERIT_ALL;
- // This eliminates the corresponding default entry.
- aclbufp[pos].a_type = 0;
- }
+ && (pos = searchace (aclbufp, nentries,
+ aclbufp[i].a_type | ACL_DEFAULT,
+ (aclbufp[i].a_type & (USER|GROUP))
+ ? aclbufp[i].a_id : -1)) >= 0
+ && pos < nentries
+ && aclbufp[i].a_perm == aclbufp[pos].a_perm)
+ {
+ inheritance = INHERIT_ALL;
+ // This eliminates the corresponding default entry.
+ aclbufp[pos].a_type = 0;
+ }
switch (aclbufp[i].a_type)
- {
- case USER_OBJ:
- case DEF_USER_OBJ:
- allow |= STANDARD_RIGHTS_ALL & ~DELETE;
- if (! add_access_allowed_ace (acl, ace_off++, allow,
- owner_sid, acl_len, inheritance))
- return -1;
- break;
- case USER:
- case DEF_USER:
- if (!(pw = getpwuid (aclbufp[i].a_id))
- || ! get_pw_sid (sid, pw)
- || ! add_access_allowed_ace (acl, ace_off++, allow,
- sid, acl_len, inheritance))
- return -1;
- break;
- case GROUP_OBJ:
- case DEF_GROUP_OBJ:
- if (! add_access_allowed_ace (acl, ace_off++, allow,
- group_sid, acl_len, inheritance))
- return -1;
- break;
- case GROUP:
- case DEF_GROUP:
- if (!(gr = getgrgid (aclbufp[i].a_id))
- || ! get_gr_sid (sid, gr)
- || ! add_access_allowed_ace (acl, ace_off++, allow,
- sid, acl_len, inheritance))
- return -1;
- break;
- case OTHER_OBJ:
- case DEF_OTHER_OBJ:
- if (! add_access_allowed_ace (acl, ace_off++, allow,
- get_world_sid(), acl_len, inheritance))
- return -1;
- break;
- }
+ {
+ case USER_OBJ:
+ case DEF_USER_OBJ:
+ allow |= STANDARD_RIGHTS_ALL & ~DELETE;
+ if (! add_access_allowed_ace (acl, ace_off++, allow,
+ owner_sid, acl_len, inheritance))
+ return -1;
+ break;
+ case USER:
+ case DEF_USER:
+ if (!(pw = getpwuid (aclbufp[i].a_id))
+ || ! get_pw_sid (sid, pw)
+ || ! add_access_allowed_ace (acl, ace_off++, allow,
+ sid, acl_len, inheritance))
+ return -1;
+ break;
+ case GROUP_OBJ:
+ case DEF_GROUP_OBJ:
+ if (! add_access_allowed_ace (acl, ace_off++, allow,
+ group_sid, acl_len, inheritance))
+ return -1;
+ break;
+ case GROUP:
+ case DEF_GROUP:
+ if (!(gr = getgrgid (aclbufp[i].a_id))
+ || ! get_gr_sid (sid, gr)
+ || ! add_access_allowed_ace (acl, ace_off++, allow,
+ sid, acl_len, inheritance))
+ return -1;
+ break;
+ case OTHER_OBJ:
+ case DEF_OTHER_OBJ:
+ if (! add_access_allowed_ace (acl, ace_off++, allow,
+ get_world_sid(), acl_len, inheritance))
+ return -1;
+ break;
+ }
}
// Set AclSize to computed value
acl->AclSize = acl_len;
if (! acl_exists || ! acl)
{
for (pos = 0; pos < MIN_ACL_ENTRIES; ++pos)
- lacl[pos].a_perm = S_IRWXU | S_IRWXG | S_IRWXO;
+ lacl[pos].a_perm = S_IRWXU | S_IRWXG | S_IRWXO;
pos = nentries < MIN_ACL_ENTRIES ? nentries : MIN_ACL_ENTRIES;
memcpy (aclbufp, lacl, pos * sizeof (aclent_t));
return pos;
ACCESS_ALLOWED_ACE *ace;
if (!GetAce (acl, i, (PVOID *) &ace))
- continue;
+ continue;
PSID ace_sid = (PSID) &ace->SidStart;
int id;
int type = 0;
if (EqualSid (ace_sid, owner_sid))
- {
- type = USER_OBJ;
- id = uid;
- }
+ {
+ type = USER_OBJ;
+ id = uid;
+ }
else if (EqualSid (ace_sid, group_sid))
- {
- type = GROUP_OBJ;
- id = gid;
- }
+ {
+ type = GROUP_OBJ;
+ id = gid;
+ }
else if (EqualSid (ace_sid, get_world_sid ()))
- {
- type = OTHER_OBJ;
- id = 0;
- }
+ {
+ type = OTHER_OBJ;
+ id = 0;
+ }
else
- {
- id = get_id_from_sid (ace_sid, FALSE, &type);
- if (type != GROUP)
- {
- int type2 = 0;
- int id2 = get_id_from_sid (ace_sid, TRUE, &type2);
- if (type2 == GROUP)
- {
- id = id2;
- type = GROUP;
- }
- }
- }
+ {
+ id = get_id_from_sid (ace_sid, FALSE, &type);
+ if (type != GROUP)
+ {
+ int type2 = 0;
+ int id2 = get_id_from_sid (ace_sid, TRUE, &type2);
+ if (type2 == GROUP)
+ {
+ id = id2;
+ type = GROUP;
+ }
+ }
+ }
if (!type)
- continue;
+ continue;
if (!(ace->Header.AceFlags & INHERIT_ONLY_ACE))
- {
- if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, id)) >= 0)
- getace (lacl[pos], type, id, ace->Mask, ace->Header.AceType);
- }
+ {
+ if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, id)) >= 0)
+ getace (lacl[pos], type, id, ace->Mask, ace->Header.AceType);
+ }
if ((ace->Header.AceFlags & INHERIT_ALL)
- && (attr & FILE_ATTRIBUTE_DIRECTORY))
- {
- type |= ACL_DEFAULT;
- if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, id)) >= 0)
- getace (lacl[pos], type, id, ace->Mask, ace->Header.AceType);
- }
+ && (attr & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ type |= ACL_DEFAULT;
+ if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, id)) >= 0)
+ getace (lacl[pos], type, id, ace->Mask, ace->Header.AceType);
+ }
}
if ((pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) < 0)
pos = MAX_ACL_ENTRIES;
for (i = 0; i < pos; ++i)
{
lacl[i].a_perm = (lacl[i].a_perm & S_IRWXU)
- & ~((lacl[i].a_perm & S_IRWXG) << 3);
+ & ~((lacl[i].a_perm & S_IRWXG) << 3);
lacl[i].a_perm |= (lacl[i].a_perm & S_IRWXU) >> 3
- | (lacl[i].a_perm & S_IRWXU) >> 6;
+ | (lacl[i].a_perm & S_IRWXU) >> 6;
}
if ((searchace (lacl, MAX_ACL_ENTRIES, USER) >= 0
|| searchace (lacl, MAX_ACL_ENTRIES, GROUP) >= 0)
{
lacl[pos].a_type = CLASS_OBJ;
lacl[pos].a_perm =
- lacl[searchace (lacl, MAX_ACL_ENTRIES, GROUP_OBJ)].a_perm;
+ lacl[searchace (lacl, MAX_ACL_ENTRIES, GROUP_OBJ)].a_perm;
}
int dgpos;
if ((searchace (lacl, MAX_ACL_ENTRIES, DEF_USER) >= 0
for (int i = 0; i < cnt; ++i)
{
switch (acls[i].a_type)
- {
- case USER_OBJ:
- case USER:
- if (acls[i].a_id != myself->uid)
- {
- // Check if user is a NT group:
- // Take SID from passwd, search SID in group, check is_grp_member
- char owner_sidbuf[MAX_SID_LEN];
- PSID owner_sid = (PSID) owner_sidbuf;
- char group_sidbuf[MAX_SID_LEN];
- PSID group_sid = (PSID) group_sidbuf;
- struct passwd *pw;
- struct group *gr = NULL;
-
- if (group_sem > 0)
- continue;
- ++group_sem;
- if ((pw = getpwuid (acls[i].a_id)) != NULL
- && get_pw_sid (owner_sid, pw))
- {
- while ((gr = getgrent ()))
- if (get_gr_sid (group_sid, gr)
- && EqualSid (owner_sid, group_sid)
- && is_grp_member (myself->uid, gr->gr_gid))
- break;
- endgrent ();
- }
- --group_sem;
- if (! gr)
- continue;
- }
- break;
- case GROUP_OBJ:
- case GROUP:
- if (acls[i].a_id != myself->gid &&
- !is_grp_member (myself->uid, acls[i].a_id))
- continue;
- break;
- case OTHER_OBJ:
- break;
- default:
- continue;
- }
+ {
+ case USER_OBJ:
+ case USER:
+ if (acls[i].a_id != myself->uid)
+ {
+ // Check if user is a NT group:
+ // Take SID from passwd, search SID in group, check is_grp_member
+ char owner_sidbuf[MAX_SID_LEN];
+ PSID owner_sid = (PSID) owner_sidbuf;
+ char group_sidbuf[MAX_SID_LEN];
+ PSID group_sid = (PSID) group_sidbuf;
+ struct passwd *pw;
+ struct group *gr = NULL;
+
+ if (group_sem > 0)
+ continue;
+ ++group_sem;
+ if ((pw = getpwuid (acls[i].a_id)) != NULL
+ && get_pw_sid (owner_sid, pw))
+ {
+ while ((gr = getgrent ()))
+ if (get_gr_sid (group_sid, gr)
+ && EqualSid (owner_sid, group_sid)
+ && is_grp_member (myself->uid, gr->gr_gid))
+ break;
+ endgrent ();
+ }
+ --group_sem;
+ if (! gr)
+ continue;
+ }
+ break;
+ case GROUP_OBJ:
+ case GROUP:
+ if (acls[i].a_id != myself->gid &&
+ !is_grp_member (myself->uid, acls[i].a_id))
+ continue;
+ break;
+ case OTHER_OBJ:
+ break;
+ default:
+ continue;
+ }
if ((!(flags & R_OK) || (acls[i].a_perm & S_IREAD))
- && (!(flags & W_OK) || (acls[i].a_perm & S_IWRITE))
- && (!(flags & X_OK) || (acls[i].a_perm & S_IEXEC)))
- return 0;
+ && (!(flags & W_OK) || (acls[i].a_perm & S_IWRITE))
+ && (!(flags & X_OK) || (acls[i].a_perm & S_IEXEC)))
+ return 0;
}
set_errno (EACCES);
return -1;
static
int
acl_worker (const char *path, int cmd, int nentries, aclent_t *aclbufp,
- int nofollow)
+ int nofollow)
{
extern suffix_info stat_suffixes[];
path_conv real_path (path, (nofollow ? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW) | PC_FULL, stat_suffixes);
int ret = -1;
switch (cmd)
- {
- case SETACL:
- set_errno (ENOSYS);
- break;
- case GETACL:
- if (nentries < 1)
- set_errno (EINVAL);
- else if ((nofollow && ! lstat (path, &st))
- || (!nofollow && ! stat (path, &st)))
- {
- aclent_t lacl[4];
- if (nentries > 0)
- {
- lacl[0].a_type = USER_OBJ;
- lacl[0].a_id = st.st_uid;
- lacl[0].a_perm = (st.st_mode & S_IRWXU)
- | (st.st_mode & S_IRWXU) >> 3
- | (st.st_mode & S_IRWXU) >> 6;
- }
- if (nentries > 1)
- {
- lacl[1].a_type = GROUP_OBJ;
- lacl[1].a_id = st.st_gid;
- lacl[1].a_perm = (st.st_mode & S_IRWXG)
- | (st.st_mode & S_IRWXG) << 3
- | (st.st_mode & S_IRWXG) >> 3;
- }
- if (nentries > 2)
- {
- lacl[2].a_type = OTHER_OBJ;
- lacl[2].a_id = 0;
- lacl[2].a_perm = (st.st_mode & S_IRWXO)
- | (st.st_mode & S_IRWXO) << 6
- | (st.st_mode & S_IRWXO) << 3;
- }
- if (nentries > 3)
- {
- lacl[3].a_type = CLASS_OBJ;
- lacl[3].a_id = 0;
- lacl[3].a_perm = (st.st_mode & S_IRWXG)
- | (st.st_mode & S_IRWXG) << 3
- | (st.st_mode & S_IRWXG) >> 3;
- }
- if (nentries > 4)
- nentries = 4;
- if (aclbufp)
- memcpy (aclbufp, lacl, nentries * sizeof (aclent_t));
- ret = nentries;
- }
- break;
- case GETACLCNT:
- ret = 4;
- break;
- }
+ {
+ case SETACL:
+ set_errno (ENOSYS);
+ break;
+ case GETACL:
+ if (nentries < 1)
+ set_errno (EINVAL);
+ else if ((nofollow && ! lstat (path, &st))
+ || (!nofollow && ! stat (path, &st)))
+ {
+ aclent_t lacl[4];
+ if (nentries > 0)
+ {
+ lacl[0].a_type = USER_OBJ;
+ lacl[0].a_id = st.st_uid;
+ lacl[0].a_perm = (st.st_mode & S_IRWXU)
+ | (st.st_mode & S_IRWXU) >> 3
+ | (st.st_mode & S_IRWXU) >> 6;
+ }
+ if (nentries > 1)
+ {
+ lacl[1].a_type = GROUP_OBJ;
+ lacl[1].a_id = st.st_gid;
+ lacl[1].a_perm = (st.st_mode & S_IRWXG)
+ | (st.st_mode & S_IRWXG) << 3
+ | (st.st_mode & S_IRWXG) >> 3;
+ }
+ if (nentries > 2)
+ {
+ lacl[2].a_type = OTHER_OBJ;
+ lacl[2].a_id = 0;
+ lacl[2].a_perm = (st.st_mode & S_IRWXO)
+ | (st.st_mode & S_IRWXO) << 6
+ | (st.st_mode & S_IRWXO) << 3;
+ }
+ if (nentries > 3)
+ {
+ lacl[3].a_type = CLASS_OBJ;
+ lacl[3].a_id = 0;
+ lacl[3].a_perm = (st.st_mode & S_IRWXG)
+ | (st.st_mode & S_IRWXG) << 3
+ | (st.st_mode & S_IRWXG) >> 3;
+ }
+ if (nentries > 4)
+ nentries = 4;
+ if (aclbufp)
+ memcpy (aclbufp, lacl, nentries * sizeof (aclent_t));
+ ret = nentries;
+ }
+ break;
+ case GETACLCNT:
+ ret = 4;
+ break;
+ }
syscall_printf ("%d = acl (%s)", ret, path);
return ret;
}
switch (cmd)
{
case SETACL:
- if (!aclsort(nentries, 0, aclbufp))
- return setacl (real_path.get_win32 (),
- nentries, aclbufp);
- break;
+ if (!aclsort(nentries, 0, aclbufp))
+ return setacl (real_path.get_win32 (),
+ nentries, aclbufp);
+ break;
case GETACL:
- if (nentries < 1)
- break;
- return getacl (real_path.get_win32 (),
- real_path.file_attributes (),
- nentries, aclbufp);
+ if (nentries < 1)
+ break;
+ return getacl (real_path.get_win32 (),
+ real_path.file_attributes (),
+ nentries, aclbufp);
case GETACLCNT:
- return getacl (real_path.get_win32 (),
- real_path.file_attributes (),
- 0, NULL);
+ return getacl (real_path.get_win32 (),
+ real_path.file_attributes (),
+ 0, NULL);
default:
- break;
+ break;
}
set_errno (EINVAL);
syscall_printf ("-1 = acl (%s)", path);
switch (aclbufp[pos].a_type)
{
case USER_OBJ:
- if (has_user_obj)
- {
- if (which)
- *which = pos;
- return USER_ERROR;
- }
- has_user_obj = TRUE;
- break;
+ if (has_user_obj)
+ {
+ if (which)
+ *which = pos;
+ return USER_ERROR;
+ }
+ has_user_obj = TRUE;
+ break;
case GROUP_OBJ:
- if (has_group_obj)
- {
- if (which)
- *which = pos;
- return GRP_ERROR;
- }
- has_group_obj = TRUE;
- break;
+ if (has_group_obj)
+ {
+ if (which)
+ *which = pos;
+ return GRP_ERROR;
+ }
+ has_group_obj = TRUE;
+ break;
case OTHER_OBJ:
- if (has_other_obj)
- {
- if (which)
- *which = pos;
- return OTHER_ERROR;
- }
- has_other_obj = TRUE;
- break;
+ if (has_other_obj)
+ {
+ if (which)
+ *which = pos;
+ return OTHER_ERROR;
+ }
+ has_other_obj = TRUE;
+ break;
case CLASS_OBJ:
- if (has_class_obj)
- {
- if (which)
- *which = pos;
- return CLASS_ERROR;
- }
- has_class_obj = TRUE;
- break;
+ if (has_class_obj)
+ {
+ if (which)
+ *which = pos;
+ return CLASS_ERROR;
+ }
+ has_class_obj = TRUE;
+ break;
case USER:
case GROUP:
- if ((pos2 = searchace (aclbufp + pos + 1, nentries - pos - 1,
- aclbufp[pos].a_type, aclbufp[pos].a_id)) >= 0)
- {
- if (which)
- *which = pos2;
- return DUPLICATE_ERROR;
- }
- has_ug_objs = TRUE;
- break;
+ if ((pos2 = searchace (aclbufp + pos + 1, nentries - pos - 1,
+ aclbufp[pos].a_type, aclbufp[pos].a_id)) >= 0)
+ {
+ if (which)
+ *which = pos2;
+ return DUPLICATE_ERROR;
+ }
+ has_ug_objs = TRUE;
+ break;
case DEF_USER_OBJ:
- if (has_def_user_obj)
- {
- if (which)
- *which = pos;
- return USER_ERROR;
- }
- has_def_user_obj = TRUE;
- break;
+ if (has_def_user_obj)
+ {
+ if (which)
+ *which = pos;
+ return USER_ERROR;
+ }
+ has_def_user_obj = TRUE;
+ break;
case DEF_GROUP_OBJ:
- if (has_def_group_obj)
- {
- if (which)
- *which = pos;
- return GRP_ERROR;
- }
- has_def_group_obj = TRUE;
- break;
+ if (has_def_group_obj)
+ {
+ if (which)
+ *which = pos;
+ return GRP_ERROR;
+ }
+ has_def_group_obj = TRUE;
+ break;
case DEF_OTHER_OBJ:
- if (has_def_other_obj)
- {
- if (which)
- *which = pos;
- return OTHER_ERROR;
- }
- has_def_other_obj = TRUE;
- break;
+ if (has_def_other_obj)
+ {
+ if (which)
+ *which = pos;
+ return OTHER_ERROR;
+ }
+ has_def_other_obj = TRUE;
+ break;
case DEF_CLASS_OBJ:
- if (has_def_class_obj)
- {
- if (which)
- *which = pos;
- return CLASS_ERROR;
- }
- has_def_class_obj = TRUE;
- break;
+ if (has_def_class_obj)
+ {
+ if (which)
+ *which = pos;
+ return CLASS_ERROR;
+ }
+ has_def_class_obj = TRUE;
+ break;
case DEF_USER:
case DEF_GROUP:
- if ((pos2 = searchace (aclbufp + pos + 1, nentries - pos - 1,
- aclbufp[pos].a_type, aclbufp[pos].a_id)) >= 0)
- {
- if (which)
- *which = pos2;
- return DUPLICATE_ERROR;
- }
- has_def_ug_objs = TRUE;
- break;
+ if ((pos2 = searchace (aclbufp + pos + 1, nentries - pos - 1,
+ aclbufp[pos].a_type, aclbufp[pos].a_id)) >= 0)
+ {
+ if (which)
+ *which = pos2;
+ return DUPLICATE_ERROR;
+ }
+ has_def_ug_objs = TRUE;
+ break;
default:
- return ENTRY_ERROR;
+ return ENTRY_ERROR;
}
if (!has_user_obj
|| !has_group_obj
)
{
if (which)
- *which = -1;
+ *which = -1;
return MISS_ERROR;
}
return 0;
return -1;
}
aclbufp[pos].a_perm = (*modep & S_IRWXU)
- | (*modep & S_IRWXU) >> 3
- | (*modep & S_IRWXU) >> 6;
+ | (*modep & S_IRWXU) >> 3
+ | (*modep & S_IRWXU) >> 6;
if ((pos = searchace (aclbufp, nentries, GROUP_OBJ)) < 0)
{
set_errno (EINVAL);
if (searchace (aclbufp, nentries, CLASS_OBJ) < 0)
pos = searchace (aclbufp, nentries, CLASS_OBJ);
aclbufp[pos].a_perm = (*modep & S_IRWXG)
- | (*modep & S_IRWXG) << 3
- | (*modep & S_IRWXG) >> 3;
+ | (*modep & S_IRWXG) << 3
+ | (*modep & S_IRWXG) >> 3;
if ((pos = searchace (aclbufp, nentries, OTHER_OBJ)) < 0)
{
set_errno (EINVAL);
return -1;
}
aclbufp[pos].a_perm = (*modep & S_IRWXO)
- | (*modep & S_IRWXO) << 6
- | (*modep & S_IRWXO) << 3;
+ | (*modep & S_IRWXO) << 6
+ | (*modep & S_IRWXO) << 3;
return 0;
}
for (int pos = 0; pos < aclcnt; ++pos)
{
if (!first)
- strcat (buf, ",");
+ strcat (buf, ",");
first = FALSE;
if (aclbufp[pos].a_type & ACL_DEFAULT)
- strcat (buf, "default");
+ strcat (buf, "default");
switch (aclbufp[pos].a_type)
- {
- case USER_OBJ:
- __small_sprintf (buf + strlen (buf), "user::%s",
- permtostr (aclbufp[pos].a_perm));
- break;
- case USER:
- __small_sprintf (buf + strlen (buf), "user:%d:%s",
- aclbufp[pos].a_id, permtostr (aclbufp[pos].a_perm));
- break;
- case GROUP_OBJ:
- __small_sprintf (buf + strlen (buf), "group::%s",
- permtostr (aclbufp[pos].a_perm));
- break;
- case GROUP:
- __small_sprintf (buf + strlen (buf), "group:%d:%s",
- aclbufp[pos].a_id, permtostr (aclbufp[pos].a_perm));
- break;
- case CLASS_OBJ:
- __small_sprintf (buf + strlen (buf), "mask::%s",
- permtostr (aclbufp[pos].a_perm));
- break;
- case OTHER_OBJ:
- __small_sprintf (buf + strlen (buf), "other::%s",
- permtostr (aclbufp[pos].a_perm));
- break;
- default:
- set_errno (EINVAL);
- return NULL;
- }
+ {
+ case USER_OBJ:
+ __small_sprintf (buf + strlen (buf), "user::%s",
+ permtostr (aclbufp[pos].a_perm));
+ break;
+ case USER:
+ __small_sprintf (buf + strlen (buf), "user:%d:%s",
+ aclbufp[pos].a_id, permtostr (aclbufp[pos].a_perm));
+ break;
+ case GROUP_OBJ:
+ __small_sprintf (buf + strlen (buf), "group::%s",
+ permtostr (aclbufp[pos].a_perm));
+ break;
+ case GROUP:
+ __small_sprintf (buf + strlen (buf), "group:%d:%s",
+ aclbufp[pos].a_id, permtostr (aclbufp[pos].a_perm));
+ break;
+ case CLASS_OBJ:
+ __small_sprintf (buf + strlen (buf), "mask::%s",
+ permtostr (aclbufp[pos].a_perm));
+ break;
+ case OTHER_OBJ:
+ __small_sprintf (buf + strlen (buf), "other::%s",
+ permtostr (aclbufp[pos].a_perm));
+ break;
+ default:
+ set_errno (EINVAL);
+ return NULL;
+ }
}
return strdup (buf);
}
for (char *c = strtok (buf, ","); c; c = strtok (NULL, ","))
{
if (!strncmp (c, "default", 7))
- {
- lacl[pos].a_type |= ACL_DEFAULT;
- c += 7;
- }
+ {
+ lacl[pos].a_type |= ACL_DEFAULT;
+ c += 7;
+ }
if (!strncmp (c, "user:", 5))
- {
- if (c[5] == ':')
- lacl[pos].a_type |= USER_OBJ;
- else
- {
- lacl[pos].a_type |= USER;
- c += 5;
- if (isalpha (*c))
- {
- struct passwd *pw = getpwnam (c);
- if (!pw)
- {
- set_errno (EINVAL);
- return NULL;
- }
- lacl[pos].a_id = pw->pw_uid;
- c = strchr (c, ':');
- }
- else if (isdigit (*c))
- lacl[pos].a_id = strtol (c, &c, 10);
- if (!c || *c != ':')
- {
- set_errno (EINVAL);
- return NULL;
- }
- }
- }
+ {
+ if (c[5] == ':')
+ lacl[pos].a_type |= USER_OBJ;
+ else
+ {
+ lacl[pos].a_type |= USER;
+ c += 5;
+ if (isalpha (*c))
+ {
+ struct passwd *pw = getpwnam (c);
+ if (!pw)
+ {
+ set_errno (EINVAL);
+ return NULL;
+ }
+ lacl[pos].a_id = pw->pw_uid;
+ c = strchr (c, ':');
+ }
+ else if (isdigit (*c))
+ lacl[pos].a_id = strtol (c, &c, 10);
+ if (!c || *c != ':')
+ {
+ set_errno (EINVAL);
+ return NULL;
+ }
+ }
+ }
else if (!strncmp (c, "group:", 6))
- {
- if (c[5] == ':')
- lacl[pos].a_type |= GROUP_OBJ;
- else
- {
- lacl[pos].a_type |= GROUP;
- c += 5;
- if (isalpha (*c))
- {
- struct group *gr = getgrnam (c);
- if (!gr)
- {
- set_errno (EINVAL);
- return NULL;
- }
- lacl[pos].a_id = gr->gr_gid;
- c = strchr (c, ':');
- }
- else if (isdigit (*c))
- lacl[pos].a_id = strtol (c, &c, 10);
- if (!c || *c != ':')
- {
- set_errno (EINVAL);
- return NULL;
- }
- }
- }
+ {
+ if (c[5] == ':')
+ lacl[pos].a_type |= GROUP_OBJ;
+ else
+ {
+ lacl[pos].a_type |= GROUP;
+ c += 5;
+ if (isalpha (*c))
+ {
+ struct group *gr = getgrnam (c);
+ if (!gr)
+ {
+ set_errno (EINVAL);
+ return NULL;
+ }
+ lacl[pos].a_id = gr->gr_gid;
+ c = strchr (c, ':');
+ }
+ else if (isdigit (*c))
+ lacl[pos].a_id = strtol (c, &c, 10);
+ if (!c || *c != ':')
+ {
+ set_errno (EINVAL);
+ return NULL;
+ }
+ }
+ }
else if (!strncmp (c, "mask:", 5))
- {
- if (c[5] == ':')
- lacl[pos].a_type |= CLASS_OBJ;
- else
- {
- set_errno (EINVAL);
- return NULL;
- }
- }
+ {
+ if (c[5] == ':')
+ lacl[pos].a_type |= CLASS_OBJ;
+ else
+ {
+ set_errno (EINVAL);
+ return NULL;
+ }
+ }
else if (!strncmp (c, "other:", 6))
- {
- if (c[5] == ':')
- lacl[pos].a_type |= OTHER_OBJ;
- else
- {
- set_errno (EINVAL);
- return NULL;
- }
- }
+ {
+ if (c[5] == ':')
+ lacl[pos].a_type |= OTHER_OBJ;
+ else
+ {
+ set_errno (EINVAL);
+ return NULL;
+ }
+ }
if ((lacl[pos].a_perm = permfromstr (c)) == 01000)
- {
- set_errno (EINVAL);
- return NULL;
- }
+ {
+ set_errno (EINVAL);
+ return NULL;
+ }
++pos;
}
aclent_t *aclp = (aclent_t *) malloc (pos * sizeof (aclent_t));
{
case WAIT_OBJECT_0:
if (!ClearCommError (h, &ev, &st))
- {
- debug_printf ("ClearCommError");
- goto err;
- }
+ {
+ debug_printf ("ClearCommError");
+ goto err;
+ }
else if (!st.cbInQue)
Sleep (to);
else
PSECURITY_ATTRIBUTES psa = (PSECURITY_ATTRIBUTES) sa_buf;
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR)
- ((char *) sa_buf + sizeof (*psa));
+ ((char *) sa_buf + sizeof (*psa));
PACL acl = (PACL) ((char *) sa_buf + sizeof (*psa) + sizeof (*psd));
char sid_buf[MAX_SID_LEN];
return inherit ? &sec_none_nih : &sec_none;
size_t acl_len = sizeof (ACL)
- + 4 * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD))
- + GetLengthSid (sid)
- + GetLengthSid (get_admin_sid ())
- + GetLengthSid (get_system_sid ())
- + GetLengthSid (get_creator_owner_sid ());
+ + 4 * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD))
+ + GetLengthSid (sid)
+ + GetLengthSid (get_admin_sid ())
+ + GetLengthSid (get_system_sid ())
+ + GetLengthSid (get_creator_owner_sid ());
if (sid2)
acl_len += sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD)
- + GetLengthSid (sid2);
+ + GetLengthSid (sid2);
if (! InitializeAcl (acl, acl_len, ACL_REVISION))
debug_printf("InitializeAcl %E");
if (! AddAccessAllowedAce (acl, ACL_REVISION,
- SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
- sid))
+ SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
+ sid))
debug_printf("AddAccessAllowedAce(%s) %E", getlogin());
if (! AddAccessAllowedAce (acl, ACL_REVISION,
- SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
- get_admin_sid ()))
+ SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
+ get_admin_sid ()))
debug_printf("AddAccessAllowedAce(admin) %E");
if (! AddAccessAllowedAce (acl, ACL_REVISION,
- SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
- get_system_sid ()))
+ SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
+ get_system_sid ()))
debug_printf("AddAccessAllowedAce(system) %E");
if (! AddAccessAllowedAce (acl, ACL_REVISION,
- SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
- get_creator_owner_sid ()))
+ SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
+ get_creator_owner_sid ()))
debug_printf("AddAccessAllowedAce(creator_owner) %E");
if (sid2)
if (! AddAccessAllowedAce (acl, ACL_REVISION,
- SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
- sid2))
+ SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
+ sid2))
debug_printf("AddAccessAllowedAce(sid2) %E");
if (! InitializeSecurityDescriptor (psd,
- SECURITY_DESCRIPTOR_REVISION))
+ SECURITY_DESCRIPTOR_REVISION))
debug_printf("InitializeSecurityDescriptor %E");
/*
#include <wingdi.h>
#include <winuser.h>
#include <ctype.h>
-#include <paths.h>
#include "cygerrno.h"
#include "fhandler.h"
#include "path.h"
#include "sigproc.h"
#include "child_info.h"
#include "pinfo.h"
+#include "cygheap.h"
#include "perthread.h"
-extern BOOL allow_ntsec;
-
#define LINE_BUF_CHUNK (MAX_PATH * 2)
suffix_info std_suffixes[] =
*/
HANDLE NO_COPY hExeced = NULL;
-DWORD NO_COPY exec_exit = 0;
int
iscmd (const char *argv0, const char *what)
hexec_proc = NULL;
}
+struct av
+{
+ int argc;
+ int calloced;
+private:
+ char **argv;
+public:
+ av (int ac, const char * const *av) : argc (ac), calloced (0)
+ {
+ argv = (char **) cmalloc (HEAP_ARGV, (argc + 1) * sizeof (char *));
+ memcpy (argv, av, (argc + 1) * sizeof (char *));
+ }
+ ~av ()
+ {
+ for (int i = 0; i < calloced; i++)
+ cfree (argv[i]);
+ cfree (argv);
+ }
+ int unshift (const char *what, int conv = 0);
+ operator char **() {return argv;}
+};
+
+int
+av::unshift (const char *what, int conv)
+{
+ char **av;
+ av = (char **) crealloc (argv, (argc + 2) * sizeof (char *));
+ if (!av)
+ return 0;
+
+ argv = av;
+ memmove (argv + 1, argv, (argc + 1) * sizeof (char *));
+ char buf[MAX_PATH + 1];
+ if (conv)
+ {
+ cygwin_conv_to_posix_path (what, buf);
+ char *p = strchr (buf, '\0') - 4;
+ if (p > buf && strcasematch (p, ".exe"))
+ *p = '\0';
+ what = buf;
+ }
+ *argv = cstrdup (what);
+ argc++;
+ calloced++;
+ return 1;
+}
+
static int __stdcall
spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
const char *const envp[], int mode)
{
int i;
BOOL rc;
- int argc;
pid_t cygpid;
hExeced = NULL;
MALLOC_CHECK;
+// if (strstr (prog_arg, "dopath")) try_to_debug ();
if (prog_arg == NULL)
{
syscall_printf ("prog_arg is NULL");
return (-1);
}
+ path_conv real_path;
+
+ linebuf one_line;
+
+ STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
+
+ child_info_spawn ciresrv;
+ si.lpReserved2 = (LPBYTE) &ciresrv;
+ si.cbReserved2 = sizeof (ciresrv);
+
+ HANDLE spr = NULL;
+ DWORD chtype;
+ if (mode != _P_OVERLAY && mode != _P_VFORK)
+ chtype = PROC_SPAWN;
+ else
+ {
+ spr = CreateEvent(&sec_all, TRUE, FALSE, NULL);
+ ProtectHandle (spr);
+ chtype = PROC_EXEC;
+ }
+
+ init_child_info (chtype, &ciresrv, (mode == _P_OVERLAY) ? myself->pid : 1, spr);
+ if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &ciresrv.parent, 0, 1,
+ DUPLICATE_SAME_ACCESS))
+ {
+ system_printf ("couldn't create handle to myself for child, %E");
+ return -1;
+ }
+
+ ciresrv.moreinfo = (cygheap_exec_info *) ccalloc (HEAP_EXEC, 1, sizeof (cygheap_exec_info));
+ ciresrv.moreinfo->old_title = old_title ? cstrdup (old_title) : NULL;
+ ciresrv.moreinfo->fds = fdtab;
+ ciresrv.moreinfo->nfds = fdtab.size;
+
/* CreateProcess takes one long string that is the command line (sigh).
We need to quote any argument that has whitespace or embedded "'s. */
- for (argc = 0; argv[argc]; argc++)
+ int ac;
+ for (ac = 0; argv[ac]; ac++)
/* nothing */;
- char *real_path;
- path_conv real_path_buf;
+ av newargv (ac, argv);
- linebuf one_line;
-
- if (argc == 3 && argv[1][0] == '/' && argv[1][1] == 'c' &&
+ if (ac == 3 && argv[1][0] == '/' && argv[1][1] == 'c' &&
(iscmd (argv[0], "command.com") || iscmd (argv[0], "cmd.exe")))
{
one_line.add (argv[0]);
one_line.add (" ");
one_line.add (argv[1]);
one_line.add (" ");
- real_path = NULL;
one_line.add (argv[2]);
- strcpy (real_path_buf, argv[0]);
+ strcpy (real_path, argv[0]);
goto skip_arg_parsing;
}
- real_path = real_path_buf;
-
- const char *saved_prog_arg;
- const char *newargv0, **firstarg;
const char *ext;
-
- if ((ext = perhaps_suffix (prog_arg, real_path_buf)) == NULL)
+ if ((ext = perhaps_suffix (prog_arg, real_path)) == NULL)
{
set_errno (ENOENT);
return -1;
}
MALLOC_CHECK;
- saved_prog_arg = prog_arg;
- newargv0 = argv[0];
- firstarg = &newargv0;
/* If the file name ends in either .exe, .com, .bat, or .cmd we assume
that it is NOT a script file */
if (buf[0] != '#' || buf[1] != '!')
{
- strcpy (buf, "sh"); /* shell script without magic */
- pgm = buf;
+ pgm = (char *) "/bin/sh";
ptr = buf + 2;
arg1 = NULL;
}
ptr = newptr - 1;
}
-
*ptr = '\0';
}
- char buf2[MAX_PATH + 1];
-
/* pointers:
* pgm interpreter name
* arg1 optional string
* ptr end of string
*/
+ if (arg1)
+ newargv.unshift (arg1);
- if (!arg1)
- one_line.prepend (" ", 1);
- else
- {
- one_line.prepend ("\" ", 2);
- one_line.prepend (arg1, strlen (arg1));
- one_line.prepend (" \"", 2);
- }
-
- find_exec (pgm, real_path_buf, "PATH=", 0, &ext);
- cygwin_conv_to_posix_path (real_path, buf2);
- one_line.prepend (buf2, strlen (buf2));
-
- /* If script had absolute path, add it to script name now!
- * This is necessary if script has been found via PATH.
- * For example, /usr/local/bin/tkman started as "tkman":
- * #!/usr/local/bin/wish -f
- * ...
- * We should run /usr/local/bin/wish -f /usr/local/bin/tkman,
- * but not /usr/local/bin/wish -f tkman!
- * We don't modify anything, if script has qulified path.
- */
- if (firstarg)
- *firstarg = saved_prog_arg;
-
- debug_printf ("prog_arg '%s', copy '%s'", prog_arg, one_line.buf);
- firstarg = NULL;
+ find_exec (pgm, real_path, "PATH=", 0, &ext);
+ newargv.unshift (real_path, 1);
}
- for (; *argv; argv++)
+ if (real_path.iscygexec ())
+ for (int i = newargv.calloced; i < newargv.argc; i++)
+ newargv[i] = cstrdup (newargv[i]);
+ else
{
- char *p = NULL;
- const char *a = newargv0 ?: *argv;
-
- MALLOC_CHECK;
-
- newargv0 = NULL;
- int len = strlen (a);
- if (len != 0 && !strpbrk (a, " \t\n\r\""))
- one_line.add (a, len);
- else
+ for (int i = 0; i < newargv.argc; i++)
{
- one_line.add ("\"", 1);
- for (; (p = strpbrk (a, "\"\\")); a = ++p)
+ char *p = NULL;
+ const char *a;
+
+ if (i >= newargv.calloced)
+ newargv[i] = cstrdup (newargv[i]);
+ a = newargv[i];
+ int len = strlen (a);
+ if (len != 0 && !strpbrk (a, " \t\n\r\""))
+ one_line.add (a, len);
+ else
{
- one_line.add (a, p - a);
- if (*p == '\\' || *p == '"')
- one_line.add ("\\", 1);
- one_line.add (p, 1);
+ one_line.add ("\"", 1);
+ for (; (p = strpbrk (a, "\"\\")); a = ++p)
+ {
+ one_line.add (a, p - a);
+ if (*p == '\\' || *p == '"')
+ one_line.add ("\\", 1);
+ one_line.add (p, 1);
+ }
+ if (*a)
+ one_line.add (a);
+ one_line.add ("\"", 1);
}
- if (*a)
- one_line.add (a);
- one_line.add ("\"", 1);
+ MALLOC_CHECK;
+ one_line.add (" ", 1);
+ MALLOC_CHECK;
}
+
MALLOC_CHECK;
- one_line.add (" ", 1);
+ if (one_line.ix)
+ one_line.buf[one_line.ix - 1] = '\0';
+ else
+ one_line.add ("", 1);
MALLOC_CHECK;
}
-
- MALLOC_CHECK;
- if (one_line.ix)
- one_line.buf[one_line.ix - 1] = '\0';
- else
- one_line.add ("", 1);
- MALLOC_CHECK;
+ ciresrv.moreinfo->argc = newargv.argc;
+ ciresrv.moreinfo->argv = newargv;
+
+ /* FIXME: Should lock cwd access here. */
+ ciresrv.moreinfo->cwd_posix = cwd_posix (NULL);
+ ciresrv.moreinfo->cwd_win32 = cwd_win32 (NULL);
+ ciresrv.moreinfo->cwd_hash = cwd_hash ();
+
+ ciresrv.moreinfo->environ = (char **) cmalloc (HEAP_ARGV, envsize (envp, 1));
+ char **c;
+ const char * const *e;
+ for (c = ciresrv.moreinfo->environ, e = envp; *e; )
+ *c++ = cstrdup (*e++);
+ *c = NULL;
+ if (mode != _P_OVERLAY ||
+ !DuplicateHandle (hMainProc, myself.shared_handle (), hMainProc, &ciresrv.moreinfo->myself_pinfo, 0,
+ TRUE, DUPLICATE_SAME_ACCESS))
+ ciresrv.moreinfo->myself_pinfo = NULL;
skip_arg_parsing:
PROCESS_INFORMATION pi = {NULL, 0, 0, 0};
- STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
si.lpReserved = NULL;
si.lpDesktop = NULL;
si.dwFlags = STARTF_USESTDHANDLES;
/* Pass fd table to a child */
- MALLOC_CHECK;
- int len = fdtab.linearize_fd_array (0, 0);
- MALLOC_CHECK;
- if (len == -1)
- {
- system_printf ("FATAL error in linearize_fd_array");
- return -1;
- }
- int titlelen = 1 + (old_title && mode == _P_OVERLAY ? strlen (old_title) : 0);
- si.cbReserved2 = len + titlelen + sizeof(child_info);
- si.lpReserved2 = (LPBYTE) alloca (si.cbReserved2);
-
-# define ciresrv ((child_info *)si.lpReserved2)
- HANDLE spr = NULL;
- DWORD chtype;
- if (mode != _P_OVERLAY)
- chtype = PROC_SPAWN;
- else
- {
- spr = CreateEvent(&sec_all, TRUE, FALSE, NULL);
- ProtectHandle (spr);
- chtype = PROC_EXEC;
- }
-
- init_child_info (chtype, ciresrv, (mode == _P_OVERLAY) ? myself->pid : 1, spr);
- if (mode != _P_OVERLAY ||
- !DuplicateHandle (hMainProc, myself.shared_handle (), hMainProc,
- &ciresrv->myself_pinfo, 0,
- TRUE, DUPLICATE_SAME_ACCESS))
- ciresrv->myself_pinfo = NULL;
-
- LPBYTE resrv = si.lpReserved2 + sizeof *ciresrv;
-
- if (fdtab.linearize_fd_array (resrv, len) < 0)
- {
- system_printf ("FATAL error in second linearize_fd_array");
- return -1;
- }
-
- if (titlelen > 1)
- strcpy ((char *) resrv + len, old_title);
- else
- resrv[len] = '\0';
-
- /* We print the translated program and arguments here so the user can see
- what was done to it. */
- syscall_printf ("spawn_guts (%s, %.132s)", real_path, one_line.buf);
+ syscall_printf ("spawn_guts (%s, %.132s)", (char *) real_path, one_line.buf);
int flags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED |
GetPriorityClass (hMainProc);
flags |= DETACHED_PROCESS;
/* Build windows style environment list */
- char *envblock = winenv (envp, 0);
+ char *envblock;
+ if (real_path.iscygexec ())
+ envblock = NULL;
+ else
+ envblock = winenv (envp, 0);
+
+ ciresrv.cygheap = cygheap;
+ ciresrv.cygheap_max = cygheap_max;
/* Preallocated buffer for `sec_user' call */
char sa_buf[1024];
if (!hToken && myself->token != INVALID_HANDLE_VALUE)
hToken = myself->token;
+ /* FIXME: This leaves a handle to the process open so that the pid is not
+ duplicated. However, if a process execs another process two handles are
+ left open, which is unnecessary. */
if (mode == _P_OVERLAY && !hexec_proc &&
!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hexec_proc, 0,
- TRUE, DUPLICATE_SAME_ACCESS))
+ TRUE, DUPLICATE_SAME_ACCESS))
system_printf ("couldn't save current process handle %p, %E", hMainProc);
if (hToken)
PSID sid = NULL;
DWORD ret_len;
if (GetTokenInformation (hToken, TokenUser,
- (LPVOID) &tu, sizeof tu,
- &ret_len))
- sid = ((TOKEN_USER *) &tu)->User.Sid;
+ (LPVOID) &tu, sizeof tu,
+ &ret_len))
+ sid = ((TOKEN_USER *) &tu)->User.Sid;
else
- system_printf ("GetTokenInformation: %E");
+ system_printf ("GetTokenInformation: %E");
/* Retrieve security attributes before setting psid to NULL
- since it's value is needed by `sec_user'. */
+ since it's value is needed by `sec_user'. */
PSECURITY_ATTRIBUTES sec_attribs = allow_ntsec && sid
- ? sec_user (sa_buf, sid)
- : &sec_all_nih;
+ ? sec_user (sa_buf, sid)
+ : &sec_all_nih;
/* Remove impersonation */
uid_t uid = geteuid();
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
- seteuid (myself->orig_uid);
+ seteuid (myself->orig_uid);
/* Load users registry hive. */
load_registry_hive (sid);
rc = CreateProcessAsUser (hToken,
real_path, /* image name - with full path */
one_line.buf, /* what was passed to exec */
- sec_attribs, /* process security attrs */
- sec_attribs, /* thread security attrs */
+ sec_attribs, /* process security attrs */
+ sec_attribs, /* thread security attrs */
TRUE, /* inherit handles from parent */
flags,
envblock,/* environment */
&si,
&pi);
/* Restore impersonation. In case of _P_OVERLAY this isn't
- allowed since it would overwrite child data. */
- if (mode != _P_OVERLAY
- && myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
- seteuid (uid);
+ allowed since it would overwrite child data. */
+ if (mode != _P_OVERLAY && mode != _P_VFORK
+ && myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
+ seteuid (uid);
}
else
rc = CreateProcessA (real_path, /* image name - with full path */
one_line.buf, /* what was passed to exec */
- /* process security attrs */
- allow_ntsec ? sec_user (sa_buf) : &sec_all_nih,
- /* thread security attrs */
- allow_ntsec ? sec_user (sa_buf) : &sec_all_nih,
+ /* process security attrs */
+ allow_ntsec ? sec_user (sa_buf) : &sec_all_nih,
+ /* thread security attrs */
+ allow_ntsec ? sec_user (sa_buf) : &sec_all_nih,
TRUE, /* inherit handles from parent */
flags,
envblock,/* environment */
&pi);
MALLOC_CHECK;
- free (envblock);
+ if (envblock)
+ free (envblock);
MALLOC_CHECK;
- if (ciresrv->myself_pinfo)
- CloseHandle (ciresrv->myself_pinfo);
-
/* Set errno now so that debugging messages from it appear before our
final debugging message [this is a general rule for debugging
messages]. */
if (!rc)
-
- if (!rc)
{
if (spr)
ForceCloseHandle (spr);
if (mode == _P_OVERLAY)
{
- close_all_files ();
- strcpy (myself->progname, real_path_buf);
+ strcpy (myself->progname, real_path);
+ // close_all_files ();
proc_terminate ();
hExeced = pi.hProcess;
}
child->username[0] = '\0';
child->progname[0] = '\0';
- // CGF FIXME -- need to do this? strcpy (child->progname, path);
- // CGF FIXME -- need to do this? memcpy (child->username, myself->username, MAX_USER_NAME);
child->ppid = myself->pid;
child->uid = myself->uid;
child->gid = myself->gid;
DWORD res;
- if (mode == _P_OVERLAY)
+ if (mode == _P_OVERLAY || mode == _P_VFORK)
{
BOOL exited;
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
res = 0;
- DWORD timeout = INFINITE;
- exec_exit = 1;
exited = FALSE;
MALLOC_CHECK;
for (int i = 0; i < 100; i++)
{
- switch (WaitForMultipleObjects (nwait, waitbuf, FALSE, timeout))
+ switch (WaitForMultipleObjects (nwait, waitbuf, FALSE, INFINITE))
{
- case WAIT_TIMEOUT:
- syscall_printf ("WFMO timed out after signal");
- if (WaitForSingleObject (pi.hProcess, 0) != WAIT_OBJECT_0)
+ case WAIT_OBJECT_0:
+ sigproc_printf ("subprocess exited");
+ if (!GetExitCodeProcess (pi.hProcess, &res))
+ res = 1;
+ exited = TRUE;
+
+ if (nwait <= 2 || mode != _P_OVERLAY)
+ /* nothing to do */;
+ else if (WaitForSingleObject (spr, 1) == WAIT_OBJECT_0)
+ goto reparent;
+ else if (!(res & EXIT_REPARENTING))
{
- sigproc_printf ("subprocess still alive after signal");
- res = exec_exit;
+ MALLOC_CHECK;
+ close_all_files ();
+ MALLOC_CHECK;
}
- else
- {
- sigproc_printf ("subprocess exited after signal");
- case WAIT_OBJECT_0:
- sigproc_printf ("subprocess exited");
- if (!GetExitCodeProcess (pi.hProcess, &res))
- res = exec_exit;
- exited = TRUE;
- }
- if (nwait > 2)
- if (WaitForSingleObject (spr, 1) == WAIT_OBJECT_0)
- res |= EXIT_REPARENTING;
- else if (!(res & EXIT_REPARENTING))
- {
- MALLOC_CHECK;
- close_all_files ();
- MALLOC_CHECK;
- }
break;
case WAIT_OBJECT_0 + 1:
sigproc_printf ("signal arrived");
ResetEvent (signal_arrived);
continue;
case WAIT_OBJECT_0 + 2:
- res = EXIT_REPARENTING;
- MALLOC_CHECK;
- ForceCloseHandle (spr);
- MALLOC_CHECK;
- if (!parent_alive)
+ if (mode == _P_OVERLAY)
{
- nwait = 1;
- sigproc_terminate ();
- continue;
+ reparent:
+ res |= EXIT_REPARENTING;
+ close_all_files ();
+ if (!parent_alive)
+ {
+ nwait = 1;
+ sigproc_terminate ();
+ continue;
+ }
}
break;
case WAIT_FAILED:
break;
}
- if (nwait > 2)
- ForceCloseHandle (spr);
+ ForceCloseHandle (spr);
sigproc_printf ("res = %x", res);
/* nothing */;
else
{
+ int rc;
HANDLE hP = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
parent->dwProcessId);
sigproc_printf ("parent handle %p, pid %d", hP, parent->dwProcessId);
if (hP == NULL && GetLastError () == ERROR_INVALID_PARAMETER)
- res = 1;
+ rc = 1;
else if (hP)
{
ProtectHandle (hP);
- res = DuplicateHandle (hMainProc, pi.hProcess, hP,
- &myself->hProcess, 0, FALSE,
- DUPLICATE_SAME_ACCESS);
- sigproc_printf ("Dup hP %d", res);
+ rc = DuplicateHandle (hMainProc, pi.hProcess, hP,
+ &myself->hProcess, 0, FALSE,
+ DUPLICATE_SAME_ACCESS);
+ sigproc_printf ("Dup hP %d", rc);
ForceCloseHandle (hP);
}
if (!res)
system_printf ("myself->hProcess %x", myself->hProcess);
}
}
- res = EXIT_REPARENTING;
ForceCloseHandle1 (hExeced, childhProc);
hExeced = INVALID_HANDLE_VALUE;
}
}
MALLOC_CHECK;
- do_exit (res | EXIT_NOCLOSEALL);
+ if (mode == _P_OVERLAY)
+ do_exit (res | EXIT_NOCLOSEALL);
}
- if (mode == _P_WAIT)
- waitpid (cygpid, (int *) &res, 0);
- else if (mode == _P_DETACH)
- res = 0; /* Lose all memory of this child. */
- else if ((mode == _P_NOWAIT) || (mode == _P_NOWAITO))
- res = cygpid;
+ switch (mode)
+ {
+ case _P_WAIT:
+ waitpid (cygpid, (int *) &res, 0);
+ break;
+ case _P_DETACH:
+ res = 0; /* Lose all memory of this child. */
+ break;
+ case _P_NOWAIT:
+ case _P_NOWAITO:
+ case _P_VFORK:
+ res = cygpid;
+ break;
+ default:
+ break;
+ }
return (int) res;
}
switch (mode)
{
- case _P_OVERLAY:
- /* We do not pass _P_SEARCH_PATH here. execve doesn't search PATH.*/
- /* Just act as an exec if _P_OVERLAY set. */
- spawn_guts (hToken, path, argv, envp, mode);
- /* Errno should be set by spawn_guts. */
- ret = -1;
- break;
- case _P_NOWAIT:
- case _P_NOWAITO:
- case _P_WAIT:
- case _P_DETACH:
- subproc_init ();
- ret = spawn_guts (hToken, path, argv, envp, mode);
- if (vf && ret > 0)
- {
- vf->pid = ret;
- longjmp (vf->j, 1);
- }
- break;
- default:
- set_errno (EINVAL);
- ret = -1;
- break;
+ case _P_OVERLAY:
+ /* We do not pass _P_SEARCH_PATH here. execve doesn't search PATH.*/
+ /* Just act as an exec if _P_OVERLAY set. */
+ spawn_guts (hToken, path, argv, envp, mode);
+ /* Errno should be set by spawn_guts. */
+ ret = -1;
+ break;
+ case _P_VFORK:
+ case _P_NOWAIT:
+ case _P_NOWAITO:
+ case _P_WAIT:
+ case _P_DETACH:
+ subproc_init ();
+ ret = spawn_guts (hToken, path, argv, envp, 0);
+ if (vf && ret > 0)
+ {
+ vf->pid = ret;
+ longjmp (vf->j, 1);
+ }
+ break;
+ default:
+ set_errno (EINVAL);
+ ret = -1;
+ break;
}
return ret;
}
#include <sys/uio.h>
#include <errno.h>
#include <limits.h>
-#include <unistd.h>
#include <winnls.h>
#include <lmcons.h> /* for UNLEN */
#include "cygerrno.h"
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
+#include <unistd.h>
extern BOOL allow_ntsec;
debug_printf ("%s (%s, %p)", caller, name, buf);
- path_conv real_path (name, (nofollow ? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW) | PC_FULL,
- stat_suffixes);
+ path_conv real_path (name, (nofollow ? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW) |
+ PC_FULL, stat_suffixes);
if (real_path.error)
{
}
extern "C" char *
+ttyname (int fd)
+{
+ if (fdtab.not_open (fd) || !fdtab[fd]->is_tty ())
+ {
+ return 0;
+ }
+ return (char *)(fdtab[fd]->ttyname ());
+}
+
+extern "C" char *
ctermid (char *str)
{
static NO_COPY char buf[16];
return str;
}
-extern "C"
-char *
-ttyname (int fd)
-{
- if (fdtab.not_open (fd) || !fdtab[fd]->is_tty ())
- {
- return 0;
- }
- return (char *)(fdtab[fd]->ttyname ());
-}
-
/* Tells stdio if it should do the cr/lf conversion for this file */
-extern "C" int _cygwin_istext_for_stdio (int fd);
-int
+extern "C" int
_cygwin_istext_for_stdio (int fd)
{
syscall_printf("_cygwin_istext_for_stdio (%d)\n", fd);
}
/* ftruncate: P96 5.6.7.1 */
-extern "C"
-int
+extern "C" int
ftruncate (int fd, off_t length)
{
int res = -1;
/* truncate: Provided by SVR4 and 4.3+BSD. Not part of POSIX.1 or XPG3 */
/* FIXME: untested */
-extern "C"
-int
+extern "C" int
truncate (const char *pathname, off_t length)
{
int fd;
return res;
}
-extern "C"
-long
+extern "C" long
get_osfhandle (int fd)
{
long res = -1;
return res;
}
-extern "C"
-int
+extern "C" int
statfs (const char *fname, struct statfs *sfs)
{
if (!sfs)
return 0;
}
-extern "C"
-int
+extern "C" int
fstatfs (int fd, struct statfs *sfs)
{
if (fdtab.not_open (fd))
}
/* setpgid: POSIX 4.3.3.1 */
-extern "C"
-int
+extern "C" int
setpgid (pid_t pid, pid_t pgid)
{
int res = -1;
return res;
}
-extern "C"
-pid_t
+extern "C" pid_t
getpgid (pid_t pid)
{
if (pid == 0)
return p->pgid;
}
-extern "C"
-int
+extern "C" int
setpgrp (void)
{
return setpgid (0, 0);
}
-extern "C"
-pid_t
+extern "C" pid_t
getpgrp (void)
{
return getpgid (0);
}
-extern "C"
-char *
+extern "C" char *
ptsname (int fd)
{
if (fdtab.not_open (fd))
}
/* FIXME: what is this? */
-extern "C"
-int
+extern "C" int
regfree ()
{
return 0;
Although mknod hasn't been implemented yet, some GNU tools (e.g. the
fileutils) assume its existence so we must provide a stub that always
fails. */
-extern "C"
-int
+extern "C" int
mknod ()
{
set_errno (ENOSYS);
}
/* setgid: POSIX 4.2.2.1 */
-extern "C"
-int
+extern "C" int
setgid (gid_t gid)
{
int ret = setegid (gid);
}
/* setuid: POSIX 4.2.2.1 */
-extern "C"
-int
+extern "C" int
setuid (uid_t uid)
{
int ret = seteuid (uid);
extern char *internal_getlogin (_pinfo *pi);
/* seteuid: standards? */
-extern "C"
-int
+extern "C" int
seteuid (uid_t uid)
{
if (os_being_run == winNT)
{
current = _list->items[_index];
if (current->used && comp (current, _value))
- break;
+ break;
current = NULL;
}
return current;
{
current = _list->items[_index];
if (current->used && current == &_item)
- break;
+ break;
}
return (_index == _list->index ? -1 : _index);
};
struct _reent local_clib;
struct sigaction _sigs[NSIG];
- sigset_t _sig_mask; /* one set for everything to ignore. */
+ sigset_t _sig_mask; /* one set for everything to ignore. */
LONG _sigtodo[NSIG + __SIGOFFSET];
// setup signal structures
// FIX ME : cleanup code
-// thread->used = false; // release thread entry
+// thread->used = false; // release thread entry
thread->return_ptr = ret;
ExitThread (0);
}
if (item->joinable == 'N')
{
if (return_val)
- *return_val = NULL;
+ *return_val = NULL;
return EINVAL;
}
else
item->joinable = 'N';
WaitForSingleObject ((HANDLE)*thread, INFINITE);
if (return_val)
- *return_val = item->return_ptr;
+ *return_val = item->return_ptr;
}/* End if*/
return 0;
return ESRCH;
if (item->suspended == true)
- ResumeThread ((HANDLE)*thread);
+ ResumeThread ((HANDLE)*thread);
item->suspended = false;
return 0;
}
}
-#endif // MT_SAFE
+#endif // MT_SAFE
/* path.cc */
struct mntent _ret;
- char *_cwd_win32;
- char *_cwd_posix;
- unsigned long _cwd_hash;
int _iteration;
/* strerror */
};
-#endif // MT_SAFE
+#endif // MT_SAFE
-#endif // _CYGNUS_THREADS_
+#endif // _CYGNUS_THREADS_
/* First trying to get logon info from environment */
if ((env = getenv ("USERNAME")) != NULL)
- un = env;
+ un = env;
if ((env = getenv ("LOGONSERVER")) != NULL)
- strcpy (pi->logsrv, env + 2); /* filter leading double backslashes */
+ strcpy (pi->logsrv, env + 2); /* filter leading double backslashes */
if ((env = getenv ("USERDOMAIN")) != NULL)
- strcpy (pi->domain, env);
+ strcpy (pi->domain, env);
/* Trust only if usernames are identical */
if (un && strcasematch (pi->username, un)
- && pi->domain[0] && pi->logsrv[0])
- debug_printf ("Domain: %s, Logon Server: %s", pi->domain, pi->logsrv);
+ && pi->domain[0] && pi->logsrv[0])
+ debug_printf ("Domain: %s, Logon Server: %s", pi->domain, pi->logsrv);
/* If that failed, try to get that info from NetBIOS */
else if (!NetWkstaUserGetInfo (NULL, 1, (LPBYTE *)&wui))
- {
- sys_wcstombs (pi->username, wui->wkui1_username, MAX_USER_NAME);
- sys_wcstombs (pi->logsrv, wui->wkui1_logon_server, MAX_HOST_NAME);
- sys_wcstombs (pi->domain, wui->wkui1_logon_domain,
- MAX_COMPUTERNAME_LENGTH + 1);
- /* Save values in environment */
- if (!strcasematch (pi->username, "SYSTEM")
- && pi->domain[0] && pi->logsrv[0])
- {
- LPUSER_INFO_3 ui = NULL;
- WCHAR wbuf[MAX_HOST_NAME + 2];
+ {
+ sys_wcstombs (pi->username, wui->wkui1_username, MAX_USER_NAME);
+ sys_wcstombs (pi->logsrv, wui->wkui1_logon_server, MAX_HOST_NAME);
+ sys_wcstombs (pi->domain, wui->wkui1_logon_domain,
+ MAX_COMPUTERNAME_LENGTH + 1);
+ /* Save values in environment */
+ if (!strcasematch (pi->username, "SYSTEM")
+ && pi->domain[0] && pi->logsrv[0])
+ {
+ LPUSER_INFO_3 ui = NULL;
+ WCHAR wbuf[MAX_HOST_NAME + 2];
- strcat (strcpy (buf, "\\\\"), pi->logsrv);
- setenv ("USERNAME", pi->username, 1);
- setenv ("LOGONSERVER", buf, 1);
- setenv ("USERDOMAIN", pi->domain, 1);
- /* HOMEDRIVE and HOMEPATH are wrong most of the time, too,
- after changing user context! */
- sys_mbstowcs (wbuf, buf, MAX_HOST_NAME + 2);
- if (!NetUserGetInfo (NULL, wui->wkui1_username, 3, (LPBYTE *)&ui)
- || !NetUserGetInfo (wbuf,wui->wkui1_username,3,(LPBYTE *)&ui))
- {
- sys_wcstombs (buf, ui->usri3_home_dir, MAX_PATH);
- if (!buf[0])
- {
- sys_wcstombs (buf, ui->usri3_home_dir_drive, MAX_PATH);
- if (buf[0])
- strcat (buf, "\\");
- else
- {
- env = getenv ("SYSTEMDRIVE");
- if (env && *env)
- strcat (strcpy (buf, env), "\\");
- else
- GetSystemDirectoryA (buf, MAX_PATH);
- }
- }
- setenv ("HOMEPATH", buf + 2, 1);
- buf[2] = '\0';
- setenv ("HOMEDRIVE", buf, 1);
- NetApiBufferFree (ui);
- }
- }
- debug_printf ("Domain: %s, Logon Server: %s, Windows Username: %s",
- pi->domain, pi->logsrv, pi->username);
- NetApiBufferFree (wui);
- }
+ strcat (strcpy (buf, "\\\\"), pi->logsrv);
+ setenv ("USERNAME", pi->username, 1);
+ setenv ("LOGONSERVER", buf, 1);
+ setenv ("USERDOMAIN", pi->domain, 1);
+ /* HOMEDRIVE and HOMEPATH are wrong most of the time, too,
+ after changing user context! */
+ sys_mbstowcs (wbuf, buf, MAX_HOST_NAME + 2);
+ if (!NetUserGetInfo (NULL, wui->wkui1_username, 3, (LPBYTE *)&ui)
+ || !NetUserGetInfo (wbuf,wui->wkui1_username,3,(LPBYTE *)&ui))
+ {
+ sys_wcstombs (buf, ui->usri3_home_dir, MAX_PATH);
+ if (!buf[0])
+ {
+ sys_wcstombs (buf, ui->usri3_home_dir_drive, MAX_PATH);
+ if (buf[0])
+ strcat (buf, "\\");
+ else
+ {
+ env = getenv ("SYSTEMDRIVE");
+ if (env && *env)
+ strcat (strcpy (buf, env), "\\");
+ else
+ GetSystemDirectoryA (buf, MAX_PATH);
+ }
+ }
+ setenv ("HOMEPATH", buf + 2, 1);
+ buf[2] = '\0';
+ setenv ("HOMEDRIVE", buf, 1);
+ NetApiBufferFree (ui);
+ }
+ }
+ debug_printf ("Domain: %s, Logon Server: %s, Windows Username: %s",
+ pi->domain, pi->logsrv, pi->username);
+ NetApiBufferFree (wui);
+ }
if (allow_ntsec)
- {
- HANDLE ptok = pi->token; /* Which is INVALID_HANDLE_VALUE if no
- impersonation took place. */
- DWORD siz;
- char tu[1024];
- int ret = 0;
-
- /* Try to get the SID either from already impersonated token
- or from current process first. To differ that two cases is
- important, because you can't rely on the user information
- in a process token of a currently impersonated process. */
- if (ptok == INVALID_HANDLE_VALUE
- && !OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok))
- debug_printf ("OpenProcessToken(): %E\n");
- else if (!GetTokenInformation (ptok, TokenUser, (LPVOID) &tu,
- sizeof tu, &siz))
- debug_printf ("GetTokenInformation(): %E");
- else if (!(ret = CopySid (MAX_SID_LEN, (PSID) pi->psid,
- ((TOKEN_USER *) &tu)->User.Sid)))
- debug_printf ("Couldn't retrieve SID from access token!");
- /* Close token only if it's a result from OpenProcessToken(). */
- if (ptok != INVALID_HANDLE_VALUE && pi->token == INVALID_HANDLE_VALUE)
- CloseHandle (ptok);
+ {
+ HANDLE ptok = pi->token; /* Which is INVALID_HANDLE_VALUE if no
+ impersonation took place. */
+ DWORD siz;
+ char tu[1024];
+ int ret = 0;
+
+ /* Try to get the SID either from already impersonated token
+ or from current process first. To differ that two cases is
+ important, because you can't rely on the user information
+ in a process token of a currently impersonated process. */
+ if (ptok == INVALID_HANDLE_VALUE
+ && !OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok))
+ debug_printf ("OpenProcessToken(): %E\n");
+ else if (!GetTokenInformation (ptok, TokenUser, (LPVOID) &tu,
+ sizeof tu, &siz))
+ debug_printf ("GetTokenInformation(): %E");
+ else if (!(ret = CopySid (MAX_SID_LEN, (PSID) pi->psid,
+ ((TOKEN_USER *) &tu)->User.Sid)))
+ debug_printf ("Couldn't retrieve SID from access token!");
+ /* Close token only if it's a result from OpenProcessToken(). */
+ if (ptok != INVALID_HANDLE_VALUE && pi->token == INVALID_HANDLE_VALUE)
+ CloseHandle (ptok);
- /* If that failes, try to get the SID from localhost. This can only
- be done if a domain is given because there's a chance that a local
- and a domain user may have the same name. */
- if (!ret && pi->domain[0])
- {
- /* Concat DOMAIN\USERNAME for the next lookup */
- strcat (strcat (strcpy (buf, pi->domain), "\\"), pi->username);
- if (!(ret = lookup_name (buf, NULL, (PSID) pi->psid)))
- debug_printf ("Couldn't retrieve SID locally!");
- }
+ /* If that failes, try to get the SID from localhost. This can only
+ be done if a domain is given because there's a chance that a local
+ and a domain user may have the same name. */
+ if (!ret && pi->domain[0])
+ {
+ /* Concat DOMAIN\USERNAME for the next lookup */
+ strcat (strcat (strcpy (buf, pi->domain), "\\"), pi->username);
+ if (!(ret = lookup_name (buf, NULL, (PSID) pi->psid)))
+ debug_printf ("Couldn't retrieve SID locally!");
+ }
- /* If that failes, too, as a last resort try to get the SID from
- the logon server. */
- if (!ret && !(ret = lookup_name(pi->username, pi->logsrv,
- (PSID)pi->psid)))
- debug_printf ("Couldn't retrieve SID from '%s'!", pi->logsrv);
+ /* If that failes, too, as a last resort try to get the SID from
+ the logon server. */
+ if (!ret && !(ret = lookup_name(pi->username, pi->logsrv,
+ (PSID)pi->psid)))
+ debug_printf ("Couldn't retrieve SID from '%s'!", pi->logsrv);
- /* If we have a SID, try to get the corresponding Cygwin user name
- which can be different from the Windows user name. */
- if (ret)
- {
- struct passwd *pw;
- char psidbuf[MAX_SID_LEN];
- PSID psid = (PSID) psidbuf;
+ /* If we have a SID, try to get the corresponding Cygwin user name
+ which can be different from the Windows user name. */
+ if (ret)
+ {
+ struct passwd *pw;
+ char psidbuf[MAX_SID_LEN];
+ PSID psid = (PSID) psidbuf;
- pi->use_psid = 1;
- if (!strcasematch (pi->username, "SYSTEM")
- && pi->domain[0] && pi->logsrv[0])
- {
- if (get_registry_hive_path (pi->psid, buf))
- setenv ("USERPROFILE", buf, 1);
- }
- while ((pw = getpwent ()) != NULL)
- if (get_pw_sid (psid, pw) && EqualSid (pi->psid, psid))
- {
- strcpy (pi->username, pw->pw_name);
- break;
- }
- endpwent ();
- }
- }
+ pi->use_psid = 1;
+ if (!strcasematch (pi->username, "SYSTEM")
+ && pi->domain[0] && pi->logsrv[0])
+ {
+ if (get_registry_hive_path (pi->psid, buf))
+ setenv ("USERPROFILE", buf, 1);
+ }
+ while ((pw = getpwent ()) != NULL)
+ if (get_pw_sid (psid, pw) && EqualSid (pi->psid, psid))
+ {
+ strcpy (pi->username, pw->pw_name);
+ break;
+ }
+ endpwent ();
+ }
+ }
}
debug_printf ("Cygwins Username: %s", pi->username);
return pi->username;
if (myself->uid == USHRT_MAX)
if ((p = getpwnam (username = internal_getlogin (myself))) != NULL)
{
- myself->uid = p->pw_uid;
- myself->gid = p->pw_gid;
+ myself->uid = p->pw_uid;
+ myself->gid = p->pw_gid;
}
else
{
- myself->uid = DEFAULT_UID;
- myself->gid = DEFAULT_GID;
+ myself->uid = DEFAULT_UID;
+ myself->gid = DEFAULT_GID;
}
/* Real and effective uid/gid are always identical on process start up.
This is at least true for NT/W2K. */
/* winsup.h: main Cygwin header file.
- Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
+ Copyright 1996, 1997, 1998, 1999, 2000 Red Hat, Inc.
This file is part of Cygwin.
extern int dynamically_loaded;
#define sys_wcstombs(tgt,src,len) \
- WideCharToMultiByte(CP_ACP,0,(src),-1,(tgt),(len),NULL,NULL)
+ WideCharToMultiByte(CP_ACP,0,(src),-1,(tgt),(len),NULL,NULL)
#define sys_mbstowcs(tgt,src,len) \
- MultiByteToWideChar(CP_ACP,0,(src),-1,(tgt),(len))
+ MultiByteToWideChar(CP_ACP,0,(src),-1,(tgt),(len))
#include <cygwin/version.h>
extern "C" void __stdcall do_exit (int) __attribute__ ((noreturn));
/* Initialize the environment */
-void environ_init (int);
-
-/* Heap management. */
-void heap_init (void);
-void malloc_init (void);
+void environ_init (char **);
/* UID/GID */
void uinfo_init (void);
/* File manipulation */
int __stdcall set_process_privileges ();
int __stdcall get_file_attribute (int, const char *, int *,
- uid_t * = NULL, gid_t * = NULL);
+ uid_t * = NULL, gid_t * = NULL);
int __stdcall set_file_attribute (int, const char *, int);
int __stdcall set_file_attribute (int, const char *, uid_t, gid_t, int, const char *);
void __stdcall set_std_handle (int);
void __stdcall mark (const char *, int);
+#define _P_VFORK 0
extern "C" int _spawnve (HANDLE hToken, int mode, const char *path,
const char *const *argv, const char *const *envp);
void __stdcall totimeval (struct timeval *dst, FILETIME * src, int sub, int flag);
long __stdcall to_time_t (FILETIME * ptr);
-/* pinfo table manipulation */
-#ifndef lock_pinfo_for_update
-int __stdcall lock_pinfo_for_update (DWORD timeout);
-#endif
-void unlock_pinfo (void);
-
/* Retrieve a security descriptor that allows all access */
SECURITY_DESCRIPTOR *__stdcall get_null_sd (void);
char * __stdcall winenv (const char * const *, int);
extern char **__cygwin_environ, ***main_environ;
extern "C" char __stdcall **cur_environ ();
+int __stdcall envsize (const char * const *, int debug_print = 0);
/* The title on program start. */
extern char *old_title;