⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umount.c

📁 手机嵌入式Linux下可用的busybox源码
💻 C
字号:
/* vi: set sw=4 ts=4: *//* * Mini umount implementation for busybox * * * Copyright (C) 1999,2000 by Lineo, inc. and Erik Andersen * Copyright (C) 1999,2000,2001 by Erik Andersen <andersee@debian.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */#include <limits.h>#include <stdio.h>#include <mntent.h>#include <errno.h>#include <string.h>#include <stdlib.h>#include "busybox.h"/* Teach libc5 about realpath -- it includes it but the  * prototype is missing... */#if (__GLIBC__ <= 2) && (__GLIBC_MINOR__ < 1)extern char *realpath(const char *path, char *resolved_path);#endifstatic const int MNT_FORCE = 1;static const int MS_MGC_VAL = 0xc0ed0000; /* Magic number indicatng "new" flags */static const int MS_REMOUNT = 32;	/* Alter flags of a mounted FS.  */static const int MS_RDONLY = 1;	/* Mount read-only.  */extern int mount (__const char *__special_file, __const char *__dir,			__const char *__fstype, unsigned long int __rwflag,			__const void *__data);extern int umount (__const char *__special_file);extern int umount2 (__const char *__special_file, int __flags);struct _mtab_entry_t {	char *device;	char *mountpt;	struct _mtab_entry_t *next;};static struct _mtab_entry_t *mtab_cache = NULL;#if defined BB_FEATURE_MOUNT_FORCEstatic int doForce = FALSE;#endif#if defined BB_FEATURE_MOUNT_LOOPstatic int freeLoop = TRUE;#endif#if defined BB_FEATURE_MTAB_SUPPORTstatic int useMtab = TRUE;#endifstatic int umountAll = FALSE;static int doRemount = FALSE;extern const char mtab_file[];	/* Defined in utility.c *//* These functions are here because the getmntent functions do not appear * to be re-entrant, which leads to all sorts of problems when we try to * use them recursively - randolph * * TODO: Perhaps switch to using Glibc's getmntent_r *        -Erik */static void mtab_read(void){	struct _mtab_entry_t *entry = NULL;	struct mntent *e;	FILE *fp;	if (mtab_cache != NULL)		return;	if ((fp = setmntent(mtab_file, "r")) == NULL) {		error_msg("Cannot open %s", mtab_file);		return;	}	while ((e = getmntent(fp))) {		entry = xmalloc(sizeof(struct _mtab_entry_t));		entry->device = strdup(e->mnt_fsname);		entry->mountpt = strdup(e->mnt_dir);		entry->next = mtab_cache;		mtab_cache = entry;	}	endmntent(fp);}static char *mtab_getinfo(const char *match, const char which){	struct _mtab_entry_t *cur = mtab_cache;	while (cur) {		if (strcmp(cur->mountpt, match) == 0 ||			strcmp(cur->device, match) == 0) {			if (which == MTAB_GETMOUNTPT) {				return cur->mountpt;			} else {#if !defined BB_FEATURE_MTAB_SUPPORT				if (strcmp(cur->device, "/dev/root") == 0) {					/* Adjusts device to be the real root device,					 * or leaves device alone if it can't find it */					cur->device = find_real_root_device_name(cur->device);				}#endif				return cur->device;			}		}		cur = cur->next;	}	return NULL;}static char *mtab_next(void **iter){	char *mp;	if (iter == NULL || *iter == NULL)		return NULL;	mp = ((struct _mtab_entry_t *) (*iter))->mountpt;	*iter = (void *) ((struct _mtab_entry_t *) (*iter))->next;	return mp;}static char *mtab_first(void **iter){	struct _mtab_entry_t *mtab_iter;	if (!iter)		return NULL;	mtab_iter = mtab_cache;	*iter = (void *) mtab_iter;	return mtab_next(iter);}/* Don't bother to clean up, since exit() does that  * automagically, so we can save a few bytes */#ifdef BB_FEATURE_CLEAN_UPstatic void mtab_free(void){	struct _mtab_entry_t *this, *next;	this = mtab_cache;	while (this) {		next = this->next;		if (this->device)			free(this->device);		if (this->mountpt)			free(this->mountpt);		free(this);		this = next;	}}#endifstatic int do_umount(const char *name){	int status;	char *blockDevice = mtab_getinfo(name, MTAB_GETDEVICE);	if (blockDevice && strcmp(blockDevice, name) == 0)		name = mtab_getinfo(blockDevice, MTAB_GETMOUNTPT);	status = umount(name);#if defined BB_FEATURE_MOUNT_LOOP	if (freeLoop == TRUE && blockDevice != NULL && !strncmp("/dev/loop", blockDevice, 9))		/* this was a loop device, delete it */		del_loop(blockDevice);#endif#if defined BB_FEATURE_MOUNT_FORCE	if (status != 0 && doForce == TRUE) {		status = umount2(blockDevice, MNT_FORCE);		if (status != 0) {			error_msg_and_die("forced umount of %s failed!", blockDevice);		}	}#endif	if (status != 0 && doRemount == TRUE && errno == EBUSY) {		status = mount(blockDevice, name, NULL,					   MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL);		if (status == 0) {			error_msg("%s busy - remounted read-only", blockDevice);		} else {			error_msg("Cannot remount %s read-only", blockDevice);		}	}	if (status == 0) {#if defined BB_FEATURE_MTAB_SUPPORT		if (useMtab == TRUE)			erase_mtab(name);#endif		return (TRUE);	}	return (FALSE);}static int umount_all(void){	int status = TRUE;	char *mountpt;	void *iter;	for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) {		/* Never umount /proc on a umount -a */		if (strstr(mountpt, "proc")!= NULL)			continue;		if (!do_umount(mountpt)) {			/* Don't bother retrying the umount on busy devices */			if (errno == EBUSY) {				perror_msg("%s", mountpt);				status = FALSE;				continue;			}			if (!do_umount(mountpt)) {				printf("Couldn't umount %s on %s: %s\n",					   mountpt, mtab_getinfo(mountpt, MTAB_GETDEVICE),					   strerror(errno));				status = FALSE;			}		}	}	return (status);}extern int umount_main(int argc, char **argv){	char path[PATH_MAX];	if (argc < 2) {		show_usage();	}#ifdef BB_FEATURE_CLEAN_UP	atexit(mtab_free);#endif	/* Parse any options */	while (--argc > 0 && **(++argv) == '-') {		while (*++(*argv))			switch (**argv) {			case 'a':				umountAll = TRUE;				break;#if defined BB_FEATURE_MOUNT_LOOP			case 'l':				freeLoop = FALSE;				break;#endif#ifdef BB_FEATURE_MTAB_SUPPORT			case 'n':				useMtab = FALSE;				break;#endif#ifdef BB_FEATURE_MOUNT_FORCE			case 'f':				doForce = TRUE;				break;#endif			case 'r':				doRemount = TRUE;				break;			case 'v':				break; /* ignore -v */			default:				show_usage();			}	}	mtab_read();	if (umountAll == TRUE) {		if (umount_all() == TRUE)			return EXIT_SUCCESS;		else			return EXIT_FAILURE;	}	if (realpath(*argv, path) == NULL)		perror_msg_and_die("%s", path);	if (do_umount(path) == TRUE)		return EXIT_SUCCESS;	perror_msg_and_die("%s", *argv);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -