fixed xargs/grep
This commit is contained in:
parent
577f8312d7
commit
db62ddffc1
|
@ -108,7 +108,7 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
char *val = strchr(arg, '=');
|
char *val = strchr(arg, '=');
|
||||||
if (val == NULL) {
|
if (val == NULL) {
|
||||||
printf("dd\n\tif=InputFile\n\tof=OutputFile\n\tbs=obs and obs\n\tibs=Input buffer size\n\tobs=Output buffer size\n\tseek=Skip N obs-sized output blocks\n\tskip=Skip N ibs-sized output blocks\n\tcount=Copy only N input blocks\n\nN and BYTES may be followed by the following multiplicative\nsuffixes: w=2, b=512, k=1000, K=1024, m=1000*1000,\nM=1024*1024, g=1000*1000*1000, G=1024*1024*1024\n");
|
printf("dd\n\tif=InputFile\n\tof=OutputFile\n\tbs=ibs and obs\n\tibs=Input buffer size\n\tobs=Output buffer size\n\tseek=Skip N obs-sized output blocks\n\tskip=Skip N ibs-sized output blocks\n\tcount=Copy only N input blocks\n\nN and BYTES may be followed by the following multiplicative\nsuffixes: w=2, b=512, k=1000, K=1024, m=1000*1000,\nM=1024*1024, g=1000*1000*1000, G=1024*1024*1024\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,29 @@ typedef struct {
|
||||||
char *pattern;
|
char *pattern;
|
||||||
regex_t rgex;
|
regex_t rgex;
|
||||||
} PATTERN;
|
} PATTERN;
|
||||||
|
PATTERN *regexs;
|
||||||
|
size_t r_size;
|
||||||
|
|
||||||
|
int addpattern(char *str) {
|
||||||
|
if (regexs == NULL) {
|
||||||
|
regexs = malloc(sizeof(PATTERN));
|
||||||
|
if (regexs == NULL) {
|
||||||
|
fprintf(stderr, "grep: malloc failed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
regexs = realloc(regexs, (r_size + 1) * sizeof(PATTERN));
|
||||||
|
if (regexs == NULL) {
|
||||||
|
fprintf(stderr, "grep: malloc failed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
regexs[r_size].pattern = str;
|
||||||
|
|
||||||
|
r_size++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
@ -15,16 +38,25 @@ int main(int argc, char **argv) {
|
||||||
while ((opt = getopt(argc, argv, "e:")) != -1) {
|
while ((opt = getopt(argc, argv, "e:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'e':
|
case 'e':
|
||||||
addpattern(optarg);
|
if (addpattern(optarg))
|
||||||
|
return 1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("grep [e] [PATTERN | -e PATTERN]\n");
|
printf("grep [e] [PATTERN | -e PATTERN] [FILE]\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
argv += optind;
|
argv += optind;
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
|
if (r_size == 0) {
|
||||||
|
fprintf(stderr, "grep: no patterns specified\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(regexs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,21 @@
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
int t_flag;
|
char t_flag;
|
||||||
|
char r_flag;
|
||||||
int n_flag;
|
int n_flag;
|
||||||
int s_flag;
|
int s_flag;
|
||||||
int r_flag;
|
int P_flag;
|
||||||
|
int P_flag2;
|
||||||
|
|
||||||
int args;
|
int args;
|
||||||
char *cmd[NARGS + 1];
|
char *cmd[NARGS + 1];
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NONE,
|
||||||
|
QUOTE
|
||||||
|
};
|
||||||
|
|
||||||
void clear_cmd(void) {
|
void clear_cmd(void) {
|
||||||
for (int i = 0; i < args; i++)
|
for (int i = 0; i < args; i++)
|
||||||
if (cmd[i] != NULL)
|
if (cmd[i] != NULL)
|
||||||
|
@ -44,19 +51,30 @@ int stdin_read(void) {
|
||||||
|
|
||||||
/* Word start */
|
/* Word start */
|
||||||
char *p = arg;
|
char *p = arg;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
int chars = 0;
|
int chars = 0;
|
||||||
|
|
||||||
int args_passed = 0;
|
int args_passed = 0;
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
char flag = NONE;
|
||||||
while (1) {
|
while (1) {
|
||||||
int c = getchar();
|
int c = getchar();
|
||||||
if (c == EOF) {
|
if (c == EOF) {
|
||||||
ret = 2;
|
if (flag == QUOTE) {
|
||||||
|
fprintf(stderr, "xargs: unterminated double quote\n");
|
||||||
|
ret = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p != arg)
|
||||||
|
goto PUSH;
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((isspace(c)) && strlen(arg) > 0) {
|
/* Place str */
|
||||||
|
else if ((flag == NONE && isspace(c) && strlen(arg) > 0) || p + 1 == arg + sizeof(arg)) {
|
||||||
|
PUSH:
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
p = arg;
|
p = arg;
|
||||||
|
|
||||||
|
@ -66,13 +84,21 @@ int stdin_read(void) {
|
||||||
args_passed++;
|
args_passed++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add char to str */
|
||||||
else {
|
else {
|
||||||
if (c == '\\')
|
if (c == '"' || c == '\'') {
|
||||||
c = getchar();
|
if (flag == QUOTE)
|
||||||
|
flag = NONE;
|
||||||
|
|
||||||
|
else
|
||||||
|
flag = QUOTE;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
*p = c;
|
*p = c;
|
||||||
if (p + 1 == arg + sizeof(arg))
|
if (p + 1 == arg + sizeof(arg))
|
||||||
break;
|
continue;
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
chars++;
|
chars++;
|
||||||
|
@ -102,13 +128,34 @@ int run(void) {
|
||||||
|
|
||||||
int status = 0;
|
int status = 0;
|
||||||
waitpid(pid, &status, 0);
|
waitpid(pid, &status, 0);
|
||||||
|
|
||||||
|
if (status == 255)
|
||||||
|
status = 124;
|
||||||
|
|
||||||
|
else if (status >= 0x180)
|
||||||
|
status = 125;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int spawn(void) {
|
||||||
|
if (P_flag == 0)
|
||||||
|
return run();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void check(int val) {
|
||||||
|
if (val <= 0) {
|
||||||
|
fprintf(stderr, "xargs: invalid number: %s\n", optarg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
int opt;
|
int opt;
|
||||||
while ((opt = getopt(argc, argv, "tn:s:r")) != -1) {
|
while ((opt = getopt(argc, argv, "tn:s:rP:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 't':
|
case 't':
|
||||||
t_flag = 1;
|
t_flag = 1;
|
||||||
|
@ -116,18 +163,25 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
n_flag = atoi(optarg);
|
n_flag = atoi(optarg);
|
||||||
|
check(n_flag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
s_flag = atoi(optarg);
|
s_flag = atoi(optarg);
|
||||||
|
check(s_flag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
r_flag = 1;
|
r_flag = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'P':
|
||||||
|
P_flag = atoi(optarg);
|
||||||
|
check(P_flag);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("xargs [tnsr] [cmd [arg1] [arg2...]]\n\t-t Print the command\n\t-n Pass no more than N args\n\t-r Don't run command if input is empty\n\t-s Pass command line of no more than N bytes\n");
|
printf("xargs [tnsr] [cmd [arg1] [arg2...]\n\t-t Print the command before start\n\t-n Pass no more than N args\n\t-r Don't run command if input is empty\n\t-s Pass command line of no more than N bytes\n\t-P Run up to N PROGs in parallel\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,11 +217,11 @@ int main(int argc, char **argv) {
|
||||||
/* Run */
|
/* Run */
|
||||||
if (stdin_stat == 1) {
|
if (stdin_stat == 1) {
|
||||||
if (!r_flag)
|
if (!r_flag)
|
||||||
ret = run();
|
ret = spawn();
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else if (stdin_stat == 0)
|
||||||
ret = run();
|
ret = spawn();
|
||||||
|
|
||||||
/* Clear */
|
/* Clear */
|
||||||
clear_cmd();
|
clear_cmd();
|
||||||
|
|
Loading…
Reference in New Issue