aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--findutils/xargs.c156
-rw-r--r--xargs.c156
2 files changed, 124 insertions, 188 deletions
diff --git a/findutils/xargs.c b/findutils/xargs.c
index 21bfb6bbe..b8ac31aa0 100644
--- a/findutils/xargs.c
+++ b/findutils/xargs.c
@@ -28,68 +28,19 @@
28#include <errno.h> 28#include <errno.h>
29#include <getopt.h> 29#include <getopt.h>
30#include <ctype.h> 30#include <ctype.h>
31 31#include <sys/types.h>
32/* get_sh_safe_line_from_file() - This function reads an entire line from a text file 32#include <sys/wait.h>
33 * up to a newline. It returns a malloc'ed char * which must be stored and
34 * free'ed by the caller. */
35extern char *get_sh_safe_line_from_file(FILE *file)
36{
37 static const int GROWBY = 80; /* how large we will grow strings by */
38
39 char ch, last_ch = 0;
40 char tmp[]=" ";
41 int idx = 0;
42 char *linebuf = NULL;
43 int linebufsz = 0;
44
45 while (1) {
46 ch = fgetc(file);
47 if (ch == EOF)
48 break;
49
50 /* grow the line buffer as necessary */
51 while (idx > linebufsz-4)
52 linebuf = xrealloc(linebuf, linebufsz += GROWBY);
53
54 /* Remove any extra spaces */
55 if (last_ch == ' ' && ch == ' ')
56 continue;
57
58 /* Replace any tabs with spaces */
59 if (ch == '\t')
60 ch=' ';
61
62 /* Escape any characters that are treated specially by /bin/sh */
63 *tmp=ch;
64 if (strpbrk(tmp, "\\~`!$^&*()=|{}[];\"'<>?#") != NULL && last_ch!='\\') {
65 linebuf[idx++] = '\\';
66 }
67
68 linebuf[idx++] = ch;
69 last_ch=ch;
70
71 if (ch == '\n')
72 break;
73 }
74 if (idx == 0 && last_ch!=0)
75 linebuf[idx++]=' ';
76
77 if (idx == 0)
78 return NULL;
79
80 linebuf[idx] = 0;
81 return linebuf;
82}
83
84 33
85 34
86int xargs_main(int argc, char **argv) 35int xargs_main(int argc, char **argv)
87{ 36{
88 char *in_from_stdin = NULL; 37 char *in_from_stdin = NULL;
89 char *args_from_cmdline = NULL; 38 char *args = NULL;
90 char *cmd_to_be_executed = NULL; 39 char *cmd_to_be_executed = NULL;
91 char traceflag = 0; 40 char traceflag = 0;
92 int len_args_from_cmdline, len_cmd_to_be_executed, len, opt; 41 int len_args=10, len_cmd_to_be_executed, opt;
42 pid_t pid;
43 int wpid, status;
93 44
94 /* Note that we do not use getopt here, since 45 /* Note that we do not use getopt here, since
95 * we only want to interpret initial options, 46 * we only want to interpret initial options,
@@ -102,50 +53,45 @@ int xargs_main(int argc, char **argv)
102 break; 53 break;
103 default: 54 default:
104 fatalError(xargs_usage); 55 fatalError(xargs_usage);
105 } 56 }
106 } 57 }
107 } 58 }
108 59
109 /* Store the command and arguments to be executed (from the command line) */ 60 /* Store the command to be executed (taken from the command line) */
110 if (argc == 0) { 61 if (argc == 0) {
111 len_args_from_cmdline = 6; 62 len_cmd_to_be_executed=6;
112 args_from_cmdline = xmalloc(len_args_from_cmdline); 63 cmd_to_be_executed = xmalloc(len_cmd_to_be_executed);
113 strcat(args_from_cmdline, "echo "); 64 strcat(cmd_to_be_executed, "echo");
114 } else { 65 } else {
115 opt=strlen(*argv); 66 opt=strlen(*argv);
116 len_args_from_cmdline = (opt > 10)? opt : 10; 67 len_cmd_to_be_executed = (opt > 10)? opt : 10;
117 args_from_cmdline = xcalloc(len_args_from_cmdline, sizeof(char)); 68 cmd_to_be_executed = xcalloc(len_cmd_to_be_executed, sizeof(char));
118 while (argc-- > 0) { 69 strcat(cmd_to_be_executed, *argv);
119 if (strlen(*argv) + strlen(args_from_cmdline) >
120 len_args_from_cmdline) {
121 len_args_from_cmdline += strlen(*argv);
122 args_from_cmdline =
123 xrealloc(args_from_cmdline,
124 len_args_from_cmdline+1);
125 }
126 strcat(args_from_cmdline, *argv);
127 strcat(args_from_cmdline, " ");
128 ++argv;
129 }
130 } 70 }
131 71
132 /* Set up some space for the command to be executed to be held in */
133 len_cmd_to_be_executed=10;
134 cmd_to_be_executed = xcalloc(len_cmd_to_be_executed, sizeof(char));
135 strcpy(cmd_to_be_executed, args_from_cmdline);
136 72
137 /* Now, read in one line at a time from stdin, and run command+args on it */ 73 /* Now, read in one line at a time from stdin, and stroe this to be used later
138 in_from_stdin = get_sh_safe_line_from_file(stdin); 74 * as an argument to the command we just stored */
75 in_from_stdin = get_line_from_file(stdin);
139 for (;in_from_stdin!=NULL;) { 76 for (;in_from_stdin!=NULL;) {
140 char *tmp; 77 char *tmp;
141 opt = strlen(in_from_stdin); 78 opt = strlen(in_from_stdin);
142 len = opt + len_args_from_cmdline; 79 len_args += opt + 3;
143 len_cmd_to_be_executed+=len+3; 80 args=xrealloc(args, len_args);
144 cmd_to_be_executed=xrealloc(cmd_to_be_executed, len_cmd_to_be_executed);
145 81
146 /* Strip out the final \n */ 82 /* Strip out the final \n */
147 in_from_stdin[opt-1]=' '; 83 in_from_stdin[opt-1]=' ';
148 84
85 /* Replace any tabs with spaces */
86 while( (tmp = strchr(in_from_stdin, '\t')) != NULL )
87 *tmp=' ';
88
89 /* Strip out any extra intra-word spaces */
90 while( (tmp = strstr(in_from_stdin, " ")) != NULL ) {
91 opt = strlen(in_from_stdin);
92 memmove(tmp, tmp+1, opt-(tmp-in_from_stdin));
93 }
94
149 /* trim trailing whitespace */ 95 /* trim trailing whitespace */
150 opt = strlen(in_from_stdin) - 1; 96 opt = strlen(in_from_stdin) - 1;
151 while (isspace(in_from_stdin[opt])) 97 while (isspace(in_from_stdin[opt]))
@@ -157,26 +103,49 @@ int xargs_main(int argc, char **argv)
157 while(isspace(*tmp)) 103 while(isspace(*tmp))
158 tmp++; 104 tmp++;
159 105
160 strcat(cmd_to_be_executed, tmp); 106 strcat(args, tmp);
161 strcat(cmd_to_be_executed, " "); 107 strcat(args, " ");
162 108
163 free(in_from_stdin); 109 free(in_from_stdin);
164 in_from_stdin = get_sh_safe_line_from_file(stdin); 110 in_from_stdin = get_line_from_file(stdin);
165 } 111 }
166 112
167 if (traceflag==1) 113 if (traceflag==1) {
168 fputs(cmd_to_be_executed, stderr); 114 fputs(cmd_to_be_executed, stderr);
115 fputs(args, stderr);
116 }
169 117
170 if ((system(cmd_to_be_executed) != 0) && (errno != 0)) 118 if ((pid = fork()) == 0) {
171 fatalError("%s", strerror(errno)); 119 char *cmd[255];
120 int i=1;
121
122 //printf("argv[0]='%s'\n", cmd_to_be_executed);
123 cmd[0] = cmd_to_be_executed;
124 while (--argc && ++argv && *argv ) {
125 //printf("argv[%d]='%s'\n", i, *argv);
126 cmd[i++]=*argv;
127 }
128 //printf("argv[%d]='%s'\n", i, args);
129 cmd[i++] = args;
130 cmd[i] = NULL;
131 execvp(cmd_to_be_executed, cmd);
132
133 /* What? Still here? Exit with an error */
134 fatalError("%s: %s\n", cmd_to_be_executed, strerror(errno));
135 }
136 /* Wait for a child process to exit */
137 wpid = wait(&status);
172 138
173 139
174#ifdef BB_FEATURE_CLEAN_UP 140#ifdef BB_FEATURE_CLEAN_UP
175 free(args_from_cmdline); 141 free(args);
176 free(cmd_to_be_executed); 142 free(cmd_to_be_executed);
177#endif 143#endif
178 144
179 return 0; 145 if (wpid > 0)
146 return (WEXITSTATUS(status));
147 else
148 return EXIT_FAILURE;
180} 149}
181/* 150/*
182Local Variables: 151Local Variables:
@@ -185,4 +154,3 @@ c-basic-offset: 4
185tab-width: 4 154tab-width: 4
186End: 155End:
187*/ 156*/
188
diff --git a/xargs.c b/xargs.c
index 21bfb6bbe..b8ac31aa0 100644
--- a/xargs.c
+++ b/xargs.c
@@ -28,68 +28,19 @@
28#include <errno.h> 28#include <errno.h>
29#include <getopt.h> 29#include <getopt.h>
30#include <ctype.h> 30#include <ctype.h>
31 31#include <sys/types.h>
32/* get_sh_safe_line_from_file() - This function reads an entire line from a text file 32#include <sys/wait.h>
33 * up to a newline. It returns a malloc'ed char * which must be stored and
34 * free'ed by the caller. */
35extern char *get_sh_safe_line_from_file(FILE *file)
36{
37 static const int GROWBY = 80; /* how large we will grow strings by */
38
39 char ch, last_ch = 0;
40 char tmp[]=" ";
41 int idx = 0;
42 char *linebuf = NULL;
43 int linebufsz = 0;
44
45 while (1) {
46 ch = fgetc(file);
47 if (ch == EOF)
48 break;
49
50 /* grow the line buffer as necessary */
51 while (idx > linebufsz-4)
52 linebuf = xrealloc(linebuf, linebufsz += GROWBY);
53
54 /* Remove any extra spaces */
55 if (last_ch == ' ' && ch == ' ')
56 continue;
57
58 /* Replace any tabs with spaces */
59 if (ch == '\t')
60 ch=' ';
61
62 /* Escape any characters that are treated specially by /bin/sh */
63 *tmp=ch;
64 if (strpbrk(tmp, "\\~`!$^&*()=|{}[];\"'<>?#") != NULL && last_ch!='\\') {
65 linebuf[idx++] = '\\';
66 }
67
68 linebuf[idx++] = ch;
69 last_ch=ch;
70
71 if (ch == '\n')
72 break;
73 }
74 if (idx == 0 && last_ch!=0)
75 linebuf[idx++]=' ';
76
77 if (idx == 0)
78 return NULL;
79
80 linebuf[idx] = 0;
81 return linebuf;
82}
83
84 33
85 34
86int xargs_main(int argc, char **argv) 35int xargs_main(int argc, char **argv)
87{ 36{
88 char *in_from_stdin = NULL; 37 char *in_from_stdin = NULL;
89 char *args_from_cmdline = NULL; 38 char *args = NULL;
90 char *cmd_to_be_executed = NULL; 39 char *cmd_to_be_executed = NULL;
91 char traceflag = 0; 40 char traceflag = 0;
92 int len_args_from_cmdline, len_cmd_to_be_executed, len, opt; 41 int len_args=10, len_cmd_to_be_executed, opt;
42 pid_t pid;
43 int wpid, status;
93 44
94 /* Note that we do not use getopt here, since 45 /* Note that we do not use getopt here, since
95 * we only want to interpret initial options, 46 * we only want to interpret initial options,
@@ -102,50 +53,45 @@ int xargs_main(int argc, char **argv)
102 break; 53 break;
103 default: 54 default:
104 fatalError(xargs_usage); 55 fatalError(xargs_usage);
105 } 56 }
106 } 57 }
107 } 58 }
108 59
109 /* Store the command and arguments to be executed (from the command line) */ 60 /* Store the command to be executed (taken from the command line) */
110 if (argc == 0) { 61 if (argc == 0) {
111 len_args_from_cmdline = 6; 62 len_cmd_to_be_executed=6;
112 args_from_cmdline = xmalloc(len_args_from_cmdline); 63 cmd_to_be_executed = xmalloc(len_cmd_to_be_executed);
113 strcat(args_from_cmdline, "echo "); 64 strcat(cmd_to_be_executed, "echo");
114 } else { 65 } else {
115 opt=strlen(*argv); 66 opt=strlen(*argv);
116 len_args_from_cmdline = (opt > 10)? opt : 10; 67 len_cmd_to_be_executed = (opt > 10)? opt : 10;
117 args_from_cmdline = xcalloc(len_args_from_cmdline, sizeof(char)); 68 cmd_to_be_executed = xcalloc(len_cmd_to_be_executed, sizeof(char));
118 while (argc-- > 0) { 69 strcat(cmd_to_be_executed, *argv);
119 if (strlen(*argv) + strlen(args_from_cmdline) >
120 len_args_from_cmdline) {
121 len_args_from_cmdline += strlen(*argv);
122 args_from_cmdline =
123 xrealloc(args_from_cmdline,
124 len_args_from_cmdline+1);
125 }
126 strcat(args_from_cmdline, *argv);
127 strcat(args_from_cmdline, " ");
128 ++argv;
129 }
130 } 70 }
131 71
132 /* Set up some space for the command to be executed to be held in */
133 len_cmd_to_be_executed=10;
134 cmd_to_be_executed = xcalloc(len_cmd_to_be_executed, sizeof(char));
135 strcpy(cmd_to_be_executed, args_from_cmdline);
136 72
137 /* Now, read in one line at a time from stdin, and run command+args on it */ 73 /* Now, read in one line at a time from stdin, and stroe this to be used later
138 in_from_stdin = get_sh_safe_line_from_file(stdin); 74 * as an argument to the command we just stored */
75 in_from_stdin = get_line_from_file(stdin);
139 for (;in_from_stdin!=NULL;) { 76 for (;in_from_stdin!=NULL;) {
140 char *tmp; 77 char *tmp;
141 opt = strlen(in_from_stdin); 78 opt = strlen(in_from_stdin);
142 len = opt + len_args_from_cmdline; 79 len_args += opt + 3;
143 len_cmd_to_be_executed+=len+3; 80 args=xrealloc(args, len_args);
144 cmd_to_be_executed=xrealloc(cmd_to_be_executed, len_cmd_to_be_executed);
145 81
146 /* Strip out the final \n */ 82 /* Strip out the final \n */
147 in_from_stdin[opt-1]=' '; 83 in_from_stdin[opt-1]=' ';
148 84
85 /* Replace any tabs with spaces */
86 while( (tmp = strchr(in_from_stdin, '\t')) != NULL )
87 *tmp=' ';
88
89 /* Strip out any extra intra-word spaces */
90 while( (tmp = strstr(in_from_stdin, " ")) != NULL ) {
91 opt = strlen(in_from_stdin);
92 memmove(tmp, tmp+1, opt-(tmp-in_from_stdin));
93 }
94
149 /* trim trailing whitespace */ 95 /* trim trailing whitespace */
150 opt = strlen(in_from_stdin) - 1; 96 opt = strlen(in_from_stdin) - 1;
151 while (isspace(in_from_stdin[opt])) 97 while (isspace(in_from_stdin[opt]))
@@ -157,26 +103,49 @@ int xargs_main(int argc, char **argv)
157 while(isspace(*tmp)) 103 while(isspace(*tmp))
158 tmp++; 104 tmp++;
159 105
160 strcat(cmd_to_be_executed, tmp); 106 strcat(args, tmp);
161 strcat(cmd_to_be_executed, " "); 107 strcat(args, " ");
162 108
163 free(in_from_stdin); 109 free(in_from_stdin);
164 in_from_stdin = get_sh_safe_line_from_file(stdin); 110 in_from_stdin = get_line_from_file(stdin);
165 } 111 }
166 112
167 if (traceflag==1) 113 if (traceflag==1) {
168 fputs(cmd_to_be_executed, stderr); 114 fputs(cmd_to_be_executed, stderr);
115 fputs(args, stderr);
116 }
169 117
170 if ((system(cmd_to_be_executed) != 0) && (errno != 0)) 118 if ((pid = fork()) == 0) {
171 fatalError("%s", strerror(errno)); 119 char *cmd[255];
120 int i=1;
121
122 //printf("argv[0]='%s'\n", cmd_to_be_executed);
123 cmd[0] = cmd_to_be_executed;
124 while (--argc && ++argv && *argv ) {
125 //printf("argv[%d]='%s'\n", i, *argv);
126 cmd[i++]=*argv;
127 }
128 //printf("argv[%d]='%s'\n", i, args);
129 cmd[i++] = args;
130 cmd[i] = NULL;
131 execvp(cmd_to_be_executed, cmd);
132
133 /* What? Still here? Exit with an error */
134 fatalError("%s: %s\n", cmd_to_be_executed, strerror(errno));
135 }
136 /* Wait for a child process to exit */
137 wpid = wait(&status);
172 138
173 139
174#ifdef BB_FEATURE_CLEAN_UP 140#ifdef BB_FEATURE_CLEAN_UP
175 free(args_from_cmdline); 141 free(args);
176 free(cmd_to_be_executed); 142 free(cmd_to_be_executed);
177#endif 143#endif
178 144
179 return 0; 145 if (wpid > 0)
146 return (WEXITSTATUS(status));
147 else
148 return EXIT_FAILURE;
180} 149}
181/* 150/*
182Local Variables: 151Local Variables:
@@ -185,4 +154,3 @@ c-basic-offset: 4
185tab-width: 4 154tab-width: 4
186End: 155End:
187*/ 156*/
188