Date: Sun, 8 Dec 2013 17:11:24 +0100 (CET) From: Tobias Rehbein <tobias.rehbein@web.de> To: FreeBSD-gnats-submit@freebsd.org Cc: m_evmenkin@yahoo.com Subject: bin/184597: [PATCH] Fix rfcomm_sppd pseudo slave TTY mode Message-ID: <201312081611.rB8GBOsb002312@oshi.local> Resent-Message-ID: <201312081620.rB8GK1A0073173@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 184597 >Category: bin >Synopsis: [PATCH] Fix rfcomm_sppd pseudo slave TTY mode >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Sun Dec 08 16:20:01 UTC 2013 >Closed-Date: >Last-Modified: >Originator: Tobias Rehbein >Release: FreeBSD 10.0-BETA4 amd64 >Organization: >Environment: System: FreeBSD oshi.local 10.0-BETA4 FreeBSD 10.0-BETA4 #0: Tue Dec 3 19:39:08 CET 2013 tobi@oshi.local:/usr/obj/usr/src/sys/GENERIC amd64 >Description: rfcomm_sppd uses the deprecated pty(4) driver to implement its pseudo slave TTY mode (invoked by the '-t tty' option). This breaks on recent FreeBSD systems. In order to fix this I changed the code to use the openpty(3) API which uses the pts(4) driver instead of the pty(4) driver. The patch works fine for me, but there is one regression in functionality: The old code allowed the user to select the name of the pseudo terminal. This no longer works using the pts(4) driver, the name is always automatically selected by the pts(4) driver. But maybe I missed something here. >How-To-Repeat: >Fix: --- rfcomm_sppd-to-pts-openpty.diff begins here --- diff --git a/usr.bin/bluetooth/rfcomm_sppd/Makefile b/usr.bin/bluetooth/rfcomm_sppd/Makefile index 9018f6e..0da7498 100644 --- a/usr.bin/bluetooth/rfcomm_sppd/Makefile +++ b/usr.bin/bluetooth/rfcomm_sppd/Makefile @@ -6,6 +6,6 @@ SRCS= rfcomm_sppd.c rfcomm_sdp.c WARNS?= 2 DPADD= ${LIBBLUETOOTH} ${LIBSDP} -LDADD= -lbluetooth -lsdp +LDADD= -lbluetooth -lsdp -lutil .include <bsd.prog.mk> diff --git a/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.1 b/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.1 index 92c7d45..38a8153 100644 --- a/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.1 +++ b/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.1 @@ -33,10 +33,9 @@ .Nd RFCOMM Serial Port Profile daemon .Sh SYNOPSIS .Nm -.Op Fl bhS +.Op Fl bhtS .Fl a Ar address .Fl c Ar channel -.Op Fl t Ar tty .Sh DESCRIPTION The .Nm @@ -53,7 +52,7 @@ Once connection is established, the .Nm utility provides access to the server's remote serial port via stdin/stdout or via -.Xr pty 4 +.Xr pts 4 interface if .Fl t option was specified. @@ -72,8 +71,7 @@ daemon. If .Fl t options was specified, -the server side of the virtual serial port is attached to the pseudo-terminal -.Ar tty . +the server side of the virtual serial port is attached to a pseudo-terminal. Otherwise the virtual serial port is attached to the stdin/stdout. .Nm should be run as root in order to communicate with @@ -146,24 +144,22 @@ Display usage message and exit. .It Fl S Server mode; see .Sx DESCRIPTION . -.It Fl t Ar tty -Slave pseudo tty name. +.It Fl t +Use slave pseudo tty. If not set stdin/stdout will be used. This option is required if .Fl b option was specified. .El .Sh FILES -.Bl -tag -width ".Pa /dev/tty[p-sP-S][0-9a-v]" -compact -.It Pa /dev/pty[p-sP-S][0-9a-v] -master pseudo terminals -.It Pa /dev/tty[p-sP-S][0-9a-v] +.Bl -tag -width ".Pa /dev/pts/[num]" -compact +.It Pa /dev/pts/[num] slave pseudo terminals .El .Sh EXIT STATUS .Ex -std .Sh EXAMPLES -.Dl "rfcomm_sppd -a 00:01:02:03:04:05 -c 1 -t /dev/ttyp1" +.Dl "rfcomm_sppd -a 00:01:02:03:04:05 -c 1 -t" .Pp Will start the .Nm @@ -171,13 +167,17 @@ utility and open RFCOMM connection to the server at .Li 00:01:02:03:04:05 and channel .Li 1 . -Once the connection has been established, -.Pa /dev/ttyp1 +Once the connection has been established, a +.Xr pts 4 can be used to talk to the remote serial port on the server. +.Nm +prints the name of the +.Xr pts 4 +to use. .Sh SEE ALSO .Xr bluetooth 3 , .Xr ng_btsocket 4 , -.Xr pty 4 , +.Xr pts 4 , .Xr rfcomm_pppd 8 , .Xr sdpd 8 .Sh AUTHORS diff --git a/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.c b/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.c index 4e0d04b..5e426f5 100644 --- a/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.c +++ b/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.c @@ -32,6 +32,7 @@ */ #include <sys/stat.h> +#include <sys/types.h> #include <bluetooth.h> #include <ctype.h> #include <err.h> @@ -49,6 +50,7 @@ #include <syslog.h> #include <termios.h> #include <unistd.h> +#include <libutil.h> #define SPPD_IDENT "rfcomm_sppd" #define SPPD_BUFFER_SIZE 1024 @@ -58,7 +60,7 @@ int rfcomm_channel_lookup (bdaddr_t const *local, bdaddr_t const *remote, int service, int *channel, int *error); -static int sppd_ttys_open (char const *tty, int *amaster, int *aslave); +static int sppd_ttys_open (char **tty, int *amaster, int *aslave); static int sppd_read (int fd, char *buffer, int size); static int sppd_write (int fd, char *buffer, int size); static void sppd_sighandler (int s); @@ -74,7 +76,8 @@ main(int argc, char *argv[]) struct sockaddr_rfcomm ra; bdaddr_t addr; int n, background, channel, service, - s, amaster, aslave, fd, doserver; + s, amaster, aslave, fd, doserver, + dopty; fd_set rfd; char *tty = NULL, *ep = NULL, buf[SPPD_BUFFER_SIZE]; @@ -82,9 +85,10 @@ main(int argc, char *argv[]) background = channel = 0; service = SDP_SERVICE_CLASS_SERIAL_PORT; doserver = 0; + dopty = 0; /* Parse command line options */ - while ((n = getopt(argc, argv, "a:bc:t:hS")) != -1) { + while ((n = getopt(argc, argv, "a:bc:thS")) != -1) { switch (n) { case 'a': /* BDADDR */ if (!bt_aton(optarg, &addr)) { @@ -130,11 +134,8 @@ main(int argc, char *argv[]) background = 1; break; - case 't': /* Slave TTY name */ - if (optarg[0] != '/') - asprintf(&tty, "%s%s", _PATH_DEV, optarg); - else - tty = optarg; + case 't': /* Open pseudo TTY */ + dopty = 1; break; case 'S': @@ -173,18 +174,18 @@ main(int argc, char *argv[]) err(1, "Could not sigaction(SIGCHLD)"); /* Open TTYs */ - if (tty == NULL) { + if (dopty) { + if (sppd_ttys_open(&tty, &amaster, &aslave) < 0) + exit(1); + + fd = amaster; + } else { if (background) usage(); amaster = STDIN_FILENO; fd = STDOUT_FILENO; - } else { - if (sppd_ttys_open(tty, &amaster, &aslave) < 0) - exit(1); - - fd = amaster; - } + } /* Open RFCOMM connection */ @@ -359,72 +360,20 @@ main(int argc, char *argv[]) /* Open TTYs */ static int -sppd_ttys_open(char const *tty, int *amaster, int *aslave) +sppd_ttys_open(char **tty, int *amaster, int *aslave) { - char pty[PATH_MAX], *slash; - struct group *gr = NULL; - gid_t ttygid; + char pty[PATH_MAX]; struct termios tio; - /* - * Construct master PTY name. The slave tty name must be less then - * PATH_MAX characters in length, must contain '/' character and - * must not end with '/'. - */ - - if (strlen(tty) >= sizeof(pty)) { - syslog(LOG_ERR, "Slave tty name is too long"); - return (-1); - } - - strlcpy(pty, tty, sizeof(pty)); - slash = strrchr(pty, '/'); - if (slash == NULL || slash[1] == '\0') { - syslog(LOG_ERR, "Invalid slave tty name (%s)", tty); - return (-1); - } - - slash[1] = 'p'; - - if (strcmp(pty, tty) == 0) { - syslog(LOG_ERR, "Master and slave tty are the same (%s)", tty); - return (-1); - } - - if ((*amaster = open(pty, O_RDWR, 0)) < 0) { - syslog(LOG_ERR, "Could not open(%s). %s", pty, strerror(errno)); - return (-1); - } - - /* - * Slave TTY - */ - - if ((gr = getgrnam("tty")) != NULL) - ttygid = gr->gr_gid; - else - ttygid = -1; - - (void) chown(tty, getuid(), ttygid); - (void) chmod(tty, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP); - (void) revoke(tty); + cfmakeraw(&tio); - if ((*aslave = open(tty, O_RDWR, 0)) < 0) { - syslog(LOG_ERR, "Could not open(%s). %s", tty, strerror(errno)); - close(*amaster); + if (openpty(amaster, aslave, pty, &tio, NULL) == -1) { + syslog(LOG_ERR, "Could not openpty(). %s", strerror(errno)); return (-1); } - /* - * Make slave TTY raw - */ - - cfmakeraw(&tio); - - if (tcsetattr(*aslave, TCSANOW, &tio) < 0) { - syslog(LOG_ERR, "Could not tcsetattr(). %s", strerror(errno)); - close(*aslave); - close(*amaster); + if ((*tty = strdup(pty)) == NULL) { + syslog(LOG_ERR, "Could not strdup(). %s", strerror(errno)); return (-1); } @@ -496,7 +445,7 @@ usage(void) "\t-a address Peer address (required in client mode)\n" \ "\t-b Run in background\n" \ "\t-c channel RFCOMM channel to connect to or listen on\n" \ -"\t-t tty TTY name (required in background mode)\n" \ +"\t-t use slave pseudo tty (required in background mode)\n" \ "\t-S Server mode\n" \ "\t-h Display this message\n", SPPD_IDENT); exit(255); --- rfcomm_sppd-to-pts-openpty.diff ends here --- >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201312081611.rB8GBOsb002312>