bin/184597: [PATCH] Fix rfcomm_sppd(1) pseudo slave TTY mode

Tobias Rehbein tobias.rehbein at web.de
Thu Dec 12 18:20:01 UTC 2013


The following reply was made to PR bin/184597; it has been noted by GNATS.

From: Tobias Rehbein <tobias.rehbein at web.de>
To: bug-followup at FreeBSD.org
Cc:  
Subject: Re: bin/184597: [PATCH] Fix rfcomm_sppd(1) pseudo slave TTY mode
Date: Thu, 12 Dec 2013 19:11:40 +0100

 --rwEMma7ioTxnRzrJ
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 Update:
 - Close file descriptors if strdup(3) call fails
 
 --rwEMma7ioTxnRzrJ
 Content-Type: text/x-diff; charset=us-ascii
 Content-Disposition: attachment; filename="rfcomm_sppd-to-pts-openpty.2.diff"
 
 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..c052063 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,70 +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));
 +	if ((*tty = strdup(pty)) == NULL) {
 +		syslog(LOG_ERR, "Could not strdup(). %s", strerror(errno));
  		close(*aslave);
  		close(*amaster);
  		return (-1);
 @@ -496,7 +447,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);
 
 --rwEMma7ioTxnRzrJ--


More information about the freebsd-bugs mailing list