void runSuccess1() {
    size_t argz_len = anysize();
    char* argz = anyargz(argz_len, anysize());
    char* elem = argz_next(argz, argz_len, argz);
    if (elem) {
        argz_delete(&argz, &argz_len, elem);
    }
}
void testValues() {
    f = 2;

    size_t argz_len = anysize();
    char* argz = anyargz(argz_len, anysize());
    char* elem = argz_next(argz, argz_len, argz);
    if (elem) {
        argz_delete(&argz, &argz_len, elem);
    }

    //@ assert f == 2;
    //@ assert vacuous: \false;
}
void runFailure3() {
    size_t argz_len = anysize();
     char* argz = anyargz(argz_len, anysize());
     argz_delete(&argz, &argz_len, anystring());
}
void runFailure2() {
    size_t argz_len = anysize();
     char* argz = anyargz(argz_len, anysize());
     argz_delete(&argz, &argz_len, NULL);
}
void runFailure1() {
    char argz[] = "s";
    argz_delete(argz, anysize(), argz);
}
void runFailure() {
    argz_delete(NULL, anysize(), NULL);
}
void runSuccess() {
    size_t argz_len = anysize();
    char* argz = anyargz(argz_len, anysize());
    argz_delete(&argz, &argz_len, argz);
}
Ejemplo n.º 8
0
/* Mount one filesystem.  */
static error_t
do_mount (struct fs *fs, int remount)
{
    error_t err;
    char *fsopts, *o;
    size_t fsopts_len;
    char *mntopts;
    size_t mntopts_len;
    fsys_t mounted;

    inline void explain (const char *command)
    {
        if (verbose)
        {
            const char *o;
            printf ("%s %s", command, fs->mntent.mnt_dir);
            for (o = fsopts; o; o = argz_next (fsopts, fsopts_len, o))
                printf (" %s", o);
            putchar ('\n');
        }
    }

    err = fs_fsys (fs, &mounted);
    if (err)
    {
        error (0, err, "cannot determine if %s is already mounted",
               fs->mntent.mnt_fsname);
        return err;
    }


    /* Produce an argz of translator option arguments from the
       given FS's options and the command-line options.  */

#define ARGZ(call)							      \
  err = argz_##call;							      \
  if (err)								      \
    error (3, ENOMEM, "collecting mount options");			      \

    if (fs->mntent.mnt_opts)
    {
        /* Append the fstab options to any specified on the command line.  */
        ARGZ (create_sep (fs->mntent.mnt_opts, ',', &mntopts, &mntopts_len));

        /* Remove the `noauto' and `bind' options, since they're for us not the
           filesystem.  */
        for (o = mntopts; o; o = argz_next (mntopts, mntopts_len, o))
        {
            if (strcmp (o, MNTOPT_NOAUTO) == 0)
                argz_delete (&mntopts, &mntopts_len, o);
            if (strcmp (o, "bind") == 0)
            {
                fs->mntent.mnt_type = strdup ("firmlink");
                if (!fs->mntent.mnt_type)
                    error (3, ENOMEM, "failed to allocate memory");
                argz_delete (&mntopts, &mntopts_len, o);
            }
        }

        ARGZ (append (&mntopts, &mntopts_len, options, options_len));
    }
    else
    {
        mntopts = options;
        mntopts_len = options_len;
    }

    /* Convert the list of options into a list of switch arguments.  */
    fsopts = 0;
    fsopts_len = 0;
    for (o = mntopts; o; o = argz_next (mntopts, mntopts_len, o))
        if (*o == '-')		/* Allow letter opts `-o -r,-E', BSD style.  */
        {
            ARGZ (add (&fsopts, &fsopts_len, o));
        }
        else if ((strcmp (o, "defaults") != 0) && (strlen (o) != 0))
        {
            /* Prepend `--' to the option to make a long option switch,
               e.g. `--ro' or `--rsize=1024'.  */
            char arg[2 + strlen (o) + 1];
            arg[0] = arg[1] = '-';
            memcpy (&arg[2], o, sizeof arg - 2);
            ARGZ (add (&fsopts, &fsopts_len, arg));
        }

    if (mntopts != options)
        free (mntopts);
#undef ARGZ

    if (remount)
    {
        if (mounted == MACH_PORT_NULL)
        {
            error (0, 0, "%s not already mounted", fs->mntent.mnt_fsname);
            return EBUSY;
        }

        /* Send an RPC to request the new options, including --update.  */
        explain ("fsysopts");
        err = fsys_set_options (mounted, fsopts, fsopts_len, 0);
        if (err)
            error (0, err, "cannot remount %s", fs->mntent.mnt_fsname);
        return err;
    }
    else
    {
        /* Error during file lookup; we use this to avoid duplicating error
        messages.  */
        error_t open_err = 0;
        /* The control port for any active translator we start up.  */
        fsys_t active_control;
        file_t node;		/* Port to the underlying node.  */
        struct fstype *type;

        /* The callback to start_translator opens NODE as a side effect.  */
        error_t open_node (int flags,
                           mach_port_t *underlying,
                           mach_msg_type_name_t *underlying_type,
                           task_t task, void *cookie)
        {
            node = file_name_lookup (fs->mntent.mnt_dir,
                                     flags | O_NOTRANS, 0666);
            if (node == MACH_PORT_NULL)
            {
                open_err = errno;
                return open_err;
            }

            *underlying = node;
            *underlying_type = MACH_MSG_TYPE_COPY_SEND;

            return 0;
        }

        /* Do not fail if there is an active translator if --fake is
           given. This mimics Linux mount utility more closely which
           just looks into the mtab file. */
        if (mounted != MACH_PORT_NULL && !fake)
        {
            error (0, 0, "%s already mounted", fs->mntent.mnt_fsname);
            return EBUSY;
        }

        if (strcmp (fs->mntent.mnt_type, "auto") == 0)
        {
#if HAVE_BLKID
            char *type =
                blkid_get_tag_value (NULL, "TYPE", fs->mntent.mnt_fsname);
            if (! type)
            {
                error (0, 0, "failed to detect file system type");
                return EFTYPE;
            }
            else
            {
                if (strcmp (type, "vfat") == 0)
                    fs->mntent.mnt_type = strdup ("fat");
                else
                    fs->mntent.mnt_type = strdup (type);
                if (! fs->mntent.mnt_type)
                    error (3, ENOMEM, "failed to allocate memory");
            }
#else
            fs->mntent.mnt_type = strdup ("ext2");
            if (! fs->mntent.mnt_type)
                error (3, ENOMEM, "failed to allocate memory");
#endif
        }

        err = fs_type (fs, &type);
        if (err)
        {
            error (0, err, "%s: cannot determine filesystem type",
                   fs->mntent.mnt_fsname);
            return err;
        }
        if (type->program == 0)
        {
            error (0, 0, "%s: filesystem type `%s' unknown",
                   fs->mntent.mnt_fsname, type->name);
            return EFTYPE;
        }

        /* Stick the translator program name in front of the option switches.  */
        err = argz_insert (&fsopts, &fsopts_len, fsopts, type->program);
        /* Now stick the device name on the end as the last argument.  */
        if (!err)
            err = argz_add (&fsopts, &fsopts_len, fs->mntent.mnt_fsname);
        if (err)
            error (3, ENOMEM, "collecting mount options");

        /* Now we have a translator command line argz in FSOPTS.  */

        if (fake) {
            /* Fake the translator startup. */
            mach_port_t underlying;
            mach_msg_type_name_t underlying_type;
            err = open_node (O_READ, &underlying, &underlying_type, 0, NULL);
            if (err)
                error (1, errno, "cannot mount on %s", fs->mntent.mnt_dir);

            mach_port_deallocate (mach_task_self (), underlying);

            /* See if the translator is at least executable. */
            if (access(type->program, X_OK) == -1)
                error (1, errno, "can not execute %s", type->program);

            return 0;
        }

        explain ("settrans -a");
        err = fshelp_start_translator (open_node, NULL, fsopts,
                                       fsopts, fsopts_len, timeout,
                                       &active_control);
        /* If ERR is due to a problem opening the translated node, we print
        that name, otherwise, the name of the translator.  */
        if (open_err)
            error (0, open_err, "cannot mount on %s", fs->mntent.mnt_dir);
        else if (err)
            error (0, err, "cannot start translator %s", fsopts);
        else
        {
            err = file_set_translator (node, 0, FS_TRANS_SET|FS_TRANS_EXCL, 0,
                                       0, 0,
                                       active_control, MACH_MSG_TYPE_COPY_SEND);
            if (err == EBUSY)
                error (0, 0, "%s already mounted on", fs->mntent.mnt_dir);
            else if (err)
                error (0, err, "cannot set translator on %s", fs->mntent.mnt_dir);
            if (err)
                fsys_goaway (active_control, FSYS_GOAWAY_FORCE);
            mach_port_deallocate (mach_task_self (), active_control);
        }

        return err;
    }