summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorscottc <scottc>2002-06-18 21:16:08 +0000
committerscottc <scottc>2002-06-18 21:16:08 +0000
commitb26e9c2b0625abeb6a1527e39a1412c88f79d26d (patch)
treef6af03fdd9fa88c725e685c016278fe96723ba45
parent5027b62c5b84c975903bf0ccfbfc621fb59e9aea (diff)
downloadgdb-b26e9c2b0625abeb6a1527e39a1412c88f79d26d.tar.gz
* woutsup.h (cygserver_running): Add declaration.
(api_fatal): Eliminate. * include/cygwin/cygserver.h (client_request_get_version::check_version): Change return type to bool. (check_cygserver_available): New function. (cygserver_init): Add check_version_too argument. * cygserver_client.cc (allow_daemon): Make a bool. (client_request_get_version::make_request): See errno on error. Remove special case for CYGSERVER_REQUEST_GET_VERSION; this is now handled in cygserver_init(). (client_request_get_version::check_version): Use syscall_printf() instead of api_fatal(). Return true if cygserver version is compatible. (check_cygserver_available): New function; code moved here from cygserver_init(). (cygserver_init): Move some code into check_cygserver_available(). * cygserver.cc (__set_errno): Copy from debug.cc so that set_errno() can be used when __OUTSIDE_CYGWIN__. (main): Call cygserver_init() to set up cygserver_running and add checks against this to (try and) prevent multiple copies of cygserver running simultaneously. Remember to delete all transport connections so that (one day) the transport classes can tidy up on cygserver shutdown.
-rw-r--r--winsup/cygserver/woutsup.h10
-rw-r--r--winsup/cygwin/ChangeLog27
-rwxr-xr-xwinsup/cygwin/cygserver.cc63
-rwxr-xr-xwinsup/cygwin/cygserver_client.cc150
-rwxr-xr-xwinsup/cygwin/include/cygwin/cygserver.h5
-rw-r--r--winsup/cygwin/woutsup.h10
6 files changed, 177 insertions, 88 deletions
diff --git a/winsup/cygserver/woutsup.h b/winsup/cygserver/woutsup.h
index ae62ac63d64..1e1d52c1d9c 100644
--- a/winsup/cygserver/woutsup.h
+++ b/winsup/cygserver/woutsup.h
@@ -38,16 +38,16 @@
/* The one function we use from winuser.h most of the time */
extern "C" DWORD WINAPI GetLastError (void);
-/* From "winsup.h". */
+extern int cygserver_running;
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ >= 199900L
#define NEW_MACRO_VARARGS
#endif
/*
- * A reproduction of the api_fatal() and <sys/strace.h> macros. This
- * allows code that runs both inside and outside the Cygwin DLL to use
- * the same macros for logging messages.
+ * A reproduction of the <sys/strace.h> macros. This allows code that
+ * runs both inside and outside the Cygwin DLL to use the same macros
+ * for logging messages.
*/
extern "C" void __cygserver__printf (const char *, const char *, ...);
@@ -74,8 +74,6 @@ extern "C" void __cygserver__printf (const char *, const char *, ...);
#endif /* !NEW_MACRO_VARARGS */
-#define api_fatal system_printf
-
#ifdef DEBUGGING
#define debug_printf system_printf
#define paranoid_printf system_printf
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index dafcf45cc69..2802f2a4a56 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,30 @@
+2002-06-18 Conrad Scott <conrad.scott@dsl.pipex.com>
+
+ * woutsup.h (cygserver_running): Add declaration.
+ (api_fatal): Eliminate.
+ * include/cygwin/cygserver.h
+ (client_request_get_version::check_version): Change return type to
+ bool.
+ (check_cygserver_available): New function.
+ (cygserver_init): Add check_version_too argument.
+ * cygserver_client.cc (allow_daemon): Make a bool.
+ (client_request_get_version::make_request): See errno on error.
+ Remove special case for CYGSERVER_REQUEST_GET_VERSION; this is now
+ handled in cygserver_init().
+ (client_request_get_version::check_version): Use syscall_printf()
+ instead of api_fatal(). Return true if cygserver version is
+ compatible.
+ (check_cygserver_available): New function; code moved here from
+ cygserver_init().
+ (cygserver_init): Move some code into check_cygserver_available().
+ * cygserver.cc (__set_errno): Copy from debug.cc so that
+ set_errno() can be used when __OUTSIDE_CYGWIN__.
+ (main): Call cygserver_init() to set up cygserver_running and add
+ checks against this to (try and) prevent multiple copies of
+ cygserver running simultaneously. Remember to delete all
+ transport connections so that (one day) the transport classes can
+ tidy up on cygserver shutdown.
+
2002-06-17 Conrad Scott <conrad.scott@dsl.pipex.com>
* cygserver.cc (main): Adjust tracing output for a cleaner display
diff --git a/winsup/cygwin/cygserver.cc b/winsup/cygwin/cygserver.cc
index bbbab9064d8..d482a23245f 100755
--- a/winsup/cygwin/cygserver.cc
+++ b/winsup/cygwin/cygserver.cc
@@ -29,6 +29,7 @@ details. */
#include <ostream.h>
#include "cygwin_version.h"
+#include "cygerrno.h"
#include "cygserver_shm.h"
#include "cygwin/cygserver.h"
@@ -119,6 +120,17 @@ __cygserver__printf (const char * const function, const char * const fmt, ...)
return;
}
+#ifdef DEBUGGING
+
+int __stdcall
+__set_errno (const char *func, int ln, int val)
+{
+ debug_printf ("%s:%d val %d", func, ln, val);
+ return _impure_ptr->_errno = val;
+}
+
+#endif /* DEBUGGING */
+
static BOOL
setup_privileges ()
{
@@ -627,39 +639,66 @@ main (const int argc, char *argv[])
case '?':
cerr << "Try `" << pgm << " --help' for more information." << endl;
- return 1;
+ exit (1);
}
if (optind != argc)
{
cerr << pgm << ": too many arguments" << endl;
- return 1;
+ exit (1);
}
+ /*
+ * This has been run in the cygwin DLL but we use some of the DLL
+ * functions, e.g. client_request::make_request() in the server so
+ * we need to duplicate it all up here. Sigh.
+ */
+ cygserver_init (false); // false == don't check version
+
+ assert ( cygserver_running == CYGSERVER_OK \
+ || cygserver_running == CYGSERVER_DEAD);
+
if (shutdown)
{
+ if (cygserver_running != CYGSERVER_OK)
+ {
+ cout << pgm << ": cygserver is not running" << endl;
+ exit (1);
+ }
+
client_request_shutdown req;
if (req.make_request () == -1 || req.error_code ())
- return 1;
+ {
+ cout << pgm << ": shutdown request failed: "
+ << strerror(errno) << endl;
+ exit (1);
+ }
+
+ // FIXME: It would be nice to wait here for the daemon to exit.
return 0;
}
- transport_layer_base * const transport = create_server_transport ();
-
- assert (transport);
+ if (cygserver_running == CYGSERVER_OK)
+ {
+ cout << pgm << ": cygserver is already running" << endl;
+ exit (1);
+ }
- print_version (pgm);
- setbuf (stdout, NULL);
- printf ("daemon starting up");
if (signal (SIGQUIT, handle_signal) == SIG_ERR)
{
system_printf ("could not install signal handler (%d)- aborting startup",
errno);
exit (1);
}
- printf (".");
+
+ transport_layer_base * const transport = create_server_transport ();
+ assert (transport);
+
+ print_version (pgm);
+ setbuf (stdout, NULL);
+ printf ("daemon starting up");
transport->listen ();
printf (".");
class process_cache cache (2);
@@ -691,9 +730,11 @@ main (const int argc, char *argv[])
printf ("\nShutdown request received - new requests will be denied\n");
request_queue.cleanup ();
printf ("All pending requests processed\n");
- transport->close ();
+ delete transport;
printf ("No longer accepting requests - cygwin will operate in daemonless mode\n");
cache.cleanup ();
printf ("All outstanding process-cache activities completed\n");
printf ("daemon shutdown\n");
+
+ return 0;
}
diff --git a/winsup/cygwin/cygserver_client.cc b/winsup/cygwin/cygserver_client.cc
index 5bc61ceb645..e8a725d030c 100755
--- a/winsup/cygwin/cygserver_client.cc
+++ b/winsup/cygwin/cygserver_client.cc
@@ -24,6 +24,8 @@ details. */
#include <stdio.h>
#include <unistd.h>
+#include "cygerrno.h"
+
#include "cygwin/cygserver_transport.h"
#include "cygwin/cygserver_transport_pipes.h"
#include "cygwin/cygserver_transport_sockets.h"
@@ -35,7 +37,7 @@ int cygserver_running = CYGSERVER_UNKNOWN;
/* On by default during development. For release, we probably want off
* by default.
*/
-int allow_daemon = TRUE;
+bool allow_daemon = true;
client_request_get_version::client_request_get_version ()
: client_request (CYGSERVER_REQUEST_GET_VERSION, &version, sizeof (version))
@@ -45,22 +47,35 @@ client_request_get_version::client_request_get_version ()
syscall_printf ("created");
}
-void
+/*
+ * client_request_get_version::check_version()
+ *
+ * The major version and API version numbers must match exactly. An
+ * older than expected minor version number is accepted (as long as
+ * the first numbers match, that is).
+ */
+
+bool
client_request_get_version::check_version () const
{
- if (version.major != CYGWIN_SERVER_VERSION_MAJOR ||
- version.api != CYGWIN_SERVER_VERSION_API ||
- version.minor > CYGWIN_SERVER_VERSION_MINOR)
- api_fatal ("incompatible version of cygwin server:\n"
- "client version %d.%d.%d.%d, server version %ld.%ld.%ld.%ld",
- CYGWIN_SERVER_VERSION_MAJOR,
- CYGWIN_SERVER_VERSION_API,
- CYGWIN_SERVER_VERSION_MINOR,
- CYGWIN_SERVER_VERSION_PATCH,
- version.major,
- version.api,
- version.minor,
- version.patch);
+ const bool ok = (version.major == CYGWIN_SERVER_VERSION_MAJOR
+ && version.api == CYGWIN_SERVER_VERSION_API
+ && version.minor <= CYGWIN_SERVER_VERSION_MINOR);
+
+ if (!ok)
+ syscall_printf (("incompatible version of cygwin server: "
+ "client version %d.%d.%d.%d, "
+ "server version %ld.%ld.%ld.%ld"),
+ CYGWIN_SERVER_VERSION_MAJOR,
+ CYGWIN_SERVER_VERSION_API,
+ CYGWIN_SERVER_VERSION_MINOR,
+ CYGWIN_SERVER_VERSION_PATCH,
+ version.major,
+ version.api,
+ version.minor,
+ version.patch);
+
+ return ok;
}
#ifdef __INSIDE_CYGWIN__
@@ -313,13 +328,21 @@ client_request::~client_request ()
int
client_request::make_request ()
{
+ assert ( cygserver_running == CYGSERVER_OK \
+ || cygserver_running == CYGSERVER_DEAD);
+
if (!allow_daemon)
- return -1;
+ {
+ set_errno (ENOSYS);
+ return -1;
+ }
/* Don't retry every request if the server's not there */
- if (cygserver_running == CYGSERVER_DEAD
- && request_code() != CYGSERVER_REQUEST_GET_VERSION)
- return -1;
+ if (cygserver_running != CYGSERVER_OK)
+ {
+ set_errno (ENOSYS);
+ return -1;
+ }
class transport_layer_base * const transport = create_server_transport ();
@@ -452,32 +475,50 @@ client_request::handle (transport_layer_base * const conn,
#endif /* !__INSIDE_CYGWIN__ */
-#ifdef __INSIDE_CYGWIN__
-
-#if 0
-BOOL
-check_cygserver_available ()
+bool
+check_cygserver_available (const bool check_version_too)
{
- BOOL ret_val = FALSE;
- HANDLE pipe = CreateFile (pipe_name,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- &sec_all_nih,
- OPEN_EXISTING,
- 0,
- NULL);
- if (pipe != INVALID_HANDLE_VALUE || GetLastError () != ERROR_PIPE_BUSY)
- ret_val = TRUE;
-
- if (pipe && pipe != INVALID_HANDLE_VALUE)
- CloseHandle (pipe);
-
- return (ret_val);
+ client_request_get_version req;
+
+ // This indicates that we failed to connect to cygserver at all but
+ // that's fine as cygwin doesn't need it to be running.
+ if (req.make_request () == -1)
+ {
+ return false;
+ }
+
+ // We connected to the server but something went wrong after that
+ // (in sending the message, in cygserver itself, or in receiving the
+ // reply).
+ if (req.error_code () != 0)
+ {
+ syscall_printf ("failure in cygserver version request: %d",
+ req.error_code ());
+ syscall_printf ("process will continue without cygserver support");
+ return false;
+ }
+
+ if (check_version_too && !req.check_version ())
+ {
+ return false;
+ }
+
+ return true;
}
-#endif
+
+/*
+ * check_cygserver_available()
+ *
+ * FIXME: This is being used for two different purposes: bad. Used by
+ * the DLL in crt to check for the existence of a compatible
+ * cygserver.Used by cygserver itself at start up to probe for whether
+ * another copy of cygserver is running (w/o checking the version).
+ * These should be separated out: the probing functionality should
+ * probably be moved into the transport layer.
+ */
void
-cygserver_init ()
+cygserver_init (const bool check_version_too)
{
if (!allow_daemon)
{
@@ -486,32 +527,15 @@ cygserver_init ()
}
if (cygserver_running == CYGSERVER_OK)
- return;
-
- client_request_get_version req;
-
- // This indicates that we failed to connect to cygserver at all but
- // that's fine as cygwin doesn't need it to be running.
- if (req.make_request () == -1)
{
- cygserver_running = CYGSERVER_DEAD;
return;
}
- // We connected to the server but something went wrong after that
- // (sending the message, cygserver itself, or receiving the reply).
- if (req.error_code () != 0)
- {
- cygserver_running = CYGSERVER_DEAD;
- debug_printf ("failure in cygserver version request: %d",
- req.error_code ());
- debug_printf ("process will continue without cygserver support");
- return;
- }
+ assert ( cygserver_running == CYGSERVER_UNKNOWN \
+ || cygserver_running == CYGSERVER_DEAD);
- req.check_version (); // Dies if bad . . .
+ cygserver_running = CYGSERVER_OK; // Needed for make_request() to work.
- cygserver_running = CYGSERVER_OK;
+ if (!check_cygserver_available (check_version_too))
+ cygserver_running = CYGSERVER_DEAD;
}
-
-#endif /* __INSIDE_CYGWIN__ */
diff --git a/winsup/cygwin/include/cygwin/cygserver.h b/winsup/cygwin/include/cygwin/cygserver.h
index ccc4b6b1030..cda6df0ab4f 100755
--- a/winsup/cygwin/include/cygwin/cygserver.h
+++ b/winsup/cygwin/include/cygwin/cygserver.h
@@ -108,7 +108,7 @@ private:
public:
client_request_get_version ();
- void check_version () const;
+ bool check_version () const;
private:
struct request_get_version version;
@@ -173,6 +173,7 @@ private:
#endif
};
-extern void cygserver_init ();
+extern bool check_cygserver_available (bool check_version_too = true);
+extern void cygserver_init (bool check_version_too = true);
#endif /* _CYGSERVER_H_ */
diff --git a/winsup/cygwin/woutsup.h b/winsup/cygwin/woutsup.h
index ae62ac63d64..1e1d52c1d9c 100644
--- a/winsup/cygwin/woutsup.h
+++ b/winsup/cygwin/woutsup.h
@@ -38,16 +38,16 @@
/* The one function we use from winuser.h most of the time */
extern "C" DWORD WINAPI GetLastError (void);
-/* From "winsup.h". */
+extern int cygserver_running;
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ >= 199900L
#define NEW_MACRO_VARARGS
#endif
/*
- * A reproduction of the api_fatal() and <sys/strace.h> macros. This
- * allows code that runs both inside and outside the Cygwin DLL to use
- * the same macros for logging messages.
+ * A reproduction of the <sys/strace.h> macros. This allows code that
+ * runs both inside and outside the Cygwin DLL to use the same macros
+ * for logging messages.
*/
extern "C" void __cygserver__printf (const char *, const char *, ...);
@@ -74,8 +74,6 @@ extern "C" void __cygserver__printf (const char *, const char *, ...);
#endif /* !NEW_MACRO_VARARGS */
-#define api_fatal system_printf
-
#ifdef DEBUGGING
#define debug_printf system_printf
#define paranoid_printf system_printf