From b0e82b74fbdfa2dee89505aba03f2827480cc8ca Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sun, 3 Sep 2000 04:16:35 +0000 Subject: [PATCH] * 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. --- winsup/cygwin/ChangeLog | 67 ++ winsup/cygwin/Makefile.in | 23 +- winsup/cygwin/assert.cc | 4 +- winsup/cygwin/child_info.h | 59 +- winsup/cygwin/cygheap.cc | 232 ++++++ winsup/cygwin/cygheap.h | 37 + winsup/cygwin/dcrt0.cc | 349 ++++---- winsup/cygwin/delqueue.cc | 4 +- winsup/cygwin/dir.cc | 16 +- winsup/cygwin/dtable.cc | 191 +---- winsup/cygwin/dtable.h | 3 +- winsup/cygwin/environ.cc | 92 +- winsup/cygwin/fhandler.cc | 85 +- winsup/cygwin/fhandler.h | 31 +- winsup/cygwin/fhandler_console.cc | 13 +- winsup/cygwin/fhandler_random.cc | 10 +- winsup/cygwin/fhandler_raw.cc | 89 +- winsup/cygwin/fhandler_serial.cc | 10 +- winsup/cygwin/fhandler_tape.cc | 48 +- winsup/cygwin/fhandler_tty.cc | 11 +- winsup/cygwin/fork.cc | 52 +- winsup/cygwin/heap.cc | 6 +- winsup/cygwin/heap.h | 22 + winsup/cygwin/init.cc | 2 +- winsup/cygwin/malloc_wrapper.cc | 39 +- winsup/cygwin/mmap.cc | 10 +- winsup/cygwin/net.cc | 132 +-- winsup/cygwin/passwd.cc | 26 +- winsup/cygwin/path.cc | 149 +++- winsup/cygwin/path.h | 5 + winsup/cygwin/pinfo.cc | 19 +- winsup/cygwin/pinfo.h | 10 +- winsup/cygwin/poll.cc | 40 +- winsup/cygwin/registry.cc | 10 +- winsup/cygwin/scandir.cc | 10 +- winsup/cygwin/security.cc | 1294 ++++++++++++++--------------- winsup/cygwin/select.cc | 8 +- winsup/cygwin/shared.cc | 36 +- winsup/cygwin/spawn.cc | 511 ++++++------ winsup/cygwin/syscalls.cc | 75 +- winsup/cygwin/thread.cc | 16 +- winsup/cygwin/thread.h | 7 +- winsup/cygwin/uinfo.cc | 232 +++--- winsup/cygwin/winsup.h | 22 +- 44 files changed, 2219 insertions(+), 1888 deletions(-) create mode 100644 winsup/cygwin/cygheap.cc create mode 100644 winsup/cygwin/cygheap.h create mode 100644 winsup/cygwin/heap.h diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index fdf767b3b..90c7bea3a 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,70 @@ +Sun Sep 3 00:07:32 2000 Christopher Faylor + + * 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 * Makefile.in: Remove "make check" support. It is now in diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 35da6de36..e57329dd5 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -50,7 +50,7 @@ DEFS = @DEFS@ 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. @@ -116,16 +116,17 @@ EXTRA_OFILES=$(bupdir1)/libiberty/random.o $(bupdir1)/libiberty/strsignal.o 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 diff --git a/winsup/cygwin/assert.cc b/winsup/cygwin/assert.cc index c66418bd1..5e1c0b88b 100644 --- a/winsup/cygwin/assert.cc +++ b/winsup/cygwin/assert.cc @@ -42,10 +42,10 @@ __assert (const char *file, int line, const char *failedexpr) { 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 */ } diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h index 7e47b591a..29e44af02 100644 --- a/winsup/cygwin/child_info.h +++ b/winsup/cygwin/child_info.h @@ -14,8 +14,9 @@ enum 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 @@ -34,12 +35,6 @@ public: 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 @@ -55,9 +50,53 @@ public: 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; diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc new file mode 100644 index 000000000..157c7e478 --- /dev/null +++ b/winsup/cygwin/cygheap.cc @@ -0,0 +1,232 @@ +/* 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 +#include +#include +#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; +} diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h new file mode 100644 index 000000000..6eaeee240 --- /dev/null +++ b/winsup/cygwin/cygheap.h @@ -0,0 +1,37 @@ +/* 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 *); +} diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 62a5bca04..ac93dc29d 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -20,6 +20,8 @@ details. */ #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" @@ -121,7 +123,7 @@ do_global_ctors (void (**in_pfunc)(), int force) 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; } @@ -293,58 +295,38 @@ quoted (char *cmd, int winshell) 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. @@ -494,7 +476,8 @@ build_argv (char *cmd, char **&argv, int &argc, int winshell) } argv[argc] = NULL; - debug_printf ("argv[%d] = '%s'\n", argc, argv[argc]); + + debug_printf ("argc %d", argc); } /* sanity and sync check */ @@ -532,22 +515,35 @@ check_sanity_and_sync (per_process *p) } 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); @@ -559,11 +555,14 @@ alloc_stack_hard_way (child_info_fork *ci, volatile char *b) 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; @@ -572,7 +571,7 @@ alloc_stack_hard_way (child_info_fork *ci, volatile char *b) /* 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 @@ -595,12 +594,9 @@ alloc_stack (child_info_fork *ci) 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) @@ -616,22 +612,20 @@ 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 @@ -642,10 +636,58 @@ dll_crt0_1 () _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 (); @@ -657,9 +699,6 @@ dll_crt0_1 () 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. */ @@ -684,18 +723,20 @@ dll_crt0_1 () 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; @@ -740,26 +781,32 @@ dll_crt0_1 () /* 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. */ @@ -768,7 +815,7 @@ dll_crt0_1 () /* 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); @@ -785,8 +832,9 @@ dll_crt0_1 () 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 @@ -798,16 +846,7 @@ dll_crt0_1 () 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 (); @@ -833,62 +872,35 @@ _dll_crt0 () 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"); } } @@ -913,19 +925,6 @@ cygwin_dll_init () { 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 (), diff --git a/winsup/cygwin/delqueue.cc b/winsup/cygwin/delqueue.cc index 08a17fd75..a08b24aef 100644 --- a/winsup/cygwin/delqueue.cc +++ b/winsup/cygwin/delqueue.cc @@ -86,7 +86,7 @@ delqueue_list::process_queue () 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]); @@ -94,7 +94,7 @@ delqueue_list::process_queue () else { syscall_printf ("Hmm, don't know what to do with '%s', %E", name[i]); - inuse[i] = 0; + inuse[i] = 0; } } } diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index 96ca52d93..350fbce8d 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -75,7 +75,7 @@ opendir (const char *dirname) } if (stat (myself->rootlen ? dirname : real_dirname.get_win32 (), - &statbuf) == -1) + &statbuf) == -1) goto failed; if (!(statbuf.st_mode & S_IFDIR)) @@ -296,7 +296,7 @@ mkdir (const char *dir, mode_t mode) 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 @@ -324,18 +324,18 @@ rmdir (const char *dir) 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); diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index 05b767f0f..affac33d5 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -23,6 +23,7 @@ details. */ #include "sync.h" #include "sigproc.h" #include "pinfo.h" +#include "cygheap.h" #include "cygerrno.h" #include "fhandler.h" #include "path.h" @@ -62,7 +63,7 @@ dtable::extend (int howmuch) /* 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; @@ -70,7 +71,7 @@ dtable::extend (int howmuch) if (fds) { memcpy (newfds, fds, size * sizeof (fds[0])); - free (fds); + cfree (fds); } size = new_size; @@ -151,7 +152,7 @@ dtable::release (int fd) { if (!not_open (fd)) { - delete (fds[fd]); + delete fds[fd]; /* CGF FIXME */ fds[fd] = NULL; } } @@ -240,7 +241,7 @@ fhandler_base * 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) @@ -312,7 +313,7 @@ dtable::dup_worker (fhandler_base *oldfh) newfh->set_io_handle (NULL); if (oldfh->dup (newfh)) { - free (newfh); + cfree (newfh); newfh = NULL; return NULL; } @@ -351,18 +352,21 @@ dtable::dup2 (int oldfd, int newfd) } 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; @@ -382,12 +386,12 @@ done: 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; @@ -399,12 +403,12 @@ dtable::select_read (int fd, select_record *s) 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; @@ -416,12 +420,12 @@ dtable::select_write (int fd, select_record *s) 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; @@ -430,151 +434,33 @@ dtable::select_except (int fd, select_record *s) 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 ()); + fds[i]->clear_readahead (); + fds[i]->fixup_after_exec (parent); } - - 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; - } - /* 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 ()); @@ -588,7 +474,7 @@ int 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"); @@ -601,6 +487,7 @@ dtable::vfork_child_dup () set_errno (EBADF); goto out; } + fds_on_hold = fds; fds = newtable; out: @@ -617,7 +504,7 @@ dtable::vfork_parent_restore () 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; diff --git a/winsup/cygwin/dtable.h b/winsup/cygwin/dtable.h index 64ffc496f..db57c6b8c 100644 --- a/winsup/cygwin/dtable.h +++ b/winsup/cygwin/dtable.h @@ -30,8 +30,7 @@ public: 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); diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index 1af364697..89ad0ab13 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -27,6 +27,8 @@ extern DWORD chunksize; 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. * @@ -102,7 +104,7 @@ getwinenv (const char *env, const char *in_posix) /* 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; @@ -111,22 +113,17 @@ posify (int already_posix, char **here, const char *value) if (!(conv = getwinenv (src))) return; - if (already_posix) - conv->add_cache (value, NULL); - else - { - /* Turn all the items from c:; into their - mounted equivalents - if there is one. */ + /* Turn all the items from c:; 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); } /* @@ -175,6 +172,16 @@ getenv (const char *name) 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. */ @@ -202,17 +209,19 @@ _addenv (const char *name, const char *value, int overwrite) } else { /* Create new slot. */ - char **env; + int sz = envsize (cur_environ ()); + int allocsz = sz + sizeof (char *); - /* Search for the end of the environment. */ - for (env = cur_environ (); *env; env++) - continue; - - 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. */ @@ -261,7 +270,7 @@ putenv (const char *str) if ((res = check_null_empty_path (str))) { if (res == ENOENT) - return 0; + return 0; set_errno (res); return -1; } @@ -292,7 +301,7 @@ setenv (const char *name, const char *value, int overwrite) if ((res = check_null_empty_path (name))) { if (res == ENOENT) - return 0; + return 0; set_errno (res); return -1; } @@ -503,18 +512,15 @@ regopt (const char *name) * 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); @@ -525,6 +531,19 @@ environ_init (int already_posix) 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 @@ -532,8 +551,8 @@ environ_init (int already_posix) 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 == '=') @@ -548,13 +567,16 @@ environ_init (int already_posix) 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); diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 6ce973667..c69d5f316 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -13,6 +13,7 @@ details. */ #include #include #include +#include "cygheap.h" #include #include "cygerrno.h" #include "fhandler.h" @@ -26,12 +27,26 @@ struct __cygwin_perfile *perfile_table = NULL; 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; } @@ -137,16 +152,16 @@ fhandler_base::set_name (const char *unix_path, const char *win32_path, int unit 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"); @@ -154,11 +169,11 @@ fhandler_base::set_name (const char *unix_path, const char *win32_path, int unit } 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); } @@ -196,7 +211,7 @@ fhandler_base::raw_read (void *ptr, size_t ulen) break; default: syscall_printf ("ReadFile %s failed, %E", unix_path_name_); - __seterrno_from_win_error (errcode); + __seterrno_from_win_error (errcode); return -1; break; } @@ -205,37 +220,6 @@ fhandler_base::raw_read (void *ptr, size_t ulen) 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 @@ -954,11 +938,11 @@ fhandler_disk_file::fstat (struct stat *buf) 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) @@ -979,7 +963,7 @@ fhandler_disk_file::fstat (struct stat *buf) 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 */ @@ -1124,6 +1108,13 @@ fhandler_base::tcgetpgrp (void) 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), @@ -1157,10 +1148,12 @@ fhandler_base::~fhandler_base (void) 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; } diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 21577f28b..10807ceb2 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -149,13 +149,7 @@ public: 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 (); @@ -243,7 +237,8 @@ public: 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); @@ -287,10 +282,7 @@ public: 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. */ @@ -307,6 +299,12 @@ public: 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 @@ -377,9 +375,6 @@ protected: 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); @@ -497,7 +492,7 @@ public: 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 @@ -604,7 +599,7 @@ public: 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 () @@ -712,7 +707,7 @@ public: 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 diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 38580d3e7..33bf18b58 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -8,10 +8,6 @@ This software is a copyrighted work licensed under the terms of the 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 #include @@ -21,6 +17,7 @@ details. */ #include #include #include +#include #include #include "cygerrno.h" #include "fhandler.h" @@ -1404,11 +1401,9 @@ set_console_title (char *title) 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 (); @@ -1432,5 +1427,5 @@ fhandler_console::de_linearize (const char *buf, const char *unix_name, CloseHandle (h); CloseHandle (oh); - return res; + return; } diff --git a/winsup/cygwin/fhandler_random.cc b/winsup/cygwin/fhandler_random.cc index 99d12c4a5..3a2811214 100644 --- a/winsup/cygwin/fhandler_random.cc +++ b/winsup/cygwin/fhandler_random.cc @@ -20,7 +20,7 @@ details. */ #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), @@ -42,10 +42,10 @@ fhandler_dev_random::crypt_gen_random (void *ptr, size_t len) { 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; @@ -144,7 +144,7 @@ fhandler_dev_random::close (void) { if (crypt_prov) while (!CryptReleaseContext (crypt_prov, 0) - && GetLastError () == ERROR_BUSY) + && GetLastError () == ERROR_BUSY) Sleep(10); return 0; } diff --git a/winsup/cygwin/fhandler_raw.cc b/winsup/cygwin/fhandler_raw.cc index 49c2d029d..f34a02da9 100644 --- a/winsup/cygwin/fhandler_raw.cc +++ b/winsup/cygwin/fhandler_raw.cc @@ -16,6 +16,7 @@ #include #include +#include "cygheap.h" #include "cygerrno.h" #include "fhandler.h" #include "path.h" @@ -25,7 +26,7 @@ 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; @@ -33,20 +34,20 @@ static BOOL write_file (HANDLE fh, const void *buf, DWORD to_write, 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; @@ -54,15 +55,15 @@ static BOOL read_file (HANDLE fh, void *buf, DWORD to_read, 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; } @@ -96,13 +97,13 @@ fhandler_dev_raw::writebuf (void) 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; @@ -120,23 +121,11 @@ fhandler_dev_raw::fhandler_dev_raw (DWORD devtype, const char *name, int unit) : 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) { @@ -150,7 +139,7 @@ fhandler_dev_raw::open (const char *path, int flags, mode_t) if (ret) { if (devbufsiz > 1L) - devbuf = new char[devbufsiz]; + devbuf = (char *) cmalloc (HEAP_BUF, devbufsiz); } else devbufsiz = 0; @@ -174,9 +163,9 @@ fhandler_dev_raw::fstat (struct stat *buf) 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); @@ -241,9 +230,9 @@ fhandler_dev_raw::raw_read (void *ptr, size_t ulen) { 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); @@ -252,9 +241,9 @@ fhandler_dev_raw::raw_read (void *ptr, size_t ulen) { 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); } @@ -262,7 +251,7 @@ fhandler_dev_raw::raw_read (void *ptr, size_t ulen) { 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; } @@ -276,7 +265,7 @@ fhandler_dev_raw::raw_read (void *ptr, size_t ulen) { 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; } @@ -304,7 +293,7 @@ fhandler_dev_raw::raw_read (void *ptr, size_t ulen) { 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; } @@ -317,7 +306,7 @@ fhandler_dev_raw::raw_read (void *ptr, size_t ulen) } 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; } @@ -352,7 +341,7 @@ fhandler_dev_raw::raw_write (const void *ptr, size_t len) 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); @@ -456,7 +445,7 @@ fhandler_dev_raw::dup (fhandler_base *child) 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; @@ -499,12 +488,12 @@ fhandler_dev_raw::ioctl (unsigned int cmd, void *buf) 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; diff --git a/winsup/cygwin/fhandler_serial.cc b/winsup/cygwin/fhandler_serial.cc index 8ea4c9f86..e68e34e11 100644 --- a/winsup/cygwin/fhandler_serial.cc +++ b/winsup/cygwin/fhandler_serial.cc @@ -503,7 +503,7 @@ fhandler_serial::tcsetattr (int action, const struct termios *t) 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 ------------------ */ @@ -867,14 +867,12 @@ fhandler_serial::fixup_after_fork (HANDLE parent) 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 diff --git a/winsup/cygwin/fhandler_tape.cc b/winsup/cygwin/fhandler_tape.cc index 43bbf0f5a..279c7fc37 100644 --- a/winsup/cygwin/fhandler_tape.cc +++ b/winsup/cygwin/fhandler_tape.cc @@ -80,12 +80,12 @@ fhandler_dev_tape::open (const char *path, int flags, mode_t) 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 ]; @@ -324,36 +324,36 @@ fhandler_dev_tape::ioctl (unsigned int cmd, void *buf) 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); @@ -365,7 +365,7 @@ fhandler_dev_tape::ioctl (unsigned int cmd, void *buf) devbufstart = 0; devbuf = buf; devbufsiz = size; - varblkop = op->mt_count == 0; + varblkop = op->mt_count == 0; } } break; diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index bdbe641aa..c342be954 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -22,6 +22,7 @@ details. */ #include "sync.h" #include "sigproc.h" #include "pinfo.h" +#include "cygheap.h" /* Tty master stuff */ @@ -433,7 +434,7 @@ fhandler_tty_slave::fhandler_tty_slave(int num, const char *name) : 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_); @@ -1075,14 +1076,12 @@ fhandler_tty_master::fixup_after_fork (HANDLE child) 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 diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 981862a83..6be5e3a25 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -22,6 +22,7 @@ details. */ #include "sync.h" #include "sigproc.h" #include "pinfo.h" +#include "cygheap.h" #include "child_info.h" #include "perthread.h" @@ -37,14 +38,14 @@ DWORD NO_COPY chunksize = 0; 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) @@ -356,7 +357,7 @@ fork () 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; @@ -365,13 +366,13 @@ fork () /* 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 */ @@ -388,9 +389,9 @@ fork () 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; } @@ -402,7 +403,7 @@ fork () /* 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 @@ -413,7 +414,7 @@ fork () 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"); } @@ -528,15 +529,15 @@ fork () 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); @@ -567,6 +568,7 @@ fork () MALLOC_CHECK; + cygheap_fixup_in_child (hParent); fdtab.fixup_after_fork (hParent); signal_fixup_after_fork (); exec_fixup_after_fork (); diff --git a/winsup/cygwin/heap.cc b/winsup/cygwin/heap.cc index 6c05a5d6e..d1408eb7b 100644 --- a/winsup/cygwin/heap.cc +++ b/winsup/cygwin/heap.cc @@ -14,12 +14,8 @@ details. */ #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; diff --git a/winsup/cygwin/heap.h b/winsup/cygwin/heap.h new file mode 100644 index 000000000..080b415de --- /dev/null +++ b/winsup/cygwin/heap.h @@ -0,0 +1,22 @@ +/* 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 ()) + diff --git a/winsup/cygwin/init.cc b/winsup/cygwin/init.cc index ddf482235..18342e080 100644 --- a/winsup/cygwin/init.cc +++ b/winsup/cygwin/init.cc @@ -29,7 +29,7 @@ WINAPI dll_entry (HANDLE h, DWORD reason, void *static_load) 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; diff --git a/winsup/cygwin/malloc_wrapper.cc b/winsup/cygwin/malloc_wrapper.cc index 7e17fd9ec..2e10cddc5 100644 --- a/winsup/cygwin/malloc_wrapper.cc +++ b/winsup/cygwin/malloc_wrapper.cc @@ -13,6 +13,9 @@ details. */ #include "winsup.h" #include +#include +#include "cygheap.h" +#include "heap.h" #include "sync.h" /* we provide these stubs to call into a user's @@ -60,6 +63,8 @@ extern "C" void _free_r (struct _reent *, void *p) { export_malloc_called = 1; + assert (!incygheap (p)); + assert (inheap (p)); free (p); } #undef free @@ -68,6 +73,8 @@ extern "C" void * _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 @@ -122,6 +129,22 @@ calloc (size_t nmemb, size_t size) 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 @@ -178,22 +201,6 @@ export_calloc (size_t nmemb, size_t 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); -} - /* 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 diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc index bc2764c8f..158b538c0 100644 --- a/winsup/cygwin/mmap.cc +++ b/winsup/cygwin/mmap.cc @@ -210,7 +210,7 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off) { 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 (); @@ -235,7 +235,7 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off) __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; } } @@ -247,7 +247,7 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off) __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; } } @@ -273,7 +273,7 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off) 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); @@ -327,7 +327,7 @@ munmap (caddr_t addr, size_t len) /* 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; } } diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index bcd8f8f29..4f1a8a0be 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -354,18 +354,18 @@ cygwin_socket (int af, int type, int protocol) 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; @@ -781,11 +781,11 @@ cygwin_bind (int fd, struct sockaddr *my_addr, int addrlen) 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); @@ -805,36 +805,36 @@ cygwin_bind (int fd, struct sockaddr *my_addr, int addrlen) 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)) @@ -1032,7 +1032,7 @@ getdomainname (char *domain, int len) * \Device\, where netcard is the name of the net device. * Then look under: * HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\\ - * Parameters\Tcpip + * Parameters\Tcpip * at the IPAddress, Subnetmask and DefaultGateway values for the * required values. * @@ -1709,36 +1709,36 @@ fhandler_socket::ioctl (unsigned int cmd, void *p) case SIOCGIFNETMASK: case SIOCGIFADDR: { - char buf[2048]; - struct ifconf ifc; - ifc.ifc_len = sizeof(buf); - ifc.ifc_buf = buf; - struct ifreq *ifrp; + 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; - } + 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; @@ -1750,15 +1750,15 @@ fhandler_socket::ioctl (unsigned int cmd, void *p) 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, diff --git a/winsup/cygwin/passwd.cc b/winsup/cygwin/passwd.cc index a4ceda503..98ea7b04d 100644 --- a/winsup/cygwin/passwd.cc +++ b/winsup/cygwin/passwd.cc @@ -134,22 +134,22 @@ read_etc_passwd () } 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; } } @@ -164,7 +164,7 @@ search_for (uid_t uid, const char *name) { 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) { diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 48da8c4c9..6400699ee 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -88,6 +88,7 @@ details. */ #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); @@ -150,15 +151,71 @@ struct symlink_info /* 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 && \ @@ -965,7 +1022,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *win32_path, 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); @@ -1082,10 +1139,12 @@ fillin: /* 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) @@ -1095,7 +1154,7 @@ fillin: 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) @@ -2453,10 +2512,9 @@ hash_path_name (unsigned long hash, const char *name) 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, "\\"); @@ -2481,18 +2539,20 @@ get_cwd_win32 () { 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; } @@ -2504,16 +2564,18 @@ getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot) 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; } @@ -2521,21 +2583,21 @@ getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot) 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; } @@ -2549,30 +2611,29 @@ getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot) 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); @@ -2643,12 +2704,13 @@ chdir (const char *dir) __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 @@ -2656,11 +2718,12 @@ chdir (const char *dir) 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; } diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index a4367027b..3f8025af0 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -110,6 +110,11 @@ int __stdcall check_null_empty_path (const char *name); 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 */ diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 0d7e785c3..9ccb8675a 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -68,24 +68,13 @@ set_myself (pid_t pid, HANDLE h) /* 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 { @@ -97,7 +86,7 @@ pinfo_init (LPBYTE info) 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); diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index ef8dffff2..891fd4228 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -72,10 +72,10 @@ public: 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. */ @@ -163,6 +163,6 @@ cygwin_pid (pid_t pid) 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; diff --git a/winsup/cygwin/poll.cc b/winsup/cygwin/poll.cc index fc51be1bb..91cdc2aed 100644 --- a/winsup/cygwin/poll.cc +++ b/winsup/cygwin/poll.cc @@ -48,36 +48,36 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout) 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; diff --git a/winsup/cygwin/registry.cc b/winsup/cygwin/registry.cc index af543ba67..ebe6bb3c6 100644 --- a/winsup/cygwin/registry.cc +++ b/winsup/cygwin/registry.cc @@ -208,11 +208,11 @@ get_registry_hive_path (const PSID psid, char *path) 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; } @@ -229,7 +229,7 @@ load_registry_hive (PSID psid) 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); @@ -239,7 +239,7 @@ load_registry_hive (PSID psid) { 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); } } diff --git a/winsup/cygwin/scandir.cc b/winsup/cygwin/scandir.cc index ce9f46513..793505d2f 100644 --- a/winsup/cygwin/scandir.cc +++ b/winsup/cygwin/scandir.cc @@ -73,11 +73,11 @@ scandir (const char *dir, { 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; diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index a8d578043..843385968 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -34,12 +34,12 @@ extern BOOL allow_ntea; 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) @@ -195,53 +195,53 @@ get_id_from_sid (PSID psid, BOOL search_grp, int *type) int id = -1; if (! search_grp) - { - if (passwd_sem > 0) - return 0; - ++passwd_sem; + { + 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; - } - } + 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; + { + 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; - } - } + 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 */ @@ -261,7 +261,7 @@ get_id_from_sid (PSID psid, BOOL search_grp, int *type) 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; @@ -272,27 +272,27 @@ get_id_from_sid (PSID psid, BOOL search_grp, int *type) 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; - case SidTypeUser: - if (type) - *type = USER; - if (id == -1) - { - struct passwd *pw = getpwnam (account); - if (pw) - id = pw->pw_uid; + if (type) + *type = GROUP; + if (id == -1) + { + struct group *gr = getgrnam (account); + if (gr) + id = gr->gr_gid; } - break; + break; + case SidTypeUser: + if (type) + *type = USER; + if (id == -1) + { + struct passwd *pw = getpwnam (account); + if (pw) + id = pw->pw_uid; + } + break; default: - break; + break; } } if (id == -1) @@ -310,7 +310,7 @@ static BOOL legal_sid_type (SID_NAME_USE type) { return type == SidTypeUser || type == SidTypeGroup - || SidTypeAlias || SidTypeWellKnownGroup; + || SidTypeAlias || SidTypeWellKnownGroup; } BOOL @@ -324,12 +324,12 @@ is_grp_member (uid_t uid, gid_t gid) 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; @@ -355,51 +355,51 @@ lookup_name (const char *name, const char *logsrv, PSID ret_sid) { 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 (); @@ -407,7 +407,7 @@ lookup_name (const char *name, const char *logsrv, PSID ret_sid) 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); @@ -423,7 +423,7 @@ cygwin_set_impersonation_token (const HANDLE hToken) if (myself->token != hToken) { if (myself->token != INVALID_HANDLE_VALUE) - CloseHandle (myself->token); + CloseHandle (myself->token); myself->token = hToken; myself->impersonated = FALSE; } @@ -452,13 +452,13 @@ cygwin_logon_user (const struct passwd *pw, const char *password) 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) @@ -468,12 +468,12 @@ cygwin_logon_user (const struct passwd *pw, const char *password) 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; @@ -512,10 +512,10 @@ read_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, LPDWORD sd_size) 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; @@ -541,12 +541,12 @@ write_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size) 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) { @@ -580,8 +580,8 @@ write_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size) &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) { @@ -664,7 +664,7 @@ out: 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; @@ -721,7 +721,7 @@ get_nt_attribute (const char *file, int *attribute, { *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; } @@ -733,68 +733,68 @@ get_nt_attribute (const char *file, int *attribute, 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; @@ -805,7 +805,7 @@ get_nt_attribute (const char *file, int *attribute, 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); @@ -819,7 +819,7 @@ get_file_attribute (int use_ntsec, const char *file, 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) @@ -831,7 +831,7 @@ get_file_attribute (int use_ntsec, const char *file, } 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)) { @@ -842,12 +842,12 @@ BOOL add_access_allowed_ace (PACL acl, int offset, DWORD attributes, 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)) { @@ -858,7 +858,7 @@ BOOL add_access_denied_ace (PACL acl, int offset, DWORD attributes, if (GetAce(acl, offset, (PVOID *) &ace)) ace->Header.AceFlags |= inherit; len_add += sizeof (ACCESS_DENIED_ACE) - sizeof (DWORD) - + GetLengthSid (sid); + + GetLengthSid (sid); return TRUE; } @@ -888,7 +888,7 @@ alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute, && ! 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 @@ -899,8 +899,8 @@ alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute, { 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"); @@ -949,7 +949,7 @@ alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute, // 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) @@ -961,7 +961,7 @@ alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute, // 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) @@ -973,7 +973,7 @@ alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute, // 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) @@ -990,8 +990,8 @@ alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute, 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); @@ -1001,20 +1001,20 @@ alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute, // 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 @@ -1033,33 +1033,33 @@ alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute, && 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 @@ -1094,7 +1094,7 @@ alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute, 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; @@ -1119,8 +1119,8 @@ set_nt_attribute (const char *file, uid_t uid, gid_t gid, 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) @@ -1129,7 +1129,7 @@ set_file_attribute (int use_ntsec, const char *file, if (!use_ntsec || !allow_ntsec) { if (! NTWriteEA (file, ".UNIXATTR", - (char *) &attribute, sizeof (attribute))) + (char *) &attribute, sizeof (attribute))) { __seterrno (); return -1; @@ -1147,8 +1147,8 @@ int 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 @@ -1158,7 +1158,7 @@ searchace (aclent_t *aclp, int nentries, int type, int id = -1) 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; } @@ -1247,70 +1247,70 @@ setacl (const char *file, int nentries, aclent_t *aclbufp) 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; @@ -1422,7 +1422,7 @@ getacl (const char *file, DWORD attr, int nentries, aclent_t *aclbufp) 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; @@ -1433,64 +1433,64 @@ getacl (const char *file, DWORD attr, int nentries, aclent_t *aclbufp) 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) @@ -1498,7 +1498,7 @@ getacl (const char *file, DWORD attr, int nentries, aclent_t *aclbufp) { 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 @@ -1537,53 +1537,53 @@ acl_access (const char *path, int flags) 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; + { + 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 (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; @@ -1592,7 +1592,7 @@ acl_access (const char *path, int flags) 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); @@ -1608,82 +1608,82 @@ acl_worker (const char *path, int cmd, int nentries, aclent_t *aclbufp, 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); @@ -1745,101 +1745,101 @@ aclcheck (aclent_t *aclbufp, int nentries, int *which) 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 @@ -1852,7 +1852,7 @@ aclcheck (aclent_t *aclbufp, int nentries, int *which) ) { if (which) - *which = -1; + *which = -1; return MISS_ERROR; } return 0; @@ -1936,8 +1936,8 @@ aclfrommode(aclent_t *aclbufp, int nentries, mode_t *modep) 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); @@ -1946,16 +1946,16 @@ aclfrommode(aclent_t *aclbufp, int nentries, mode_t *modep) 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; } @@ -2002,40 +2002,40 @@ acltotext (aclent_t *aclbufp, int aclcnt) 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); } @@ -2078,91 +2078,91 @@ aclfromtext (char *acltextp, int *) 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)); diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 2b0bd2d6b..c7181fb53 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -841,10 +841,10 @@ peek_serial (select_record *s, int) { 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 diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc index 2010d189b..1cb8e6e9c 100644 --- a/winsup/cygwin/shared.cc +++ b/winsup/cygwin/shared.cc @@ -209,7 +209,7 @@ sec_user (PVOID sa_buf, PSID sid2, BOOL inherit) 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]; @@ -221,46 +221,46 @@ sec_user (PVOID sa_buf, PSID sid2, BOOL inherit) 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"); /* diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 48218effe..770fea46d 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -19,7 +19,6 @@ details. */ #include #include #include -#include #include "cygerrno.h" #include "fhandler.h" #include "path.h" @@ -28,10 +27,9 @@ details. */ #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[] = @@ -171,7 +169,6 @@ handle (int n, int direction) */ HANDLE NO_COPY hExeced = NULL; -DWORD NO_COPY exec_exit = 0; int iscmd (const char *argv0, const char *what) @@ -242,19 +239,66 @@ exec_fixup_after_fork () 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"); @@ -271,46 +315,69 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv, return (-1); } - /* 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++) - /* nothing */; - - char *real_path; - path_conv real_path_buf; + path_conv real_path; linebuf one_line; - if (argc == 3 && argv[1][0] == '/' && argv[1][1] == 'c' && + 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. */ + + int ac; + for (ac = 0; argv[ac]; ac++) + /* nothing */; + + av newargv (ac, argv); + + 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 */ @@ -351,8 +418,7 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv, if (buf[0] != '#' || buf[1] != '!') { - strcpy (buf, "sh"); /* shell script without magic */ - pgm = buf; + pgm = (char *) "/bin/sh"; ptr = buf + 2; arg1 = NULL; } @@ -379,87 +445,84 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv, 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++) - { - 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 - { - 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); - } - MALLOC_CHECK; - one_line.add (" ", 1); - MALLOC_CHECK; - } - - MALLOC_CHECK; - if (one_line.ix) - one_line.buf[one_line.ix - 1] = '\0'; + if (real_path.iscygexec ()) + for (int i = newargv.calloced; i < newargv.argc; i++) + newargv[i] = cstrdup (newargv[i]); else - one_line.add ("", 1); - MALLOC_CHECK; + { + for (int i = 0; i < newargv.argc; i++) + { + 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 ("\"", 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); + } + MALLOC_CHECK; + 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; @@ -470,53 +533,7 @@ skip_arg_parsing: /* 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); @@ -525,7 +542,14 @@ skip_arg_parsing: 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]; @@ -533,9 +557,12 @@ skip_arg_parsing: 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) @@ -561,22 +588,22 @@ skip_arg_parsing: 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); @@ -584,8 +611,8 @@ skip_arg_parsing: 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 */ @@ -593,18 +620,18 @@ skip_arg_parsing: &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 */ @@ -613,17 +640,13 @@ skip_arg_parsing: &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) @@ -651,8 +674,8 @@ skip_arg_parsing: 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; @@ -676,8 +699,6 @@ skip_arg_parsing: } 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; @@ -723,7 +744,7 @@ skip_arg_parsing: DWORD res; - if (mode == _P_OVERLAY) + if (mode == _P_OVERLAY || mode == _P_VFORK) { BOOL exited; @@ -732,54 +753,45 @@ skip_arg_parsing: 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) - { - sigproc_printf ("subprocess still alive after signal"); - res = exec_exit; - } - 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; - } + 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)) + { + 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: @@ -796,8 +808,7 @@ skip_arg_parsing: break; } - if (nwait > 2) - ForceCloseHandle (spr); + ForceCloseHandle (spr); sigproc_printf ("res = %x", res); @@ -813,18 +824,19 @@ skip_arg_parsing: /* 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) @@ -837,7 +849,6 @@ skip_arg_parsing: system_printf ("myself->hProcess %x", myself->hProcess); } } - res = EXIT_REPARENTING; ForceCloseHandle1 (hExeced, childhProc); hExeced = INVALID_HANDLE_VALUE; } @@ -848,15 +859,26 @@ skip_arg_parsing: } 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; } @@ -889,29 +911,30 @@ _spawnve (HANDLE hToken, int mode, const char *path, const char *const *argv, 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; } diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 92a53a45d..876ed4cee 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -21,7 +21,6 @@ details. */ #include #include #include -#include #include #include /* for UNLEN */ #include "cygerrno.h" @@ -32,6 +31,7 @@ details. */ #include "sync.h" #include "sigproc.h" #include "pinfo.h" +#include extern BOOL allow_ntsec; @@ -1015,8 +1015,8 @@ stat_worker (const char *caller, const char *name, struct stat *buf, 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) { @@ -1421,6 +1421,16 @@ pathconf (const char *file, int v) } } +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) { @@ -1434,20 +1444,8 @@ ctermid (char *str) 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); @@ -1570,8 +1568,7 @@ setmode (int fd, int mode) } /* ftruncate: P96 5.6.7.1 */ -extern "C" -int +extern "C" int ftruncate (int fd, off_t length) { int res = -1; @@ -1609,8 +1606,7 @@ ftruncate (int fd, off_t length) /* 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; @@ -1632,8 +1628,7 @@ truncate (const char *pathname, off_t length) return res; } -extern "C" -long +extern "C" long get_osfhandle (int fd) { long res = -1; @@ -1651,8 +1646,7 @@ get_osfhandle (int fd) return res; } -extern "C" -int +extern "C" int statfs (const char *fname, struct statfs *sfs) { if (!sfs) @@ -1692,8 +1686,7 @@ statfs (const char *fname, struct statfs *sfs) return 0; } -extern "C" -int +extern "C" int fstatfs (int fd, struct statfs *sfs) { if (fdtab.not_open (fd)) @@ -1706,8 +1699,7 @@ fstatfs (int fd, struct statfs *sfs) } /* setpgid: POSIX 4.3.3.1 */ -extern "C" -int +extern "C" int setpgid (pid_t pid, pid_t pgid) { int res = -1; @@ -1746,8 +1738,7 @@ out: return res; } -extern "C" -pid_t +extern "C" pid_t getpgid (pid_t pid) { if (pid == 0) @@ -1762,22 +1753,19 @@ getpgid (pid_t pid) 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)) @@ -1789,8 +1777,7 @@ ptsname (int fd) } /* FIXME: what is this? */ -extern "C" -int +extern "C" int regfree () { return 0; @@ -1802,8 +1789,7 @@ regfree () 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); @@ -1811,8 +1797,7 @@ mknod () } /* setgid: POSIX 4.2.2.1 */ -extern "C" -int +extern "C" int setgid (gid_t gid) { int ret = setegid (gid); @@ -1822,8 +1807,7 @@ setgid (gid_t gid) } /* setuid: POSIX 4.2.2.1 */ -extern "C" -int +extern "C" int setuid (uid_t uid) { int ret = seteuid (uid); @@ -1836,8 +1820,7 @@ setuid (uid_t uid) extern char *internal_getlogin (_pinfo *pi); /* seteuid: standards? */ -extern "C" -int +extern "C" int seteuid (uid_t uid) { if (os_being_run == winNT) diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index da3b0dac1..d685ef37d 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -196,7 +196,7 @@ MTinterface::Find (void *_value, int (*comp) (void *, void *), register int &_in { current = _list->items[_index]; if (current->used && comp (current, _value)) - break; + break; current = NULL; } return current; @@ -211,7 +211,7 @@ MTinterface::Find (MTitem & _item, MTList * _list) { current = _list->items[_index]; if (current->used && current == &_item) - break; + break; } return (_index == _list->index ? -1 : _index); }; @@ -481,7 +481,7 @@ thread_init_wrapper (void *_arg) 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 @@ -520,7 +520,7 @@ thread_init_wrapper (void *_arg) // FIX ME : cleanup code -// thread->used = false; // release thread entry +// thread->used = false; // release thread entry thread->return_ptr = ret; ExitThread (0); } @@ -595,7 +595,7 @@ __pthread_join (pthread_t * thread, void **return_val) if (item->joinable == 'N') { if (return_val) - *return_val = NULL; + *return_val = NULL; return EINVAL; } else @@ -603,7 +603,7 @@ __pthread_join (pthread_t * thread, void **return_val) item->joinable = 'N'; WaitForSingleObject ((HANDLE)*thread, INFINITE); if (return_val) - *return_val = item->return_ptr; + *return_val = item->return_ptr; }/* End if*/ return 0; @@ -651,7 +651,7 @@ __pthread_continue (pthread_t * thread) return ESRCH; if (item->suspended == true) - ResumeThread ((HANDLE)*thread); + ResumeThread ((HANDLE)*thread); item->suspended = false; return 0; @@ -994,4 +994,4 @@ extern "C" } } -#endif // MT_SAFE +#endif // MT_SAFE diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index aed02dc54..4b265fbd1 100644 --- a/winsup/cygwin/thread.h +++ b/winsup/cygwin/thread.h @@ -74,9 +74,6 @@ struct _winsup_t /* path.cc */ struct mntent _ret; - char *_cwd_win32; - char *_cwd_posix; - unsigned long _cwd_hash; int _iteration; /* strerror */ @@ -306,6 +303,6 @@ int __sem_post (sem_t * sem); }; -#endif // MT_SAFE +#endif // MT_SAFE -#endif // _CYGNUS_THREADS_ +#endif // _CYGNUS_THREADS_ diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index fc3f8bf40..a0f9ae82d 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -40,130 +40,130 @@ internal_getlogin (_pinfo *pi) /* 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; @@ -187,13 +187,13 @@ uinfo_init () 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. */ diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index 56126692a..ce067260e 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -1,6 +1,6 @@ /* 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. @@ -83,9 +83,9 @@ extern os_type os_being_run; 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 @@ -200,11 +200,7 @@ extern "C" int dll_noncygwin_dllcrt0 (HMODULE, per_process *); 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); @@ -236,7 +232,7 @@ extern int cygwin_finished_initializing; /* 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); @@ -258,6 +254,7 @@ extern "C" char *__stdcall rootdir (char *full_path); 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); @@ -278,12 +275,6 @@ char *__stdcall strcasestr (const char *searchee, const char *lookfor); 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); @@ -375,6 +366,7 @@ void __stdcall update_envptrs (); 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;