# [PATCH] DIO: Flow control, Modem info, Read waiting

- Thread: https://externals.io/message/5073
- Original archive: https://news-web.php.net/php.internals/5073
- Started by Greg MacLellan on 2003-10-29T16:20:56+00:00
- Messages: 2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #5073 — Greg MacLellan — 2003-10-29T16:20:56+00:00

URL: https://externals.io/message/5073#5073

Added two functions:

dio_modemget(resource fd) - returns the control line status of a serial port
dio_read_waiting(resource fd) - returns the number of bytes waiting in 
the input buffer

(note: i have submitted a patch for dio_modemget before, but since 
current CVS doesn't have it, I'm sending it again)

Modified dio_tcsetattr() so the array accepts two more parameters:

'hwflow' - set to zero to turn hardware flow control (CRTSCTS) off 
(defaults to on)
'swflow' - set to non-zero to turn software flow control (XON/XOFF) on 
(defaults to off)

Note that the defaults maintain the old behaviour. This change to 
dio_tcsetattr() is also attached seperately as dio_tcsetattr.patch.txt, 
but it is also included in dio_changes.patch.txt.

dio_modemget() was written to get the status of a UPS. Flow control 
changes were made to be able to communicate with a serial device that 
required flow control off (and that was a fun problem to track down..). 
dio_read_waiting() was also written to communicate with the serial 
device, as I was having problems using non-blocking, and with blocking 
read() would sometimes wait forever.

fyi, the device is a "weatherduck" 
http://www.itwatchdogs.com/duckdetails.shtml

ttyl, greg
--
Greg MacLellan

---

## #5076 — Alan Knowles — 2003-10-29T16:39:07+00:00

URL: https://externals.io/message/5073#5076 · In reply to: #5073

would it not make sense to implement
a) export the ioctl  defines DIO_TIOCMGET etc.
b) write a generic dio_ioctl($fh,$type,$args) function, with switch/case 
on the $type
that way implementing more features for ioctl would just be a matter of 
adding the define and handling any special args/return values.??

(it would also follow the ioctl documenation a bit better..)

The tcsetattr bit looks OK.

Regards
Alan


Greg MacLellan wrote:

