fixed xargs/grep

This commit is contained in:
Your Name 2024-03-31 16:45:49 +03:00
parent 577f8312d7
commit db62ddffc1
3 changed files with 103 additions and 17 deletions

View File

@ -108,7 +108,7 @@ int main(int argc, char **argv) {
char *val = strchr(arg, '=');
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;
}

View File

@ -8,6 +8,29 @@ typedef struct {
char *pattern;
regex_t rgex;
} 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) {
@ -15,16 +38,25 @@ int main(int argc, char **argv) {
while ((opt = getopt(argc, argv, "e:")) != -1) {
switch (opt) {
case 'e':
addpattern(optarg);
if (addpattern(optarg))
return 1;
break;
default:
printf("grep [e] [PATTERN | -e PATTERN]\n");
printf("grep [e] [PATTERN | -e PATTERN] [FILE]\n");
return 0;
}
}
argv += optind;
argc -= optind;
if (r_size == 0) {
fprintf(stderr, "grep: no patterns specified\n");
return 1;
}
free(regexs);
return 0;
}

View File

@ -7,14 +7,21 @@
#include <sys/wait.h>
#include "config.h"
int t_flag;
char t_flag;
char r_flag;
int n_flag;
int s_flag;
int r_flag;
int P_flag;
int P_flag2;
int args;
char *cmd[NARGS + 1];
enum {
NONE,
QUOTE
};
void clear_cmd(void) {
for (int i = 0; i < args; i++)
if (cmd[i] != NULL)
@ -44,19 +51,30 @@ int stdin_read(void) {
/* Word start */
char *p = arg;
int ret = 0;
int chars = 0;
int args_passed = 0;
int ret = 0;
char flag = NONE;
while (1) {
int c = getchar();
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;
}
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 = arg;
@ -66,13 +84,21 @@ int stdin_read(void) {
args_passed++;
}
/* Add char to str */
else {
if (c == '\\')
c = getchar();
if (c == '"' || c == '\'') {
if (flag == QUOTE)
flag = NONE;
else
flag = QUOTE;
continue;
}
*p = c;
if (p + 1 == arg + sizeof(arg))
break;
continue;
p++;
chars++;
@ -102,13 +128,34 @@ int run(void) {
int status = 0;
waitpid(pid, &status, 0);
if (status == 255)
status = 124;
else if (status >= 0x180)
status = 125;
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 opt;
while ((opt = getopt(argc, argv, "tn:s:r")) != -1) {
while ((opt = getopt(argc, argv, "tn:s:rP:")) != -1) {
switch (opt) {
case 't':
t_flag = 1;
@ -116,18 +163,25 @@ int main(int argc, char **argv) {
case 'n':
n_flag = atoi(optarg);
check(n_flag);
break;
case 's':
s_flag = atoi(optarg);
check(s_flag);
break;
case 'r':
r_flag = 1;
break;
case 'P':
P_flag = atoi(optarg);
check(P_flag);
break;
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;
}
}
@ -163,11 +217,11 @@ int main(int argc, char **argv) {
/* Run */
if (stdin_stat == 1) {
if (!r_flag)
ret = run();
ret = spawn();
}
else
ret = run();
else if (stdin_stat == 0)
ret = spawn();
/* Clear */
clear_cmd();