Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F175400489
D57322.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D57322.id.diff
View Options
diff --git a/bin/ls/extern.h b/bin/ls/extern.h
--- a/bin/ls/extern.h
+++ b/bin/ls/extern.h
@@ -56,6 +56,16 @@
size_t len_octal(const char *, int);
int prn_octal(const char *);
int prn_printable(const char *);
+
+/*
+ * stdout wrappers that keep dired_pos (the number of bytes written so far)
+ * up to date. They are used instead of ftell(3) because ftell(3) fails on
+ * non-seekable outputs such as pipes.
+ */
+int dired_putchar(int);
+int dired_puts(const char *);
+int dired_fputs(const char *);
+int dired_printf(const char *, ...) __printflike(1, 2);
#ifdef COLORLS
void parsecolors(const char *cs);
void colorquit(int);
diff --git a/bin/ls/ls.h b/bin/ls/ls.h
--- a/bin/ls/ls.h
+++ b/bin/ls/ls.h
@@ -62,6 +62,8 @@
#ifdef COLORLS
extern int f_color; /* add type in color for non-regular files */
#endif
+extern int f_dired; /* dired mode */
+extern off_t dired_pos; /* number of bytes written to stdout so far */
typedef struct {
FTSENT *list;
diff --git a/bin/ls/ls.c b/bin/ls/ls.c
--- a/bin/ls/ls.c
+++ b/bin/ls/ls.c
@@ -96,7 +96,8 @@
enum {
BIN_OPT = CHAR_MAX,
COLOR_OPT,
- GROUP_OPT
+ GROUP_OPT,
+ DIRED_OPT,
};
static const struct option long_opts[] =
@@ -104,6 +105,7 @@
{"color", optional_argument, NULL, COLOR_OPT},
{"group-directories", optional_argument, NULL, GROUP_OPT},
{"group-directories-first", no_argument, NULL, GROUP_OPT},
+ {"dired", no_argument, NULL, DIRED_OPT},
{NULL, no_argument, NULL, 0}
};
@@ -162,6 +164,7 @@
char *enter_bold; /* ANSI sequence to set color to bold mode */
char *enter_underline; /* ANSI sequence to enter underline mode */
#endif
+int f_dired;
static int rval;
@@ -486,6 +489,13 @@
#else
warnx("color support not compiled in");
#endif
+ break;
+ case DIRED_OPT:
+ f_longform = 1;
+ f_singlecol = 0;
+ f_stream = 0;
+ f_dired = 1;
+ break;
default:
case '?':
usage();
@@ -698,12 +708,12 @@
* directory with its name.
*/
if (output) {
- putchar('\n');
+ dired_putchar('\n');
(void)printname(p->fts_path);
- puts(":");
+ dired_puts(":");
} else if (argc > 1) {
(void)printname(p->fts_path);
- puts(":");
+ dired_puts(":");
output = 1;
}
chp = fts_children(ftsp, ch_options);
diff --git a/bin/ls/print.c b/bin/ls/print.c
--- a/bin/ls/print.c
+++ b/bin/ls/print.c
@@ -36,12 +36,14 @@
#include <sys/stat.h>
#include <sys/acl.h>
+#include <assert.h>
#include <err.h>
#include <errno.h>
#include <fts.h>
#include <langinfo.h>
#include <libutil.h>
#include <limits.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
@@ -106,6 +108,61 @@
static size_t padding_for_month[12];
static size_t month_max_size = 0;
+off_t dired_pos;
+
+/*
+ * The following helpers wrap the stdio output routines and accumulate the
+ * number of bytes written to stdout in dired_pos. dired mode needs the byte
+ * offset of every file name in the output, and ftell(3) cannot provide it
+ * because it fails on non-seekable outputs such as pipes.
+ */
+int
+dired_putchar(int c)
+{
+ int ret;
+
+ ret = putchar(c);
+ if (ret != EOF)
+ dired_pos++;
+ return (ret);
+}
+
+int
+dired_puts(const char *s)
+{
+ int ret;
+
+ ret = puts(s);
+ if (ret != EOF)
+ dired_pos += strlen(s) + 1; /* puts() appends a newline */
+ return (ret);
+}
+
+int
+dired_fputs(const char *s)
+{
+ int ret;
+
+ ret = fputs(s, stdout);
+ if (ret != EOF)
+ dired_pos += strlen(s);
+ return (ret);
+}
+
+int
+dired_printf(const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, fmt);
+ ret = vprintf(fmt, ap);
+ va_end(ap);
+ if (ret > 0)
+ dired_pos += ret;
+ return (ret);
+}
+
void
printscol(const DISPLAY *dp)
{
@@ -204,6 +261,8 @@
FTSENT *p;
NAMES *np;
char buf[20];
+ off_t *offsets;
+ int offsets_idx = 0;
#ifdef COLORLS
int color_printed = 0;
#endif
@@ -211,37 +270,44 @@
if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) &&
(f_longform || f_size)) {
if (!f_humanval)
- (void)printf("total %lu\n", howmany(dp->btotal, blocksize));
+ (void)dired_printf("total %lu\n",
+ howmany(dp->btotal, blocksize));
else {
(void)humanize_number(buf, 7 /* "1024 KB" */,
dp->btotal * 512, "B", HN_AUTOSCALE, HN_DECIMAL);
- (void)printf("total %s\n", buf);
+ (void)dired_printf("total %s\n", buf);
}
}
+ if (f_dired) {
+ offsets = calloc(dp->entries * 2, sizeof(*offsets));
+ if (offsets == NULL && dp->entries != 0)
+ err(1, NULL);
+ }
+
for (p = dp->list; p; p = p->fts_link) {
if (IS_NOPRINT(p))
continue;
sp = p->fts_statp;
if (f_inode)
- (void)printf("%*ju ",
+ (void)dired_printf("%*ju ",
dp->s_inode, (uintmax_t)sp->st_ino);
if (f_size)
- (void)printf(f_thousands ? "%'*jd " : "%*jd ",
+ (void)dired_printf(f_thousands ? "%'*jd " : "%*jd ",
dp->s_block, howmany(sp->st_blocks, blocksize));
strmode(sp->st_mode, buf);
aclmode(buf, p);
np = p->fts_pointer;
- (void)printf("%s %*ju ", buf, dp->s_nlink,
+ (void)dired_printf("%s %*ju ", buf, dp->s_nlink,
(uintmax_t)sp->st_nlink);
if (!f_sowner)
- (void)printf("%-*s ", dp->s_user, np->user);
- (void)printf("%-*s ", dp->s_group, np->group);
+ (void)dired_printf("%-*s ", dp->s_user, np->user);
+ (void)dired_printf("%-*s ", dp->s_group, np->group);
if (f_flags)
- (void)printf("%-*s ", dp->s_flags, np->flags);
+ (void)dired_printf("%-*s ", dp->s_flags, np->flags);
if (f_label)
- (void)printf("%-*s ", dp->s_label, np->label);
+ (void)dired_printf("%-*s ", dp->s_label, np->label);
if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
printdev(dp->s_size, sp->st_rdev);
else
@@ -258,7 +324,11 @@
if (f_color)
color_printed = colortype(sp->st_mode);
#endif
+ if (f_dired)
+ offsets[offsets_idx++] = dired_pos;
(void)printname(p->fts_name);
+ if (f_dired)
+ offsets[offsets_idx++] = dired_pos;
#ifdef COLORLS
if (f_color && color_printed)
endcolor(0);
@@ -267,7 +337,18 @@
(void)printtype(sp->st_mode);
if (S_ISLNK(sp->st_mode))
printlink(p);
- (void)putchar('\n');
+ (void)dired_putchar('\n');
+ }
+
+ if (f_dired) {
+ assert(offsets_idx == dp->entries * 2);
+ (void)dired_fputs("//DIRED//");
+ for (offsets_idx = 0; offsets_idx < dp->entries * 2;
+ offsets_idx++)
+ (void)dired_printf(" %jd",
+ (intmax_t)offsets[offsets_idx]);
+ (void)dired_putchar('\n');
+ free(offsets);
}
}
@@ -430,7 +511,7 @@
printdev(size_t width, dev_t dev)
{
- (void)printf("%#*jx ", (u_int)width, (uintmax_t)dev);
+ (void)dired_printf("%#*jx ", (u_int)width, (uintmax_t)dev);
}
static void
@@ -485,8 +566,8 @@
/* mmm dd yyyy || dd mmm yyyy */
format = d_first ? "%e %b %Y" : "%b %e %Y";
ls_strftime(longstring, sizeof(longstring), format, localtime(&ftime));
- fputs(longstring, stdout);
- fputc(' ', stdout);
+ dired_fputs(longstring);
+ dired_putchar(' ');
}
static int
@@ -495,7 +576,7 @@
if (f_slash) {
if ((mode & S_IFMT) == S_IFDIR) {
- (void)putchar('/');
+ (void)dired_putchar('/');
return (1);
}
return (0);
@@ -503,25 +584,25 @@
switch (mode & S_IFMT) {
case S_IFDIR:
- (void)putchar('/');
+ (void)dired_putchar('/');
return (1);
case S_IFIFO:
- (void)putchar('|');
+ (void)dired_putchar('|');
return (1);
case S_IFLNK:
- (void)putchar('@');
+ (void)dired_putchar('@');
return (1);
case S_IFSOCK:
- (void)putchar('=');
+ (void)dired_putchar('=');
return (1);
case S_IFWHT:
- (void)putchar('%');
+ (void)dired_putchar('%');
return (1);
default:
break;
}
if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
- (void)putchar('*');
+ (void)dired_putchar('*');
return (1);
}
return (0);
@@ -531,7 +612,7 @@
static int
putch(int c)
{
- (void)putchar(c);
+ (void)dired_putchar(c);
return 0;
}
@@ -570,17 +651,17 @@
printcolor_ansi(Colors c)
{
- printf("\033[");
+ dired_printf("\033[");
if (colors[c].bold)
- printf("1");
+ dired_printf("1");
if (colors[c].underline)
- printf(";4");
+ dired_printf(";4");
if (colors[c].num[0] != -1)
- printf(";3%d", colors[c].num[0]);
+ dired_printf(";3%d", colors[c].num[0]);
if (colors[c].num[1] != -1)
- printf(";4%d", colors[c].num[1]);
- printf("m");
+ dired_printf(";4%d", colors[c].num[1]);
+ dired_printf("m");
}
static void
@@ -605,7 +686,7 @@
endcolor_ansi(void)
{
- printf("\33[m");
+ dired_printf("\33[m");
}
static void
@@ -742,7 +823,7 @@
return;
}
path[lnklen] = '\0';
- (void)printf(" -> ");
+ (void)dired_printf(" -> ");
(void)printname(path);
}
@@ -759,9 +840,9 @@
humanize_number(buf, sizeof(buf), (int64_t)bytes, "",
HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
- (void)printf("%*s ", (u_int)width, buf);
+ (void)dired_printf("%*s ", (u_int)width, buf);
} else {
- (void)printf(f_thousands ? "%'*jd " : "%*jd ",
+ (void)dired_printf(f_thousands ? "%'*jd " : "%*jd ",
(u_int)width, bytes);
}
}
diff --git a/bin/ls/util.c b/bin/ls/util.c
--- a/bin/ls/util.c
+++ b/bin/ls/util.c
@@ -60,18 +60,18 @@
n = 0;
while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
if (clen == (size_t)-2) {
- n += printf("%s", s);
+ n += dired_printf("%s", s);
break;
}
if (clen == (size_t)-1) {
memset(&mbs, 0, sizeof(mbs));
- putchar((unsigned char)*s);
+ dired_putchar((unsigned char)*s);
s++;
n++;
continue;
}
for (i = 0; i < (int)clen; i++)
- putchar((unsigned char)s[i]);
+ dired_putchar((unsigned char)s[i]);
s += clen;
if (iswprint(wc))
n += wcwidth(wc);
@@ -91,25 +91,25 @@
n = 0;
while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
if (clen == (size_t)-1) {
- putchar('?');
+ dired_putchar('?');
s++;
n++;
memset(&mbs, 0, sizeof(mbs));
continue;
}
if (clen == (size_t)-2) {
- putchar('?');
+ dired_putchar('?');
n++;
break;
}
if (!iswprint(wc)) {
- putchar('?');
+ dired_putchar('?');
s += clen;
n++;
continue;
}
for (i = 0; i < (int)clen; i++)
- putchar((unsigned char)s[i]);
+ dired_putchar((unsigned char)s[i]);
s += clen;
n += wcwidth(wc);
}
@@ -176,7 +176,7 @@
goodchar = clen != (size_t)-1 && clen != (size_t)-2;
if (goodchar && iswprint(wc) && wc != L'\"' && wc != L'\\') {
for (i = 0; i < (int)clen; i++)
- putchar((unsigned char)s[i]);
+ dired_putchar((unsigned char)s[i]);
len += wcwidth(wc);
} else if (goodchar && f_octal_escape &&
#if WCHAR_MIN < 0
@@ -184,8 +184,8 @@
#endif
wc <= (wchar_t)UCHAR_MAX &&
(p = strchr(esc, (char)wc)) != NULL) {
- putchar('\\');
- putchar(p[1]);
+ dired_putchar('\\');
+ dired_putchar(p[1]);
len += 2;
} else {
if (goodchar)
@@ -196,10 +196,10 @@
prtlen = strlen(s);
for (i = 0; i < prtlen; i++) {
ch = (unsigned char)s[i];
- putchar('\\');
- putchar('0' + (ch >> 6));
- putchar('0' + ((ch >> 3) & 7));
- putchar('0' + (ch & 7));
+ dired_putchar('\\');
+ dired_putchar('0' + (ch >> 6));
+ dired_putchar('0' + ((ch >> 3) & 7));
+ dired_putchar('0' + (ch & 7));
len += 4;
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Oct 11, 2:27 PM (4 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40609065
Default Alt Text
D57322.id.diff (10 KB)
Attached To
Mode
D57322: ls: Support dired mode
Attached
Detach File
Event Timeline
Log In to Comment