Browse Source

Added execv() and system().

tags/v0.9.3
Michael Brown 17 years ago
parent
commit
f3d817d512
4 changed files with 186 additions and 0 deletions
  1. 139
    0
      src/core/exec.c
  2. 22
    0
      src/include/gpxe/command.h
  3. 1
    0
      src/include/stdlib.h
  4. 24
    0
      src/include/unistd.h

+ 139
- 0
src/core/exec.c View File

@@ -0,0 +1,139 @@
1
+/*
2
+ * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <stdint.h>
20
+#include <string.h>
21
+#include <stdlib.h>
22
+#include <unistd.h>
23
+#include <getopt.h>
24
+#include <errno.h>
25
+#include <assert.h>
26
+#include <vsprintf.h>
27
+#include <gpxe/tables.h>
28
+#include <gpxe/command.h>
29
+
30
+/** @file
31
+ *
32
+ * Command execution
33
+ *
34
+ */
35
+
36
+static struct command commands[0] __table_start ( commands );
37
+static struct command commands_end[0] __table_end ( commands );
38
+
39
+/**
40
+ * Execute command
41
+ *
42
+ * @v command		Command name
43
+ * @v argv		Argument list
44
+ * @ret rc		Command exit status
45
+ *
46
+ * Execute the named command.  Unlike a traditional POSIX execv(),
47
+ * this function returns the exit status of the command.
48
+ */
49
+int execv ( const char *command, char * const argv[] ) {
50
+	struct command *cmd;
51
+	int argc = 0;
52
+
53
+	assert ( argv[0] != NULL );
54
+
55
+	/* Count number of arguments */
56
+	do {
57
+		argc++;
58
+	} while ( argv[argc] != NULL );
59
+
60
+	/* Reset getopt() library ready for use by the command.  This
61
+	 * is an artefact of the POSIX getopt() API within the context
62
+	 * of Etherboot; see the documentation for reset_getopt() for
63
+	 * details.
64
+	 */
65
+	reset_getopt();
66
+
67
+	/* Hand off to command implementation */
68
+	for ( cmd = commands ; cmd < commands_end ; cmd++ ) {
69
+		if ( strcmp ( command, cmd->name ) == 0 )
70
+			return cmd->exec ( argc, ( char ** ) argv );
71
+	}
72
+
73
+	printf ( "%s: command not found\n", command );
74
+	return -ENOEXEC;
75
+}
76
+
77
+/**
78
+ * Split command line into argv array
79
+ *
80
+ * @v args		Command line
81
+ * @v argv		Argument array to populate, or NULL
82
+ * @ret argc		Argument count
83
+ *
84
+ * Splits the command line into whitespace-delimited arguments.  If @c
85
+ * argv is non-NULL, any whitespace in the command line will be
86
+ * replaced with NULs.
87
+ */
88
+static int split_args ( char *args, char * argv[] ) {
89
+	int argc = 0;
90
+
91
+	while ( 1 ) {
92
+		/* Skip over any whitespace / convert to NUL */
93
+		while ( *args == ' ' ) {
94
+			if ( argv )
95
+				*args = '\0';
96
+			args++;
97
+		}
98
+		/* Check for end of line */
99
+		if ( ! *args )
100
+			break;
101
+		/* We have found the start of the next argument */
102
+		if ( argv )
103
+			argv[argc] = args;
104
+		argc++;
105
+		/* Skip to start of next whitespace, if any */
106
+		while ( *args && ( *args != ' ' ) ) {
107
+			args++;
108
+		}
109
+	}
110
+	return argc;
111
+}
112
+
113
+/**
114
+ * Execute command line
115
+ *
116
+ * @v command		Command line
117
+ * @ret rc		Command exit status
118
+ *
119
+ * Execute the named command and arguments.
120
+ */
121
+int system ( const char *command ) {
122
+	char *args = strdup ( command );
123
+	int argc;
124
+	
125
+	if ( ! args )
126
+		return -ENOMEM;
127
+
128
+	/* Count arguments */
129
+	argc = split_args ( args, NULL );
130
+
131
+	/* Create argv array and execute command */
132
+	{
133
+		char * argv[argc + 1];
134
+		
135
+		split_args ( args, argv );
136
+		argv[argc] = NULL;
137
+		return execv ( argv[0], argv );
138
+	}
139
+}

+ 22
- 0
src/include/gpxe/command.h View File

@@ -0,0 +1,22 @@
1
+#ifndef _GPXE_COMMAND_H
2
+#define _GPXE_COMMAND_H
3
+
4
+#include <gpxe/tables.h>
5
+
6
+/** A command-line command */
7
+struct command {
8
+	/** Name of the command */
9
+	const char *name;
10
+	/**
11
+	 * Function implementing the command
12
+	 *
13
+	 * @v argc		Argument count
14
+	 * @v argv		Argument list
15
+	 * @ret rc		Return status code
16
+	 */
17
+	int ( * exec ) ( int argc, char **argv );
18
+};
19
+
20
+#define __command __table ( commands, 01 )
21
+
22
+#endif /* _GPXE_COMMAND_H */

+ 1
- 0
src/include/stdlib.h View File

@@ -5,6 +5,7 @@ extern unsigned long strtoul ( const char *p, char **endp, int base );
5 5
 extern void * realloc ( void *old_ptr, size_t new_size );
6 6
 extern void * malloc ( size_t size );
7 7
 extern void free ( void *ptr );
8
+extern int system ( const char *command );
8 9
 
9 10
 /**
10 11
  * Allocate cleared memory

+ 24
- 0
src/include/unistd.h View File

@@ -0,0 +1,24 @@
1
+#ifndef _UNISTD_H
2
+#define _UNISTD_H
3
+
4
+#include <stddef.h>
5
+#include <stdarg.h>
6
+
7
+extern int execv ( const char *command, char * const argv[] );
8
+
9
+/**
10
+ * Execute command
11
+ *
12
+ * @v command		Command name
13
+ * @v arg ...		Argument list (starting with argv[0])
14
+ * @ret rc		Command exit status
15
+ *
16
+ * This is a front end to execv().
17
+ */
18
+#define execl( command, arg, ... ) ( {					\
19
+		char * const argv[] = { (arg), ## __VA_ARGS__, NULL };	\
20
+		int rc = execv ( (command), argv );			\
21
+		rc;							\
22
+	} )
23
+
24
+#endif /* _UNISTD_H */

Loading…
Cancel
Save