[lxc-devel] [PATCH 18/24] Add local implementation of mntent.h

Stéphane Graber stgraber at ubuntu.com
Wed Jan 9 15:30:47 UTC 2013


On 01/08/2013 01:33 PM, Serge Hallyn wrote:
> Quoting Stéphane Graber (stgraber at ubuntu.com):
>> 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: Stéphane Graber <stgraber at ubuntu.com>
> 
> Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.com>
> 
> I could see someone in the future deciding that ../include should be
> added to -I, which would cause our include/mntent.h to always be
> included in favor of the system one (iiuc).  Not sure whether that's
> worth worrying about.  If so, perhaps rename to lxcmntent.h?

Renamed and pushed. Thanks

>> ---
>>  configure.ac         |   2 +-
>>  src/include/mntent.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++
>>  src/include/mntent.h |  32 ++++++++++
>>  src/lxc/Makefile.am  |   6 +-
>>  src/lxc/cgroup.c     |   7 ++-
>>  src/lxc/conf.c       |   7 ++-
>>  6 files changed, 222 insertions(+), 5 deletions(-)
>>  create mode 100644 src/include/mntent.c
>>  create mode 100644 src/include/mntent.h
>>
>> diff --git a/configure.ac b/configure.ac
>> index 0d50bec..3770e8b 100644
>> --- a/configure.ac
>> +++ b/configure.ac
>> @@ -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])
>>  
>>  # Check for some functions
>> -AC_CHECK_FUNCS([getline fgetln openpty])
>> +AC_CHECK_FUNCS([getline fgetln openpty hasmntopt setmntent endmntent])
>>  
>>  # Check for some standard binaries
>>  AC_PROG_GCC_TRADITIONAL
>> diff --git a/src/include/mntent.c b/src/include/mntent.c
>> new file mode 100644
>> index 0000000..a96cd81
>> --- /dev/null
>> +++ b/src/include/mntent.c
>> @@ -0,0 +1,173 @@
>> +#include <mntent.h>
>> +#include <stdio.h>
>> +#include <string.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;
>> +}
>> diff --git a/src/include/mntent.h b/src/include/mntent.h
>> new file mode 100644
>> index 0000000..3f1d16f
>> --- /dev/null
>> +++ b/src/include/mntent.h
>> @@ -0,0 +1,32 @@
>> +#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
>> diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am
>> index 3d800d5..8bc7b4b 100644
>> --- a/src/lxc/Makefile.am
>> +++ b/src/lxc/Makefile.am
>> @@ -20,7 +20,8 @@ pkginclude_HEADERS = \
>>  if IS_BIONIC
>>  pkginclude_HEADERS += \
>>  	../include/getline.h \
>> -	../include/openpty.h
>> +	../include/openpty.h \
>> +	../include/mntent.h
>>  endif
>>  
>>  sodir=$(libdir)
>> @@ -70,7 +71,8 @@ liblxc_so_SOURCES = \
>>  if IS_BIONIC
>>  liblxc_so_SOURCES += \
>>  	../include/getline.c ../include/getline.h \
>> -	../include/openpty.c ../include/openpty.h
>> +	../include/openpty.c ../include/openpty.h \
>> +	../include/mntent.c ../include/mntent.h
>>  endif
>>  
>>  AM_CFLAGS=-I$(top_srcdir)/src \
>> diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c
>> index f6243b8..0f2057f 100644
>> --- a/src/lxc/cgroup.c
>> +++ b/src/lxc/cgroup.c
>> @@ -25,7 +25,6 @@
>>  #undef _GNU_SOURCE
>>  #include <stdlib.h>
>>  #include <errno.h>
>> -#include <mntent.h>
>>  #include <unistd.h>
>>  #include <string.h>
>>  #include <dirent.h>
>> @@ -44,6 +43,12 @@
>>  #include <lxc/cgroup.h>
>>  #include <lxc/start.h>
>>  
>> +#if IS_BIONIC
>> +#include <../include/mntent.h>
>> +#else
>> +#include <mntent.h>
>> +#endif
>> +
>>  lxc_log_define(lxc_cgroup, lxc);
>>  
>>  #define MTAB "/proc/mounts"
>> diff --git a/src/lxc/conf.c b/src/lxc/conf.c
>> index 4a2fd22..e6efcf0 100644
>> --- a/src/lxc/conf.c
>> +++ b/src/lxc/conf.c
>> @@ -28,7 +28,6 @@
>>  #include <errno.h>
>>  #include <string.h>
>>  #include <dirent.h>
>> -#include <mntent.h>
>>  #include <unistd.h>
>>  #include <sys/wait.h>
>>  #include <sys/syscall.h>
>> @@ -78,6 +77,12 @@
>>  #include <sys/personality.h>
>>  #endif
>>  
>> +#if IS_BIONIC
>> +#include <../include/mntent.h>
>> +#else
>> +#include <mntent.h>
>> +#endif
>> +
>>  #include "lxcseccomp.h"
>>  
>>  lxc_log_define(lxc_conf, lxc);
>> -- 
>> 1.8.0
>>
>>
>> ------------------------------------------------------------------------------
>> Master SQL Server Development, Administration, T-SQL, SSAS, SSIS, SSRS
>> and more. Get SQL Server skills now (including 2012) with LearnDevNow -
>> 200+ hours of step-by-step video tutorials by Microsoft MVPs and experts.
>> SALE $99.99 this month only - learn more at:
>> http://p.sf.net/sfu/learnmore_122512
>> _______________________________________________
>> Lxc-devel mailing list
>> Lxc-devel at lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/lxc-devel


-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20130109/b764ba71/attachment.pgp>


More information about the lxc-devel mailing list