VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800   1) /* Copyright (C) 2006 by Paolo Giarrusso - modified from glibc' execvp.c.
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800   2)    Original copyright notice follows:
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800   3) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800   4)    Copyright (C) 1991,92,1995-99,2002,2004 Free Software Foundation, Inc.
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800   5)    This file is part of the GNU C Library.
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800   6) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800   7)    The GNU C Library is free software; you can redistribute it and/or
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800   8)    modify it under the terms of the GNU Lesser General Public
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800   9)    License as published by the Free Software Foundation; either
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  10)    version 2.1 of the License, or (at your option) any later version.
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  11) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  12)    The GNU C Library is distributed in the hope that it will be useful,
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  13)    but WITHOUT ANY WARRANTY; without even the implied warranty of
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  14)    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  15)    Lesser General Public License for more details.
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  16) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  17)    You should have received a copy of the GNU Lesser General Public
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  18)    License along with the GNU C Library; if not, write to the Free
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  19)    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  20)    02111-1307 USA.  */
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  21) #include <unistd.h>
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  22) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  23) #include <stdbool.h>
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  24) #include <stdlib.h>
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  25) #include <string.h>
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  26) #include <errno.h>
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  27) #include <limits.h>
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  28) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  29) #ifndef TEST
37185b3324087 (Al Viro                        2012-10-08 03:27:32 +0100  30) #include <um_malloc.h>
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  31) #else
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  32) #include <stdio.h>
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  33) #define um_kmalloc malloc
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  34) #endif
37185b3324087 (Al Viro                        2012-10-08 03:27:32 +0100  35) #include <os.h>
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  36) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  37) /* Execute FILE, searching in the `PATH' environment variable if it contains
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  38)    no slashes, with arguments ARGV and environment from `environ'.  */
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  39) int execvp_noalloc(char *buf, const char *file, char *const argv[])
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  40) {
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  41) 	if (*file == '\0') {
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  42) 		return -ENOENT;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  43) 	}
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  44) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  45) 	if (strchr (file, '/') != NULL) {
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  46) 		/* Don't search when it contains a slash.  */
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  47) 		execv(file, argv);
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  48) 	} else {
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  49) 		int got_eacces;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  50) 		size_t len, pathlen;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  51) 		char *name, *p;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  52) 		char *path = getenv("PATH");
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  53) 		if (path == NULL)
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  54) 			path = ":/bin:/usr/bin";
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  55) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  56) 		len = strlen(file) + 1;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  57) 		pathlen = strlen(path);
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  58) 		/* Copy the file name at the top.  */
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  59) 		name = memcpy(buf + pathlen + 1, file, len);
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  60) 		/* And add the slash.  */
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  61) 		*--name = '/';
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  62) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  63) 		got_eacces = 0;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  64) 		p = path;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  65) 		do {
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  66) 			char *startp;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  67) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  68) 			path = p;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  69) 			//Let's avoid this GNU extension.
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  70) 			//p = strchrnul (path, ':');
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  71) 			p = strchr(path, ':');
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  72) 			if (!p)
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  73) 				p = strchr(path, '\0');
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  74) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  75) 			if (p == path)
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  76) 				/* Two adjacent colons, or a colon at the beginning or the end
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  77) 				   of `PATH' means to search the current directory.  */
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  78) 				startp = name + 1;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  79) 			else
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  80) 				startp = memcpy(name - (p - path), path, p - path);
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  81) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  82) 			/* Try to execute this name.  If it works, execv will not return.  */
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  83) 			execv(startp, argv);
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  84) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  85) 			/*
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  86) 			if (errno == ENOEXEC) {
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  87) 			}
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  88) 			*/
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  89) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  90) 			switch (errno) {
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  91) 				case EACCES:
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  92) 					/* Record the we got a `Permission denied' error.  If we end
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  93) 					   up finding no executable we can use, we want to diagnose
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  94) 					   that we did find one but were denied access.  */
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  95) 					got_eacces = 1;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  96) 				case ENOENT:
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  97) 				case ESTALE:
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  98) 				case ENOTDIR:
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800  99) 					/* Those errors indicate the file is missing or not executable
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 100) 					   by us, in which case we want to just try the next path
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 101) 					   directory.  */
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 102) 				case ENODEV:
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 103) 				case ETIMEDOUT:
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 104) 					/* Some strange filesystems like AFS return even
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 105) 					   stranger error numbers.  They cannot reasonably mean
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 106) 					   anything else so ignore those, too.  */
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 107) 				case ENOEXEC:
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 108) 					/* We won't go searching for the shell
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 109) 					 * if it is not executable - the Linux
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 110) 					 * kernel already handles this enough,
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 111) 					 * for us. */
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 112) 					break;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 113) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 114) 				default:
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 115) 					/* Some other error means we found an executable file, but
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 116) 					   something went wrong executing it; return the error to our
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 117) 					   caller.  */
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 118) 					return -errno;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 119) 			}
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 120) 		} while (*p++ != '\0');
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 121) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 122) 		/* We tried every element and none of them worked.  */
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 123) 		if (got_eacces)
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 124) 			/* At least one failure was due to permissions, so report that
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 125) 			   error.  */
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 126) 			return -EACCES;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 127) 	}
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 128) 
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 129) 	/* Return the error from the last attempt (probably ENOENT).  */
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 130) 	return -errno;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 131) }
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 132) #ifdef TEST
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 133) int main(int argc, char**argv)
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 134) {
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 135) 	char buf[PATH_MAX];
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 136) 	int ret;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 137) 	argc--;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 138) 	if (!argc) {
0936d4f3d5a3d (Masami Hiramatsu               2017-05-18 02:19:31 +0900 139) 		os_warn("Not enough arguments\n");
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 140) 		return 1;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 141) 	}
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 142) 	argv++;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 143) 	if (ret = execvp_noalloc(buf, argv[0], argv)) {
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 144) 		errno = -ret;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 145) 		perror("execvp_noalloc");
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 146) 	}
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 147) 	return 0;
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 148) }
5d48545e5e88a (Paolo 'Blaisorblade' Giarrusso 2006-11-25 11:09:39 -0800 149) #endif