|
|
1e4a06 |
|
|
|
1e4a06 |
https://bugzilla.redhat.com/show_bug.cgi?id=1372700
|
|
|
1e4a06 |
|
|
|
1e4a06 |
Backported from scl-utils-2.0.
|
|
|
1e4a06 |
|
|
|
1e4a06 |
--- scl-utils-20130529/scl.c.shebang
|
|
|
1e4a06 |
+++ scl-utils-20130529/scl.c
|
|
|
1e4a06 |
@@ -35,6 +35,74 @@
|
|
|
1e4a06 |
#define SCL_CONF_DIR "/etc/scl/conf/"
|
|
|
1e4a06 |
#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
|
|
|
1e4a06 |
|
|
|
1e4a06 |
+static int count_words(const char *str, char ch)
|
|
|
1e4a06 |
+{
|
|
|
1e4a06 |
+ int count = 0;
|
|
|
1e4a06 |
+ bool inside_word = false;
|
|
|
1e4a06 |
+
|
|
|
1e4a06 |
+ while (*str != '\0') {
|
|
|
1e4a06 |
+ if (*str != ch) {
|
|
|
1e4a06 |
+ if (!inside_word) {
|
|
|
1e4a06 |
+ count++;
|
|
|
1e4a06 |
+ }
|
|
|
1e4a06 |
+ inside_word = true;
|
|
|
1e4a06 |
+ } else {
|
|
|
1e4a06 |
+ inside_word = false;
|
|
|
1e4a06 |
+ }
|
|
|
1e4a06 |
+ str++;
|
|
|
1e4a06 |
+ }
|
|
|
1e4a06 |
+
|
|
|
1e4a06 |
+ return count;
|
|
|
1e4a06 |
+}
|
|
|
1e4a06 |
+
|
|
|
1e4a06 |
+/**
|
|
|
1e4a06 |
+ * Procedure to parse shebang line and transform it to standard command
|
|
|
1e4a06 |
+ *
|
|
|
1e4a06 |
+ * In general, the shebang line has n parts at the beginnning:
|
|
|
1e4a06 |
+ * argv[0] => the name of the utility stated in shebang
|
|
|
1e4a06 |
+ * argv[1] => all the arguments as one string
|
|
|
1e4a06 |
+ * argv[2] => the script which was executed
|
|
|
1e4a06 |
+ * argv[n] => argument for executed script
|
|
|
1e4a06 |
+ *
|
|
|
1e4a06 |
+ * Considering the following shebang line in script ./test.py:
|
|
|
1e4a06 |
+ * #!/usr/bin/scl enable collectionX
|
|
|
1e4a06 |
+ * argv[0] = "/usr/bin/scl"
|
|
|
1e4a06 |
+ * argv[1] = "enable collectionX"
|
|
|
1e4a06 |
+ * argv[2] = "./test.py"
|
|
|
1e4a06 |
+ * argv[n] = "argn"
|
|
|
1e4a06 |
+ */
|
|
|
1e4a06 |
+static void parse_shebang(int argc, char *argv[],
|
|
|
1e4a06 |
+ int *_shebang_argc, char ***_shebang_argv) {
|
|
|
1e4a06 |
+ int i = 0;
|
|
|
1e4a06 |
+ char *p;
|
|
|
1e4a06 |
+ int shebang_argc;
|
|
|
1e4a06 |
+ char **shebang_argv;
|
|
|
1e4a06 |
+
|
|
|
1e4a06 |
+ shebang_argc = count_words(argv[1], ' ') + argc - 1;
|
|
|
1e4a06 |
+ shebang_argv = (char **)malloc(sizeof(char *) * shebang_argc);
|
|
|
1e4a06 |
+ if (shebang_argv == NULL) {
|
|
|
1e4a06 |
+ fprintf(stderr, "Can't allocate memory.\n");
|
|
|
1e4a06 |
+ exit(EXIT_FAILURE);
|
|
|
1e4a06 |
+ }
|
|
|
1e4a06 |
+
|
|
|
1e4a06 |
+ shebang_argv[i++] = argv[0];
|
|
|
1e4a06 |
+
|
|
|
1e4a06 |
+ p = strtok(argv[1], " ");
|
|
|
1e4a06 |
+ while (p != NULL) {
|
|
|
1e4a06 |
+ shebang_argv[i++] = p;
|
|
|
1e4a06 |
+ p = strtok(NULL, " ");
|
|
|
1e4a06 |
+ }
|
|
|
1e4a06 |
+
|
|
|
1e4a06 |
+ while (i < shebang_argc) {
|
|
|
1e4a06 |
+ shebang_argv[i] = argv[i - (shebang_argc - argc)];
|
|
|
1e4a06 |
+ i++;
|
|
|
1e4a06 |
+ }
|
|
|
1e4a06 |
+
|
|
|
1e4a06 |
+ *_shebang_argc = shebang_argc;
|
|
|
1e4a06 |
+ *_shebang_argv = shebang_argv;
|
|
|
1e4a06 |
+}
|
|
|
1e4a06 |
+
|
|
|
1e4a06 |
+
|
|
|
1e4a06 |
static void check_asprintf( char **strp, const char *fmt, ... ) {
|
|
|
1e4a06 |
va_list args;
|
|
|
1e4a06 |
|
|
|
1e4a06 |
@@ -648,6 +716,17 @@
|
|
|
1e4a06 |
}
|
|
|
1e4a06 |
}
|
|
|
1e4a06 |
|
|
|
1e4a06 |
+ if (argc >= 3 && strchr(argv[1], ' ') != NULL) {
|
|
|
1e4a06 |
+ /* Apparently a shebang line */
|
|
|
1e4a06 |
+ char **fake_argv = argv;
|
|
|
1e4a06 |
+ int fake_argc = argc;
|
|
|
1e4a06 |
+
|
|
|
1e4a06 |
+ parse_shebang(argc, argv, &fake_argc, &fake_argv);
|
|
|
1e4a06 |
+
|
|
|
1e4a06 |
+ argc = fake_argc;
|
|
|
1e4a06 |
+ argv = fake_argv;
|
|
|
1e4a06 |
+ }
|
|
|
1e4a06 |
+
|
|
|
1e4a06 |
for (i = 0; i < argc; i++) {
|
|
|
1e4a06 |
if (strcmp(argv[i], "--") == 0) {
|
|
|
1e4a06 |
break;
|