> Added two functions:
>
> dio_modemget(resource fd) - returns the control line status of a 
> serial port
> dio_read_waiting(resource fd) - returns the number of bytes waiting in 
> the input buffer
>
> (note: i have submitted a patch for dio_modemget before, but since 
> current CVS doesn't have it, I'm sending it again)
>
> Modified dio_tcsetattr() so the array accepts two more parameters:
>
> 'hwflow' - set to zero to turn hardware flow control (CRTSCTS) off 
> (defaults to on)
> 'swflow' - set to non-zero to turn software flow control (XON/XOFF) on 
> (defaults to off)
>
> Note that the defaults maintain the old behaviour. This change to 
> dio_tcsetattr() is also attached seperately as 
> dio_tcsetattr.patch.txt, but it is also included in 
> dio_changes.patch.txt.
>
> dio_modemget() was written to get the status of a UPS. Flow control 
> changes were made to be able to communicate with a serial device that 
> required flow control off (and that was a fun problem to track 
> down..). dio_read_waiting() was also written to communicate with the 
> serial device, as I was having problems using non-blocking, and with 
> blocking read() would sometimes wait forever.
>
> fyi, the device is a "weatherduck" 
> http://www.itwatchdogs.com/duckdetails.shtml
>
> ttyl, greg
> -- 
> Greg MacLellan
>
>
>------------------------------------------------------------------------
>
>Index: php-src/ext/dio/dio.c
>===================================================================
>RCS file: /repository/php-src/ext/dio/dio.c,v
>retrieving revision 1.21.2.3
>diff -u -r1.21.2.3 dio.c
>--- php-src/ext/dio/dio.c	7 Mar 2003 13:42:11 -0000	1.21.2.3
>+++ php-src/ext/dio/dio.c	29 Oct 2003 15:57:07 -0000
>@@ -27,6 +27,7 @@
> 
> #include <sys/stat.h>
> #include <sys/types.h>
>+#include <sys/ioctl.h>
> #include <unistd.h>
> #include <fcntl.h>
> #include <termios.h>
>@@ -44,6 +45,8 @@
> 	PHP_FE(dio_write,     NULL)
> 	PHP_FE(dio_close,     NULL)
>         PHP_FE(dio_tcsetattr,     NULL)
>+	PHP_FE(dio_modemget,      NULL)
>+	PHP_FE(dio_read_waiting, NULL)
> 	{NULL, NULL, NULL}
> };
> 
>@@ -54,7 +57,7 @@
> 	dio_functions,
> 	PHP_MINIT(dio),
> 	NULL,
>-	NULL,	
>+	NULL,
> 	NULL,
> 	PHP_MINFO(dio),
> 	"0.1",
>@@ -422,8 +425,8 @@
> 	zval     *arg = NULL;
> 	php_fd_t *f;
> 	struct termios newtio;
>-	int Baud_Rate, Data_Bits=8, Stop_Bits=1, Parity=0;
>-	long BAUD,DATABITS,STOPBITS,PARITYON,PARITY;
>+	int Baud_Rate, Data_Bits=8, Stop_Bits=1, Parity=0, Swflow=0, Hwflow=1;
>+	long BAUD,DATABITS,STOPBITS,PARITYON,PARITY,SWFLOW,HWFLOW;
> 	HashTable      *fh;
> 	zval          **element;
>         
>@@ -464,6 +467,18 @@
> 		Parity = Z_LVAL_PP(element);
> 	} 
> 
>+	if (zend_hash_find(fh, "hwflow", sizeof("hwflow"), (void **) &element) == FAILURE) {
>+		Hwflow = 0;
>+	} else {
>+		Hwflow = Z_LVAL_PP(element);
>+	}
>+
>+	if (zend_hash_find(fh, "swflow", sizeof("swflow"), (void **) &element) == FAILURE) {
>+		Swflow = 0;
>+	} else {
>+		Swflow = Z_LVAL_PP(element);
>+	}
>+
>     /* assign to correct values... */
>     switch (Baud_Rate)  {
> 		case 38400:            
>@@ -561,9 +576,14 @@
> 			zend_error(E_WARNING, "invalid parity %d", Parity);
> 			RETURN_FALSE;
> 	}   
>-        
>-	newtio.c_cflag = BAUD | CRTSCTS | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD;
>-	newtio.c_iflag = IGNPAR;
>+
>+	HWFLOW = (Hwflow == 0) ? 0 : CRTSCTS;
>+
>+	SWFLOW = (Swflow == 0) ? 0 : (IXON | IXOFF | IXANY);
>+	
>+	
>+	newtio.c_cflag = BAUD | HWFLOW | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD;
>+	newtio.c_iflag = IGNPAR | SWFLOW;
> 	newtio.c_oflag = 0;
> 	newtio.c_lflag = 0;       /* ICANON; */
> 	newtio.c_cc[VMIN]=1;
>@@ -592,6 +612,60 @@
> 	zend_list_delete(Z_LVAL_P(r_fd));
> }
> /* }}} */
>+
>+
>+/* {{{ proto array dio_modemget(resource fd)
>+   Get modem bit status for the file descriptor fd */
>+PHP_FUNCTION(dio_modemget)
>+{
>+	zval        *r_fd;
>+	php_fd_t    *f;
>+	int status;
>+
>+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &r_fd) == FAILURE) {
>+		return;
>+	}
>+	ZEND_FETCH_RESOURCE(f, php_fd_t *, &r_fd, -1, le_fd_name, le_fd);
>+
>+	if (ioctl(f->fd, TIOCMGET, &status) == -1) {
>+		php_error(E_WARNING, "%s(): cannot ioctl(TIOCMGET) %d: %s",
>+				  get_active_function_name(TSRMLS_C), f->fd, strerror(errno));
>+		RETURN_FALSE;
>+	}
>+
>+	array_init(return_value);
>+	ADD_FIELD("dsr", (TIOCM_DSR & status) == TIOCM_DSR);
>+	ADD_FIELD("cts", (TIOCM_CTS & status) == TIOCM_CTS);
>+	ADD_FIELD("dcd", (TIOCM_CAR & status) == TIOCM_CAR);
>+	ADD_FIELD("ri",  (TIOCM_RNG & status) == TIOCM_RNG);
>+	ADD_FIELD("rts", (TIOCM_RTS & status) == TIOCM_RTS);
>+	ADD_FIELD("dtr", (TIOCM_DTR & status) == TIOCM_DTR);
>+}
>+/* }}} */
>+
>+
>+/* {{{ proto array dio_read_waiting(resource fd)
>+ *    Get number of bytes waiting to be read from file descriptor fd */
>+PHP_FUNCTION(dio_read_waiting)
>+{
>+	zval        *r_fd;
>+	php_fd_t    *f;
>+	int bytes;
>+
>+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &r_fd) == FAILURE) {
>+		return;
>+	}
>+	ZEND_FETCH_RESOURCE(f, php_fd_t *, &r_fd, -1, le_fd_name, le_fd);
>+	
>+	if (ioctl(f->fd, TIOCINQ, &bytes) != 0) {
>+		php_error(E_WARNING, "%s(): cannot ioctl(TIOCINQ) %d: %s",
>+				  get_active_function_name(TSRMLS_C), f->fd, strerror(errno));
>+		RETURN_FALSE;
>+	}
>+
>+	RETURN_LONG(bytes);
>+}
>+/* }}} */						
> 
> /*
>  * Local variables:
>Index: php-src/ext/dio/php_dio.h
>===================================================================
>RCS file: /repository/php-src/ext/dio/php_dio.h,v
>retrieving revision 1.4.4.1
>diff -u -r1.4.4.1 php_dio.h
>--- php-src/ext/dio/php_dio.h	31 Dec 2002 16:34:25 -0000	1.4.4.1
>+++ php-src/ext/dio/php_dio.h	29 Oct 2003 15:57:07 -0000
>@@ -45,6 +45,8 @@
> PHP_FUNCTION(dio_fcntl);
> PHP_FUNCTION(dio_close);
> PHP_FUNCTION(dio_tcsetattr);
>+PHP_FUNCTION(dio_modemget);
>+PHP_FUNCTION(dio_read_waiting);
> 
> typedef struct {
> 	int fd;
>  
>
>------------------------------------------------------------------------
>
>Index: php-src/ext/dio/dio.c
>===================================================================
>RCS file: /repository/php-src/ext/dio/dio.c,v
>retrieving revision 1.21.2.3
>diff -u -r1.21.2.3 dio.c
>--- php-src/ext/dio/dio.c	7 Mar 2003 13:42:11 -0000	1.21.2.3
>+++ php-src/ext/dio/dio.c	29 Oct 2003 16:06:58 -0000
>@@ -27,6 +27,7 @@
> 
> #include <sys/stat.h>
> #include <sys/types.h>
>+#include <sys/ioctl.h>
> #include <unistd.h>
> #include <fcntl.h>
> #include <termios.h>
>@@ -54,7 +55,7 @@
> 	dio_functions,
> 	PHP_MINIT(dio),
> 	NULL,
>-	NULL,	
>+	NULL,
> 	NULL,
> 	PHP_MINFO(dio),
> 	"0.1",
>@@ -422,8 +423,8 @@
> 	zval     *arg = NULL;
> 	php_fd_t *f;
> 	struct termios newtio;
>-	int Baud_Rate, Data_Bits=8, Stop_Bits=1, Parity=0;
>-	long BAUD,DATABITS,STOPBITS,PARITYON,PARITY;
>+	int Baud_Rate, Data_Bits=8, Stop_Bits=1, Parity=0, Swflow=0, Hwflow=1;
>+	long BAUD,DATABITS,STOPBITS,PARITYON,PARITY,SWFLOW,HWFLOW;
> 	HashTable      *fh;
> 	zval          **element;
>         
>@@ -464,6 +465,18 @@
> 		Parity = Z_LVAL_PP(element);
> 	} 
> 
>+	if (zend_hash_find(fh, "hwflow", sizeof("hwflow"), (void **) &element) == FAILURE) {
>+		Hwflow = 0;
>+	} else {
>+		Hwflow = Z_LVAL_PP(element);
>+	}
>+
>+	if (zend_hash_find(fh, "swflow", sizeof("swflow"), (void **) &element) == FAILURE) {
>+		Swflow = 0;
>+	} else {
>+		Swflow = Z_LVAL_PP(element);
>+	}
>+
>     /* assign to correct values... */
>     switch (Baud_Rate)  {
> 		case 38400:            
>@@ -561,9 +574,14 @@
> 			zend_error(E_WARNING, "invalid parity %d", Parity);
> 			RETURN_FALSE;
> 	}   
>-        
>-	newtio.c_cflag = BAUD | CRTSCTS | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD;
>-	newtio.c_iflag = IGNPAR;
>+
>+	HWFLOW = (Hwflow == 0) ? 0 : CRTSCTS;
>+
>+	SWFLOW = (Swflow == 0) ? 0 : (IXON | IXOFF | IXANY);
>+	
>+	
>+	newtio.c_cflag = BAUD | HWFLOW | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD;
>+	newtio.c_iflag = IGNPAR | SWFLOW;
> 	newtio.c_oflag = 0;
> 	newtio.c_lflag = 0;       /* ICANON; */
> 	newtio.c_cc[VMIN]=1;
>@@ -592,6 +610,8 @@
> 	zend_list_delete(Z_LVAL_P(r_fd));
> }
> /* }}} */
>+
>+
> 
> /*
>  * Local variables:
