bin/165429: [patch] wall(1): add multibyte character support
Dmitry Marakasov
amdmi3 at FreeBSD.org
Thu Feb 23 21:20:12 UTC 2012
>Number: 165429
>Category: bin
>Synopsis: [patch] wall(1): add multibyte character support
>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: Thu Feb 23 21:20:11 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator: Dmitry Marakasov
>Release: FreeBSD 9.0-RELEASE amd64
>Organization:
>Environment:
System: FreeBSD hades.panopticon 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Tue Jan 10 01:33:18 MSK 2012 root at hades.panopticon:/usr/obj/usr/src/sys/HADES amd64
>Description:
wall(1) doesn't support multibyte characters. Fix it in a similar way to write(1) (see bin/164317 or SVN rev 231586).
>How-To-Repeat:
>Fix:
--- wall.patch begins here ---
diff --git usr.bin/wall/wall.1 usr.bin/wall/wall.1
index 1c2d067..4fa82dd 100644
--- usr.bin/wall/wall.1
+++ usr.bin/wall/wall.1
@@ -28,7 +28,7 @@
.\" @(#)wall.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$
.\"
-.Dd July 17, 2004
+.Dd February 24, 2012
.Dt WALL 1
.Os
.Sh NAME
@@ -73,7 +73,3 @@ setting is used to determine which characters are safe to write to a
terminal, not the receiver's (which
.Nm
has no way of knowing).
-.Pp
-The
-.Nm
-utility does not recognize multibyte characters.
diff --git usr.bin/wall/wall.c usr.bin/wall/wall.c
index c3aa323..dafd448 100644
--- usr.bin/wall/wall.c
+++ usr.bin/wall/wall.c
@@ -62,6 +62,8 @@ static const char sccsid[] = "@(#)wall.c 8.2 (Berkeley) 11/16/93";
#include <time.h>
#include <unistd.h>
#include <utmpx.h>
+#include <wchar.h>
+#include <wctype.h>
#include "ttymsg.h"
@@ -185,14 +187,15 @@ void
makemsg(char *fname)
{
int cnt;
- unsigned char ch;
+ wchar_t ch;
struct tm *lt;
struct passwd *pw;
struct stat sbuf;
time_t now;
FILE *fp;
int fd;
- char *p, hostname[MAXHOSTNAMELEN], lbuf[256], tmpname[64];
+ char hostname[MAXHOSTNAMELEN], tmpname[64];
+ wchar_t *p, *tmp, lbuf[256], codebuf[13];
const char *tty;
const char *whom;
gid_t egid;
@@ -220,78 +223,61 @@ makemsg(char *fname)
* Which means that we may leave a non-blank character
* in column 80, but that can't be helped.
*/
- (void)fprintf(fp, "\r%79s\r\n", " ");
- (void)snprintf(lbuf, sizeof(lbuf),
- "Broadcast Message from %s@%s",
+ (void)fwprintf(fp, L"\r%79s\r\n", " ");
+ (void)swprintf(lbuf, sizeof(lbuf)/sizeof(wchar_t),
+ L"Broadcast Message from %s@%s",
whom, hostname);
- (void)fprintf(fp, "%-79.79s\007\007\r\n", lbuf);
- (void)snprintf(lbuf, sizeof(lbuf),
- " (%s) at %d:%02d %s...", tty,
+ (void)fwprintf(fp, L"%-79.79S\007\007\r\n", lbuf);
+ (void)swprintf(lbuf, sizeof(lbuf)/sizeof(wchar_t),
+ L" (%s) at %d:%02d %s...", tty,
lt->tm_hour, lt->tm_min, lt->tm_zone);
- (void)fprintf(fp, "%-79.79s\r\n", lbuf);
+ (void)fwprintf(fp, L"%-79.79S\r\n", lbuf);
}
- (void)fprintf(fp, "%79s\r\n", " ");
+ (void)fwprintf(fp, L"%79s\r\n", " ");
if (fname) {
egid = getegid();
setegid(getgid());
- if (freopen(fname, "r", stdin) == NULL)
+ if (freopen(fname, "r", stdin) == NULL)
err(1, "can't read %s", fname);
setegid(egid);
}
cnt = 0;
- while (fgets(lbuf, sizeof(lbuf), stdin)) {
- for (p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) {
- if (ch == '\r') {
- putc('\r', fp);
+ while (fgetws(lbuf, sizeof(lbuf)/sizeof(wchar_t), stdin)) {
+ for (p = lbuf; (ch = *p) != L'\0'; ++p, ++cnt) {
+ if (ch == L'\r') {
+ putwc(L'\r', fp);
cnt = 0;
continue;
- } else if (ch == '\n') {
+ } else if (ch == L'\n') {
for (; cnt < 79; ++cnt)
- putc(' ', fp);
- putc('\r', fp);
- putc('\n', fp);
+ putwc(L' ', fp);
+ putwc(L'\r', fp);
+ putwc(L'\n', fp);
break;
}
if (cnt == 79) {
- putc('\r', fp);
- putc('\n', fp);
+ putwc(L'\r', fp);
+ putwc(L'\n', fp);
cnt = 0;
}
- if (((ch & 0x80) && ch < 0xA0) ||
- /* disable upper controls */
- (!isprint(ch) && !isspace(ch) &&
- ch != '\a' && ch != '\b')
- ) {
- if (ch & 0x80) {
- ch &= 0x7F;
- putc('M', fp);
+ if (iswprint(ch) || iswspace(ch) || ch == L'\a' || ch == L'\b') {
+ putwc(ch, fp);
+ } else {
+ (void)swprintf(codebuf, sizeof(codebuf)/sizeof(wchar_t), L"<0x%X>", ch);
+ for (tmp = codebuf; *tmp != L'\0'; ++tmp) {
+ putwc(*tmp, fp);
if (++cnt == 79) {
- putc('\r', fp);
- putc('\n', fp);
- cnt = 0;
- }
- putc('-', fp);
- if (++cnt == 79) {
- putc('\r', fp);
- putc('\n', fp);
- cnt = 0;
- }
- }
- if (iscntrl(ch)) {
- ch ^= 040;
- putc('^', fp);
- if (++cnt == 79) {
- putc('\r', fp);
- putc('\n', fp);
+ putwc(L'\r', fp);
+ putwc(L'\n', fp);
cnt = 0;
}
}
+ --cnt;
}
- putc(ch, fp);
}
}
- (void)fprintf(fp, "%79s\r\n", " ");
+ (void)fwprintf(fp, L"%79s\r\n", " ");
rewind(fp);
if (fstat(fd, &sbuf))
--- wall.patch ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list