Commit edaf8b1b by Stéphane Graber

Add local implementation of mntent.h

Bionic (at least) is missing some of the usual mntent functions. This adds code defining those that we need when they're missing from the C library. Signed-off-by: 's avatarStéphane Graber <stgraber@ubuntu.com> Acked-by: 's avatarSerge E. Hallyn <serge.hallyn@ubuntu.com>
parent c4b79084
...@@ -227,7 +227,7 @@ AC_CHECK_HEADERS([sys/signalfd.h pty.h sys/capability.h sys/personality.h utmpx. ...@@ -227,7 +227,7 @@ AC_CHECK_HEADERS([sys/signalfd.h pty.h sys/capability.h sys/personality.h utmpx.
AC_CHECK_FUNCS([setns pivot_root sethostname unshare]) AC_CHECK_FUNCS([setns pivot_root sethostname unshare])
# Check for some functions # Check for some functions
AC_CHECK_FUNCS([openpty]) AC_CHECK_FUNCS([openpty hasmntopt setmntent endmntent])
AC_CHECK_FUNCS([getline], AC_CHECK_FUNCS([getline],
AM_CONDITIONAL(HAVE_GETLINE, true) AM_CONDITIONAL(HAVE_GETLINE, true)
AC_DEFINE(HAVE_GETLINE,1,[Have getline]), AC_DEFINE(HAVE_GETLINE,1,[Have getline]),
......
#include <stdio.h>
#include <string.h>
#include <mntent.h>
/* Since the values in a line are separated by spaces, a name cannot
contain a space. Therefore some programs encode spaces in names
by the strings "\040". We undo the encoding when reading an entry.
The decoding happens in place. */
static char *
decode_name (char *buf)
{
char *rp = buf;
char *wp = buf;
do
if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '4' && rp[3] == '0')
{
/* \040 is a SPACE. */
*wp++ = ' ';
rp += 3;
}
else if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '1' && rp[3] == '1')
{
/* \011 is a TAB. */
*wp++ = '\t';
rp += 3;
}
else if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '1' && rp[3] == '2')
{
/* \012 is a NEWLINE. */
*wp++ = '\n';
rp += 3;
}
else if (rp[0] == '\\' && rp[1] == '\\')
{
/* We have to escape \\ to be able to represent all characters. */
*wp++ = '\\';
rp += 1;
}
else if (rp[0] == '\\' && rp[1] == '1' && rp[2] == '3' && rp[3] == '4')
{
/* \134 is also \\. */
*wp++ = '\\';
rp += 3;
}
else
*wp++ = *rp;
while (*rp++ != '\0');
return buf;
}
/* Read one mount table entry from STREAM. Returns a pointer to storage
reused on the next call, or null for EOF or error (use feof/ferror to
check). */
struct mntent *getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
{
char *cp;
char *head;
do
{
char *end_ptr;
if (fgets (buffer, bufsiz, stream) == NULL)
{
return NULL;
}
end_ptr = strchr (buffer, '\n');
if (end_ptr != NULL) /* chop newline */
*end_ptr = '\0';
else
{
/* Not the whole line was read. Do it now but forget it. */
char tmp[1024];
while (fgets (tmp, sizeof tmp, stream) != NULL)
if (strchr (tmp, '\n') != NULL)
break;
}
head = buffer + strspn (buffer, " \t");
/* skip empty lines and comment lines: */
}
while (head[0] == '\0' || head[0] == '#');
cp = strsep (&head, " \t");
mp->mnt_fsname = cp != NULL ? decode_name (cp) : (char *) "";
if (head)
head += strspn (head, " \t");
cp = strsep (&head, " \t");
mp->mnt_dir = cp != NULL ? decode_name (cp) : (char *) "";
if (head)
head += strspn (head, " \t");
cp = strsep (&head, " \t");
mp->mnt_type = cp != NULL ? decode_name (cp) : (char *) "";
if (head)
head += strspn (head, " \t");
cp = strsep (&head, " \t");
mp->mnt_opts = cp != NULL ? decode_name (cp) : (char *) "";
switch (head ? sscanf (head, " %d %d ", &mp->mnt_freq, &mp->mnt_passno) : 0)
{
case 0:
mp->mnt_freq = 0;
case 1:
mp->mnt_passno = 0;
case 2:
break;
}
return mp;
}
struct mntent *getmntent (FILE *stream)
{
static struct mntent m;
static char *getmntent_buffer;
#define BUFFER_SIZE 4096
if (getmntent_buffer == NULL) {
getmntent_buffer = (char *) malloc (BUFFER_SIZE);
}
return getmntent_r (stream, &m, getmntent_buffer, BUFFER_SIZE);
#undef BUFFER_SIZE
}
/* Prepare to begin reading and/or writing mount table entries from the
beginning of FILE. MODE is as for `fopen'. */
FILE *setmntent (const char *file, const char *mode)
{
/* Extend the mode parameter with "c" to disable cancellation in the
I/O functions and "e" to set FD_CLOEXEC. */
size_t modelen = strlen (mode);
char newmode[modelen + 3];
memcpy (newmode, mode, modelen);
memcpy (newmode + modelen, "ce", 3);
FILE *result = fopen (file, newmode);
return result;
}
/* Close a stream opened with `setmntent'. */
int endmntent (FILE *stream)
{
if (stream) /* SunOS 4.x allows for NULL stream */
fclose (stream);
return 1; /* SunOS 4.x says to always return 1 */
}
/* Search MNT->mnt_opts for an option matching OPT.
Returns the address of the substring, or null if none found. */
char *hasmntopt (const struct mntent *mnt, const char *opt)
{
const size_t optlen = strlen (opt);
char *rest = mnt->mnt_opts, *p;
while ((p = strstr (rest, opt)) != NULL)
{
if ((p == rest || p[-1] == ',')
&& (p[optlen] == '\0' || p[optlen] == '=' || p[optlen] == ','))
return p;
rest = strchr (p, ',');
if (rest == NULL)
break;
++rest;
}
return NULL;
}
#ifndef _mntent_h
#define _mntent_h
#include <../config.h>
#if IS_BIONIC
struct mntent
{
char* mnt_fsname;
char* mnt_dir;
char* mnt_type;
char* mnt_opts;
int mnt_freq;
int mnt_passno;
};
extern struct mntent *getmntent (FILE *stream);
#endif
#ifndef HAVE_SETMNTENT
FILE *setmntent (const char *file, const char *mode);
#endif
#ifndef HAVE_ENDMNTENT
int endmntent (FILE *stream);
#endif
#ifndef HAVE_HASMNTOPT
extern char *hasmntopt (const struct mntent *mnt, const char *opt);
#endif
#endif
...@@ -19,7 +19,8 @@ pkginclude_HEADERS = \ ...@@ -19,7 +19,8 @@ pkginclude_HEADERS = \
if IS_BIONIC if IS_BIONIC
pkginclude_HEADERS += \ pkginclude_HEADERS += \
../include/openpty.h ../include/openpty.h \
../include/lxcmntent.h
endif endif
if !HAVE_GETLINE if !HAVE_GETLINE
...@@ -74,7 +75,8 @@ liblxc_so_SOURCES = \ ...@@ -74,7 +75,8 @@ liblxc_so_SOURCES = \
if IS_BIONIC if IS_BIONIC
liblxc_so_SOURCES += \ liblxc_so_SOURCES += \
../include/openpty.c ../include/openpty.h ../include/openpty.c ../include/openpty.h \
../include/lxcmntent.c ../include/lxcmntent.h
endif endif
if !HAVE_GETLINE if !HAVE_GETLINE
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#undef _GNU_SOURCE #undef _GNU_SOURCE
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <mntent.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <dirent.h> #include <dirent.h>
...@@ -44,6 +43,12 @@ ...@@ -44,6 +43,12 @@
#include <lxc/cgroup.h> #include <lxc/cgroup.h>
#include <lxc/start.h> #include <lxc/start.h>
#if IS_BIONIC
#include <../include/lxcmntent.h>
#else
#include <mntent.h>
#endif
lxc_log_define(lxc_cgroup, lxc); lxc_log_define(lxc_cgroup, lxc);
#define MTAB "/proc/mounts" #define MTAB "/proc/mounts"
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <dirent.h> #include <dirent.h>
#include <mntent.h>
#include <unistd.h> #include <unistd.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/syscall.h> #include <sys/syscall.h>
...@@ -78,6 +77,12 @@ ...@@ -78,6 +77,12 @@
#include <sys/personality.h> #include <sys/personality.h>
#endif #endif
#if IS_BIONIC
#include <../include/lxcmntent.h>
#else
#include <mntent.h>
#endif
#include "lxcseccomp.h" #include "lxcseccomp.h"
lxc_log_define(lxc_conf, lxc); lxc_log_define(lxc_conf, lxc);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment