4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-22 00:38:06 +08:00

Cygwin: /proc/<PID>/mount*: escape strings.

In order for these formats to be machine-parseable, characters used as
delimiters must be escaped.  Linux escapes space, tab, newline,
backslash, and hash (because code that parses mounts/mtab and fstab
would handle comments) using octal escapes.  Replicate that behavior
here.

Addresses: https://cygwin.com/pipermail/cygwin/2024-June/256082.html
Signed-off-by: Jeremy Drake <cygwin@jdrake.com>
This commit is contained in:
Jeremy Drake via Cygwin-patches 2024-06-04 19:04:22 -07:00 committed by Corinna Vinschen
parent 5a706ff0fc
commit 0d113da235

View File

@ -1337,9 +1337,39 @@ extern "C" {
struct mntent *getmntent (FILE *); struct mntent *getmntent (FILE *);
}; };
static size_t
escape_string_length (const char *str, const char *escapees)
{
size_t i, len = 0;
for (i = strcspn (str, escapees);
str[i];
i += strcspn (str + i + 1, escapees) + 1)
len += 3;
return len + i;
}
static size_t
escape_string (char *destbuf, const char *str, const char *escapees)
{
size_t s, i;
char *p = destbuf;
for (s = 0, i = strcspn (str, escapees);
str[i];
s = i + 1, i += strcspn (str + s, escapees) + 1)
{
p = stpncpy (p, str + s, i - s);
p += __small_sprintf (p, "\\%03o", (int)(unsigned char) str[i]);
}
p = stpcpy (p, str + s);
return (p - destbuf);
}
static off_t static off_t
format_process_mountstuff (void *data, char *&destbuf, bool mountinfo) format_process_mountstuff (void *data, char *&destbuf, bool mountinfo)
{ {
static const char MOUNTSTUFF_ESCAPEES[] = " \t\n\\#";
_pinfo *p = (_pinfo *) data; _pinfo *p = (_pinfo *) data;
user_info *u_shared = NULL; user_info *u_shared = NULL;
HANDLE u_hdl = NULL; HANDLE u_hdl = NULL;
@ -1389,9 +1419,9 @@ format_process_mountstuff (void *data, char *&destbuf, bool mountinfo)
continue; continue;
} }
destbuf = (char *) crealloc_abort (destbuf, len destbuf = (char *) crealloc_abort (destbuf, len
+ strlen (mnt->mnt_fsname) + escape_string_length (mnt->mnt_fsname, MOUNTSTUFF_ESCAPEES)
+ strlen (mnt->mnt_dir) + escape_string_length (mnt->mnt_dir, MOUNTSTUFF_ESCAPEES)
+ strlen (mnt->mnt_type) + escape_string_length (mnt->mnt_type, MOUNTSTUFF_ESCAPEES)
+ strlen (mnt->mnt_opts) + strlen (mnt->mnt_opts)
+ 30); + 30);
if (mountinfo) if (mountinfo)
@ -1400,18 +1430,44 @@ format_process_mountstuff (void *data, char *&destbuf, bool mountinfo)
dev_t dev = pc.exists () ? pc.fs_serial_number () : -1; dev_t dev = pc.exists () ? pc.fs_serial_number () : -1;
len += __small_sprintf (destbuf + len, len += __small_sprintf (destbuf + len,
"%d %d %d:%d / %s %s - %s %s %s\n", "%d %d %d:%d / ",
iteration, iteration, iteration, iteration,
major (dev), minor (dev), major (dev), minor (dev));
mnt->mnt_dir, mnt->mnt_opts, len += escape_string (destbuf + len,
mnt->mnt_type, mnt->mnt_fsname, mnt->mnt_dir,
MOUNTSTUFF_ESCAPEES);
len += __small_sprintf (destbuf + len,
" %s - ",
mnt->mnt_opts);
len += escape_string (destbuf + len,
mnt->mnt_type,
MOUNTSTUFF_ESCAPEES);
destbuf[len++] = ' ';
len += escape_string (destbuf + len,
mnt->mnt_fsname,
MOUNTSTUFF_ESCAPEES);
len += __small_sprintf (destbuf + len,
" %s\n",
(pc.fs_flags () & FILE_READ_ONLY_VOLUME) (pc.fs_flags () & FILE_READ_ONLY_VOLUME)
? "ro" : "rw"); ? "ro" : "rw");
} }
else else
len += __small_sprintf (destbuf + len, "%s %s %s %s %d %d\n", {
mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, len += escape_string (destbuf + len,
mnt->mnt_opts, mnt->mnt_freq, mnt->mnt_passno); mnt->mnt_fsname,
MOUNTSTUFF_ESCAPEES);
destbuf[len++] = ' ';
len += escape_string (destbuf + len,
mnt->mnt_dir,
MOUNTSTUFF_ESCAPEES);
destbuf[len++] = ' ';
len += escape_string (destbuf + len,
mnt->mnt_type,
MOUNTSTUFF_ESCAPEES);
len += __small_sprintf (destbuf + len, " %s %d %d\n",
mnt->mnt_opts, mnt->mnt_freq,
mnt->mnt_passno);
}
} }
/* Restore available_drives */ /* Restore available_drives */