xargs add

This commit is contained in:
Your Name 2023-12-06 18:26:26 +03:00
parent 1d0433f9c2
commit 6fd63c6dfb
3 changed files with 117 additions and 38 deletions

3
TODO
View File

@ -54,8 +54,7 @@ Modutils (linux only):
Findutils:
grep
find
*xargs (stdin)
*xargs (-r flag)
Shell:
rc - run command (1 2 3 ~ | <> <<>> & * " parsing) (sig handler)

View File

@ -10,7 +10,7 @@
/* format for printf (head) */
#define HEAD_FMT "==> %s <==\n"
/* block size (du)*/
/* block size (du) */
#define BLK_SIZE 512
/* mount config */
@ -29,8 +29,11 @@
/* RunComm prompt */
#define RC_PS "> "
/* Args count (xargs) */
#define NARGS 10000
/* Max args (xargs) */
#define NARGS 1024
#define ARG_SIZE 1024
/* Default cmd (xargs) */
#define ECHO_CMD "echo"
/* Options: To disable, comment line */

View File

@ -3,34 +3,81 @@
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/wait.h>
#include "config.h"
unsigned int t_flag;
int t_flag;
int n_flag;
int r_flag;
char *cmd[NARGS + 1];
int args;
void clear_cmd(int count) {
if (count < 1)
return;
void clear_cmd(void) {
for (int i = 0; i < args; i++)
if (cmd[i] != NULL)
free(cmd[i]);
for (int i = 0; i < count; i++)
free(cmd[i]);
args = 0;
}
char *estrdup(const char *arg, int i) {
char *val = strdup(arg);
if (!val) {
clear_cmd(i - 1);
fprintf(stderr, "xargs: %s\n", strerror(errno));
return NULL;
int add_arg(const char *str) {
if (args >= NARGS)
return 1;
else if (n_flag > 0 && args >= n_flag)
return 1;
cmd[args] = strdup(str);
args++;
return 0;
}
int stdin_read(void) {
char arg[ARG_SIZE + 1];
/* Word start */
char *p = arg;
int run = 1;
int c = 0;
while ((c = getchar()) != EOF && run) {
switch (c) {
case '\t':
case '\n':
case ' ':
*p = '\0';
p = arg;
if (add_arg(arg))
run = 0;
break;
default:
*p = c;
if (p + 1 == arg + sizeof(arg))
run = 0;
else
p++;
break;
}
}
return val;
if (getchar() == EOF)
return 1;
return 0;
}
int run(int count) {
int run(void) {
if (t_flag) {
for (int i = 0; i < count; i++)
for (int i = 0; i < args; i++)
fprintf(stderr, "%s ", cmd[i]);
fputc('\n', stderr);
@ -38,7 +85,7 @@ int run(int count) {
pid_t pid;
if ((pid = fork()) == 0) {
execvp(*cmd, cmd);
execvp(cmd[0], cmd);
fprintf(stderr, "xargs: %s\n", strerror(errno));
exit(1);
}
@ -50,14 +97,27 @@ int run(int count) {
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "t")) != -1) {
while ((opt = getopt(argc, argv, "tn:r")) != -1) {
switch (opt) {
case 't':
t_flag = 1;
break;
case 'n':
n_flag = atoi(optarg);
if (n_flag < 1) {
fprintf(stderr, "xargs: n cant be < 0\n");
return 1;
}
break;
case 'r':
r_flag = 1;
break;
default:
printf("xargs [cmd] [arg1] [arg2]\n\t[-t Print the command on stderr before execution]\n");
printf("xargs [cmd [arg1] [arg2...]]\n\t[-t Print the command]\n\t[-n Pass no more than N args]\n\t[TODO -r Don't run command if input is empty]\n");
return 0;
}
}
@ -65,22 +125,39 @@ int main(int argc, char **argv) {
argv += optind;
argc -= optind;
/* Argv */
int i = 0;
if (argc) {
for (i = 0; i < argc; i++)
if (i < NARGS)
cmd[i] = estrdup(argv[i], i);
int ret = 0;
while (1) {
/* Arg */
if (argc) {
for (int i = 0; i < argc; i++)
if (add_arg(argv[i]))
break;
}
else
add_arg(ECHO_CMD);
/* Stdin */
int stdin_stat = stdin_read();
/* Check NULL */
for (int i = 0; i < args; i++) {
if (cmd[i] == NULL) {
fprintf(stderr, "xargs: strdup failed\n");
clear_cmd();
return 1;
}
}
/* Run */
if (run())
ret = 1;
/* Clear */
clear_cmd();
if (stdin_stat)
break;
}
else {
cmd[0] = estrdup(ECHO_CMD, 0);
i++;
}
/* Stdin */
int ret = run(i);
clear_cmd(i);
return ret;
}