aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Seebach <peter.seebach@windriver.com>2016-02-23 15:47:32 -0600
committerPeter Seebach <peter.seebach@windriver.com>2016-02-23 15:47:32 -0600
commit6b14fe133eea0148ad232e41bc12cc2e6e9c969f (patch)
tree5c17763d017014c3fc98a0737fd6373ed89937a5
parent786c6d3813622d18e12d36c4aa722af6a417c8fa (diff)
downloadpseudo-6b14fe133eea0148ad232e41bc12cc2e6e9c969f.tar.gz
pseudo-6b14fe133eea0148ad232e41bc12cc2e6e9c969f.tar.bz2
pseudo-6b14fe133eea0148ad232e41bc12cc2e6e9c969f.zip
Improve logfile handling
For sound reasons, the server wants to be sure no client is on fd 2. However, the client shouldn't force the pseudo log file to be fd 2; it should leave stderr alone when a log file is specified.
-rw-r--r--ChangeLog.txt5
-rw-r--r--pseudo.h2
-rw-r--r--pseudo_server.c10
-rw-r--r--pseudo_util.c13
-rw-r--r--pseudo_wrappers.c2
5 files changed, 23 insertions, 9 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index eb72127..1a9656b 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,3 +1,8 @@
+2016-02-16:
+ * (seebs) don't try to force pseudo's debug fd to fd 2 in clients.
+ Also, don't allow server to end up with a client on fd 2, whether
+ or not fd 2 is already in use.
+
2016-02-09:
* (seebs) 1.7.5 release
diff --git a/pseudo.h b/pseudo.h
index 81db201..eb8d3da 100644
--- a/pseudo.h
+++ b/pseudo.h
@@ -82,7 +82,7 @@ extern char *pseudo_get_prefix(char *);
extern char *pseudo_get_bindir(void);
extern char *pseudo_get_libdir(void);
extern char *pseudo_get_localstatedir(void);
-extern int pseudo_logfile(char *defname);
+extern int pseudo_logfile(char *defname, int prefer_fd);
extern ssize_t pseudo_sys_path_max(void);
extern ssize_t pseudo_path_max(void);
#define PSEUDO_PWD_MAX 4096
diff --git a/pseudo_server.c b/pseudo_server.c
index 4ceaa47..7127082 100644
--- a/pseudo_server.c
+++ b/pseudo_server.c
@@ -165,7 +165,7 @@ pseudo_server_start(int daemonize) {
pseudo_new_pid();
fclose(stdin);
fclose(stdout);
- pseudo_logfile(PSEUDO_LOGFILE);
+ pseudo_logfile(PSEUDO_LOGFILE, 2);
} else {
/* Write the pid if we don't daemonize */
pseudo_server_write_pid(getpid());
@@ -480,6 +480,14 @@ pseudo_server_loop(void) {
FD_ISSET(clients[0].fd, &reads))) {
len = sizeof(client);
if ((fd = accept(listen_fd, (struct sockaddr *) &client, &len)) != -1) {
+ /* Don't allow clients to end up on fd 2, because glibc's
+ * malloc debug uses that fd unconditionally.
+ */
+ if (fd == 2) {
+ int newfd = fcntl(fd, F_DUPFD, 3);
+ close(fd);
+ fd = newfd;
+ }
pseudo_debug(PDBGF_SERVER, "new client fd %d\n", fd);
open_client(fd);
/* A new client implicitly cancels any
diff --git a/pseudo_util.c b/pseudo_util.c
index c81df5a..9d24362 100644
--- a/pseudo_util.c
+++ b/pseudo_util.c
@@ -1313,7 +1313,7 @@ pseudo_etc_file(const char *file, char *realname, int flags, const char **search
/* set up a log file */
int
-pseudo_logfile(char *defname) {
+pseudo_logfile(char *defname, int prefer_fd) {
char *pseudo_path;
char *filename = pseudo_get_value("PSEUDO_DEBUG_FILE");
char *s;
@@ -1401,15 +1401,16 @@ pseudo_logfile(char *defname) {
if (fd == -1) {
pseudo_diag("help: can't open log file %s: %s\n", pseudo_path, strerror(errno));
} else {
- /* try to force fd to 2. We do this because glibc's malloc
+ /* try to force fd to prefer_fd. We do this because glibc's malloc
* debug unconditionally writes to fd 2, and we don't want
* a client process ending op on fd 2, or server debugging
- * becomes a nightmare.
+ * becomes a nightmare. So, server sets prefer_fd to 2. Client
+ * leaves it at -1.
*/
- if (fd != 2) {
+ if (prefer_fd >= 0 && fd != prefer_fd) {
int newfd;
- close(2);
- newfd = dup2(fd, 2);
+ close(prefer_fd);
+ newfd = dup2(fd, prefer_fd);
if (newfd != -1) {
fd = newfd;
}
diff --git a/pseudo_wrappers.c b/pseudo_wrappers.c
index 34d7f23..ba8b52d 100644
--- a/pseudo_wrappers.c
+++ b/pseudo_wrappers.c
@@ -182,7 +182,7 @@ pseudo_init_wrappers(void) {
/* Once the wrappers are setup, we can now use open... so
* setup the logfile, if necessary...
*/
- pseudo_logfile(NULL);
+ pseudo_logfile(NULL, -1);
pseudo_magic();
pseudo_droplock();