shithub: riscv

Download patch

ref: e981a260006105385c4870ccb739db2bef33affd
parent: 5ea80693baf1b870e36973e1d2f3fd474f2462b7
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Jan 2 15:09:50 EST 2025

libc: provide netmkaddrbuf() function avoiding the static buffer

We need a reentrant version for netmkaddr() that
can be used in multithreaded programs.

--- a/sys/include/libc.h
+++ b/sys/include/libc.h
@@ -543,6 +543,7 @@
 extern	int	hangup(int);
 extern	int	listen(char*, char*);
 extern	char*	netmkaddr(char*, char*, char*);
+extern	char*	netmkaddrbuf(char*, char*, char*, char*, int);
 extern	int	reject(int, char*, char*);
 
 /*
--- a/sys/man/2/dial
+++ b/sys/man/2/dial
@@ -1,6 +1,6 @@
 .TH DIAL 2
 .SH NAME
-dial, hangup, announce, listen, accept, reject, netmkaddr, setnetmtpt, getnetconninfo, freenetconninfo \- make and break network connections
+dial, hangup, announce, listen, accept, reject, netmkaddr, netmkaddrbuf, setnetmtpt, getnetconninfo, freenetconninfo \- make and break network connections
 .SH SYNOPSIS
 .B #include <u.h>
 .br
@@ -25,9 +25,14 @@
 int   reject(int ctl, char *dir, char *cause)
 .PP
 .B
-char* netmkaddr(char *addr, char *defnet, char *defservice)
+char* netmkaddr(char *addr, char *defnet, char *defsrv)
 .PP
 .B
+char* netmkaddrbuf(char *addr, char *defnet, char *defsrv,
+.br
+	char *buf, int len)
+.PP
+.B
 void  setnetmtpt(char *to, int tolen, char *from)
 .PP
 .B
@@ -171,10 +176,19 @@
 .BR ORDWR .
 .PP
 .I Netmkaddr
-makes an address suitable for dialing or announcing.
-It takes an address along with a default network and service to use
+and
+.I netmkaddrbuf
+make an address suitable for dialing or announcing.
+They take an address along with a default network and service to use
 if they are not specified in the address.
-It returns a pointer to static data holding the actual address to use.
+.I Netmkaddrbuf
+stores the resulting dialstring in
+.I buf
+up to a maximum length of
+.I len
+and returns a pointer to it.
+.I Netmkaddr
+returns a pointer to a static buffer.
 .PP
 .I Getnetconninfo
 returns a structure containing information about a
--- a/sys/src/libc/port/netmkaddr.c
+++ b/sys/src/libc/port/netmkaddr.c
@@ -6,47 +6,48 @@
  *  make an address, add the defaults
  */
 char *
-netmkaddr(char *linear, char *defnet, char *defsrv)
+netmkaddrbuf(char *addr, char *defnet, char *defsrv, char *buf, int len)
 {
-	static char addr[256];
 	char *cp;
 
-	/*
-	 *  dump network name
-	 */
-	cp = strchr(linear, '!');
-	if(cp == 0){
-		if(defnet==0){
-			if(defsrv)
-				snprint(addr, sizeof(addr), "net!%s!%s",
-					linear, defsrv);
+	cp = strchr(addr, '!');
+	if(cp == nil){
+		/*
+		 *  dump network name
+		 */
+		if(defnet == nil){
+			if(defsrv != nil)
+				snprint(buf, len, "net!%s!%s", addr, defsrv);
 			else
-				snprint(addr, sizeof(addr), "net!%s", linear);
+				snprint(buf, len, "net!%s", addr);
 		}
 		else {
-			if(defsrv)
-				snprint(addr, sizeof(addr), "%s!%s!%s", defnet,
-					linear, defsrv);
+			if(defsrv != nil)
+				snprint(buf, len, "%s!%s!%s", defnet, addr, defsrv);
 			else
-				snprint(addr, sizeof(addr), "%s!%s", defnet,
-					linear);
+				snprint(buf, len, "%s!%s", defnet, addr);
 		}
-		return addr;
+	} else {
+		cp = strchr(cp+1, '!');
+		if(cp != nil || defsrv == nil){
+			/*
+			 *  if there is already a service or no defsrv given
+			 */
+			snprint(buf, len, "%s", addr);
+		} else {
+			/*
+			 *  add default service
+			 */
+			snprint(buf, len,"%s!%s", addr, defsrv);
+		}
 	}
+	return buf;
+}
 
-	/*
-	 *  if there is already a service, use it
-	 */
-	cp = strchr(cp+1, '!');
-	if(cp)
-		return linear;
+char *
+netmkaddr(char *addr, char *defnet, char *defsrv)
+{
+	static char buf[256];
 
-	/*
-	 *  add default service
-	 */
-	if(defsrv == 0)
-		return linear;
-	snprint(addr, sizeof(addr), "%s!%s", linear, defsrv);
-
-	return addr;
+	return netmkaddrbuf(addr, defnet, defsrv, buf, sizeof(buf));
 }
--