[patch] new pty allocation strategy for BSD
- From: Roland Illig <roland illig gmx de>
- To: MC Devel <mc-devel gnome org>
- Subject: [patch] new pty allocation strategy for BSD
- Date: Sat, 04 Feb 2006 13:06:50 +0100
Hi,
subshell.c currently contains hard-coded values for the available pty
names. These names do not match with the ptys that can be found on
actual systems. NetBSD 3.0 has ptyp[0-9A-Za-z], as well as
pty[qrs][0-9A-Za-z], so mc can only use 64 of the 100 available ptys.
There may be similar issues on other systems, I haven't checked.
The appended patch just scans through the /dev/ directory, looking for
anything that matches /^pty..$/.
Roland
Index: subshell.c
===================================================================
RCS file: /cvsroot/mc/mc/src/subshell.c,v
retrieving revision 1.90
diff -u -p -r1.90 subshell.c
--- subshell.c 23 Jan 2006 18:55:36 -0000 1.90
+++ subshell.c 4 Feb 2006 11:57:08 -0000
@@ -39,6 +39,10 @@
#endif
#include <unistd.h>
+#ifndef HAVE_GRANTPT
+# include <dirent.h>
+#endif
+
#ifdef HAVE_STROPTS_H
# include <stropts.h> /* For I_PUSH */
#endif /* HAVE_STROPTS_H */
@@ -67,7 +71,7 @@ static char tcsh_fifo[128];
static void init_raw_mode (void);
static int feed_subshell (int how, int fail_on_error);
static void synchronize (void);
-static int pty_open_master (char *pty_name);
+static int pty_open_master (char *pty_name, size_t pty_name_size);
static int pty_open_slave (const char *pty_name);
static int resize_tty (int fd);
@@ -406,7 +410,7 @@ init_subshell (void)
/* FIXME: We may need to open a fresh pty each time on SVR4 */
- subshell_pty = pty_open_master (pty_name);
+ subshell_pty = pty_open_master (pty_name, sizeof(pty_name));
if (subshell_pty == -1) {
fprintf (stderr, "Cannot open master side of pty: %s\r\n",
unix_error_string (errno));
@@ -1071,7 +1075,7 @@ static void synchronize (void)
/* System V version of pty_open_master */
-static int pty_open_master (char *pty_name)
+static int pty_open_master (char *pty_name, size_t pty_name_size)
{
char *slave_name;
int pty_master;
@@ -1082,10 +1086,10 @@ static int pty_open_master (char *pty_na
/* getpt () is a GNU extension (glibc 2.1.x) */
pty_master = getpt ();
#elif IS_AIX
- strcpy (pty_name, "/dev/ptc");
+ g_strlcpy (pty_name, "/dev/ptc", pty_name_size);
pty_master = open (pty_name, O_RDWR);
#else
- strcpy (pty_name, "/dev/ptmx");
+ g_strlcpy (pty_name, "/dev/ptmx", pty_name_size);
pty_master = open (pty_name, O_RDWR);
#endif
@@ -1099,7 +1103,7 @@ static int pty_open_master (char *pty_na
close (pty_master);
return -1;
}
- strcpy (pty_name, slave_name);
+ g_strlcpy (pty_name, slave_name, pty_name_size);
return pty_master;
}
@@ -1151,36 +1155,45 @@ pty_open_slave (const char *pty_name)
#else /* !HAVE_GRANTPT */
/* BSD version of pty_open_master */
-static int pty_open_master (char *pty_name)
+static int pty_open_master (char *pty_name, size_t pty_name_size)
{
int pty_master;
- const char *ptr1, *ptr2;
+ DIR *dir;
+ struct dirent *ent;
+ const char *p;
- strcpy (pty_name, "/dev/ptyXX");
- for (ptr1 = "pqrstuvwxyzPQRST"; *ptr1; ++ptr1)
- {
- pty_name [8] = *ptr1;
- for (ptr2 = "0123456789abcdef"; *ptr2; ++ptr2)
- {
- pty_name [9] = *ptr2;
+ pty_master = -1;
- /* Try to open master */
- if ((pty_master = open (pty_name, O_RDWR)) == -1) {
- if (errno == ENOENT) /* Different from EIO */
- return -1; /* Out of pty devices */
- else
- continue; /* Try next pty device */
- }
- pty_name [5] = 't'; /* Change "pty" to "tty" */
- if (access (pty_name, 6)){
- close (pty_master);
- pty_name [5] = 'p';
- continue;
- }
- return pty_master;
- }
+ if ((dir = opendir ("/dev")) == NULL)
+ return -1;
+
+ while ((ent = readdir (dir)) != NULL) {
+
+ /* d_name =~ qr"^pty..$" */
+ p = ent->d_name;
+ if (!(*p++ == 'p' && *p++ == 't' && *p++ == 'y' &&
+ *p++ != '\0' && *p++ != '\0' && *p++ == '\0')) {
+ continue;
+ }
+
+ if (g_strlcpy (pty_name, "/dev/", pty_name_size) >= pty_name_size ||
+ g_strlcat (pty_name, ent->d_name, pty_name_size) >= pty_name_size)
+ break; /* pty_name too short */
+
+ /* Try to open master */
+ if ((pty_master = open (pty_name, O_RDWR)) == -1)
+ continue;
+
+ pty_name [5] = 't'; /* Change "/dev/pty" to "/dev/tty" */
+ if (access (pty_name, W_OK | R_OK) == 0)
+ break; /* We've found a terminal */
+
+ close (pty_master);
+ pty_master = -1;
}
- return -1; /* Ran out of pty devices */
+
+ closedir (dir);
+ return pty_master;
}
/* BSD version of pty_open_slave */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]