8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / modload / modload.c
blob2d528b3759d1a3302931b6cf1cc335291d0482c5
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/types.h>
27 #include <sys/wait.h>
28 #include <sys/param.h>
29 #include <sys/stat.h>
30 #include <sys/modctl.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <string.h>
35 #include <fcntl.h>
36 #include <errno.h>
37 #include <zone.h>
39 void l_exec_userfile(char *execfile, int id, char **envp);
40 void l_usage();
42 extern void fatal(char *fmt, ...);
43 extern void error(char *fmt, ...);
46 * Load a module.
48 int
49 main(int argc, char *argv[], char *envp[])
51 char *execfile = NULL; /* name of file to exec after loading */
52 char *modpath = NULL;
53 int id;
54 extern int optind;
55 extern char *optarg;
56 int opt;
57 int use_path = 0;
58 char path[1024];
60 if (argc < 2 || argc > 5) {
61 l_usage();
64 while ((opt = getopt(argc, argv, "e:p")) != -1) {
65 switch (opt) {
66 case 'e':
67 execfile = optarg;
68 break;
69 case 'p':
70 use_path++;
71 break;
72 case '?':
73 l_usage();
77 if (getzoneid() != GLOBAL_ZONEID) {
78 fatal("modload can only be run from the global zone\n");
81 modpath = argv[optind];
83 if (modpath == NULL) {
84 (void) printf("modpath is null\n");
85 l_usage();
87 if (!use_path && modpath[0] != '/') {
88 if (getcwd(path, 1023 - strlen(modpath)) == NULL)
89 fatal("Can't get current directory\n");
90 (void) strcat(path, "/");
91 (void) strcat(path, modpath);
92 } else
93 (void) strcpy(path, modpath);
96 * Load the module.
98 if (modctl(MODLOAD, use_path, path, &id) != 0) {
99 if (errno == EPERM)
100 fatal("Insufficient privileges to load a module\n");
101 else
102 error("can't load module");
106 * Exec the user's file (if any)
108 if (execfile)
109 l_exec_userfile(execfile, id, envp);
111 return (0); /* success */
115 * Exec the user's file
117 void
118 l_exec_userfile(char *execfile, int id, char **envp)
120 struct modinfo modinfo;
122 int child;
123 int status;
124 int waitret;
125 char module_id[8];
126 char mod0[8];
128 if ((child = fork()) == -1)
129 error("can't fork %s", execfile);
132 * exec the user program.
134 if (child == 0) {
135 modinfo.mi_id = id;
136 modinfo.mi_nextid = id;
137 modinfo.mi_info = MI_INFO_ONE;
138 if (modctl(MODINFO, id, &modinfo) < 0)
139 error("can't get module status");
141 (void) sprintf(module_id, "%d", modinfo.mi_id);
142 (void) sprintf(mod0, "%d", modinfo.mi_msinfo[0].msi_p0);
143 (void) execle(execfile, execfile, module_id, mod0, NULL, envp);
145 /* Shouldn't get here if execle was successful */
147 error("couldn't exec %s", execfile);
148 } else {
149 do {
150 /* wait for exec'd program to finish */
151 waitret = wait(&status);
152 } while ((waitret != child) && (waitret != -1));
154 waitret = (waitret == -1) ? waitret : status;
156 if ((waitret & 0377) != 0) {
157 /* exited because of a signal */
158 (void) printf("'%s' terminated because of signal %d",
159 execfile, (waitret & 0177));
160 if (waitret & 0200)
161 (void) printf(" and produced a core file\n");
162 (void) printf(".\n");
163 exit(waitret >> 8);
164 } else {
165 /* simple termination */
166 if (((waitret >> 8) & 0377) != 0) {
167 (void) printf("'%s' returned error %d.\n",
168 execfile, (waitret >> 8) & 0377);
169 exit(waitret >> 8);
175 void
176 l_usage()
178 fatal("usage: modload [-p] [-e <exec_file>] <filename>\n");