mm(1): interpret retvals
This commit is contained in:
parent
a7b27f0d6a
commit
7e347bebdf
83
src/mm.c
83
src/mm.c
@ -82,8 +82,7 @@ Files_append(struct Files *files, FILE *file, char *name) {
|
|||||||
* appropriate for an OS error. */
|
* appropriate for an OS error. */
|
||||||
static int
|
static int
|
||||||
oserr(char *s, char *r) {
|
oserr(char *s, char *r) {
|
||||||
|
(void)fprintf(stderr, "%s: %s: %s\n", s, r, strerror(errno));
|
||||||
fprintf(stderr, "%s: %s: %s\n", s, r, strerror(errno));
|
|
||||||
|
|
||||||
return EX_OSERR;
|
return EX_OSERR;
|
||||||
}
|
}
|
||||||
@ -100,11 +99,7 @@ usage(char *argv0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int c;
|
|
||||||
struct Files files[2]; /* {read, write} */
|
struct Files files[2]; /* {read, write} */
|
||||||
size_t i;
|
|
||||||
size_t j;
|
|
||||||
size_t k; /* loop index but also unbuffer status */
|
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
/* Initializes the files structs with their default values, standard
|
/* Initializes the files structs with their default values, standard
|
||||||
@ -112,39 +107,41 @@ int main(int argc, char *argv[]) {
|
|||||||
* these initial values will be overwritten, so to, say, use mm(1)
|
* these initial values will be overwritten, so to, say, use mm(1)
|
||||||
* equivalently to tee(1p), -o - will need to be specified before
|
* equivalently to tee(1p), -o - will need to be specified before
|
||||||
* additional files to ensure standard output is still written. */
|
* additional files to ensure standard output is still written. */
|
||||||
for (i = 0; i < 2; ++i) {
|
for (size_t i = 0; i < 2; ++i) {
|
||||||
files[i].a = 0;
|
files[i].a = 0;
|
||||||
files[i].s = 0;
|
files[i].s = 0;
|
||||||
files[i].mode = fmode[i];
|
files[i].mode = fmode[i];
|
||||||
files[i].files = NULL;
|
files[i].files = NULL;
|
||||||
files[i].names = NULL;
|
files[i].names = NULL;
|
||||||
|
|
||||||
Files_append(
|
if (Files_append(
|
||||||
&files[i],
|
&files[i],
|
||||||
i == 0 ? stdin : stdout,
|
i == 0 ? stdin : stdout,
|
||||||
i == 0 ? stdin_name : stdout_name
|
i == 0 ? stdin_name : stdout_name
|
||||||
);
|
) == NULL) {
|
||||||
|
return oserr(program_name, i == 0 ? stdin_name : stdout_name);
|
||||||
|
}
|
||||||
|
|
||||||
files[i].s = 0;
|
files[i].s = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
k = 0;
|
|
||||||
|
|
||||||
if (argc > 0) {
|
if (argc > 0) {
|
||||||
|
int c;
|
||||||
|
char unbuffered = 0;
|
||||||
|
|
||||||
program_name = argv[0];
|
program_name = argv[0];
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "aehi:no:u")) != -1) {
|
while ((c = getopt(argc, argv, "aehi:no:u")) != -1) {
|
||||||
switch (c){
|
switch (c) {
|
||||||
case 'a': /* "rb+" -> "ab" */
|
case 'a': /* "rb+" -> "ab" */
|
||||||
files[1].mode[0] = 'a';
|
files[1].mode[0] = 'a';
|
||||||
files[1].mode[2] = '\0';
|
files[1].mode[2] = '\0';
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
if (Files_append(&files[1], stderr, stderr_name) != NULL) {
|
if (Files_append(&files[1], stderr, stderr_name) == NULL) {
|
||||||
break;
|
return oserr(program_name, stderr_name);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
return oserr(program_name, "-e");
|
|
||||||
case 'i':
|
case 'i':
|
||||||
if (
|
if (
|
||||||
(strcmp(optarg, "-") == 0
|
(strcmp(optarg, "-") == 0
|
||||||
@ -171,16 +168,28 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
return oserr(program_name, optarg);
|
return oserr(program_name, optarg);
|
||||||
case 'n':
|
case 'n':
|
||||||
if (signal(SIGINT, SIG_IGN) != SIG_ERR) { break; }
|
if (signal(SIGINT, SIG_IGN) == SIG_ERR) {
|
||||||
|
return oserr(program_name, "-n");
|
||||||
|
}
|
||||||
|
|
||||||
return oserr(program_name, "-n");
|
|
||||||
case 'u':
|
|
||||||
k = 1;
|
|
||||||
break;
|
break;
|
||||||
default:
|
case 'u': unbuffered = 1; break;
|
||||||
return usage(program_name);
|
default: return usage(program_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (unbuffered) { /* Unbuffer files. */
|
||||||
|
for (
|
||||||
|
size_t i = 0;
|
||||||
|
i < files[0].s;
|
||||||
|
setvbuf(files[0].files[i++], NULL, _IONBF, 0)
|
||||||
|
);
|
||||||
|
for (
|
||||||
|
size_t i = 0;
|
||||||
|
i < files[1].s;
|
||||||
|
setvbuf(files[1].files[i++], NULL, _IONBF, 0)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind != argc) { return usage(program_name); }
|
if (optind != argc) { return usage(program_name); }
|
||||||
@ -188,26 +197,18 @@ int main(int argc, char *argv[]) {
|
|||||||
files[0].s += files[0].s == 0;
|
files[0].s += files[0].s == 0;
|
||||||
files[1].s += files[1].s == 0;
|
files[1].s += files[1].s == 0;
|
||||||
|
|
||||||
/* Unbuffer files. */
|
|
||||||
if (k) {
|
|
||||||
for (
|
|
||||||
i = 0; i < files[0].s; setvbuf(files[0].files[i++], NULL, _IONBF, 0)
|
|
||||||
);
|
|
||||||
for (
|
|
||||||
i = 0; i < files[1].s; setvbuf(files[1].files[i++], NULL, _IONBF, 0)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
retval = EX_OK;
|
retval = EX_OK;
|
||||||
|
|
||||||
/* Actual program loop. */
|
/* Actual program loop. */
|
||||||
for (i = 0; i < files[0].s; ++i) { /* iterate ins */
|
for (size_t i = 0; i < files[0].s; ++i) { /* iterate ins */
|
||||||
|
int c;
|
||||||
|
|
||||||
while ((c = getc(files[0].files[i])) != EOF) { /* iterate chars */
|
while ((c = getc(files[0].files[i])) != EOF) { /* iterate chars */
|
||||||
for (j = 0; j < files[1].s; ++j) { /* iterate outs */
|
for (size_t j = 0; j < files[1].s; ++j) { /* iterate outs */
|
||||||
if (putc(c, files[1].files[j]) == EOF) {
|
if (putc(c, files[1].files[j]) == EOF) { /* notebook's full */
|
||||||
/* notebook's full */
|
|
||||||
retval = EX_IOERR;
|
retval = EX_IOERR;
|
||||||
fprintf(
|
(void)fprintf(
|
||||||
stderr,
|
stderr,
|
||||||
"%s: %s: %s\n",
|
"%s: %s: %s\n",
|
||||||
program_name,
|
program_name,
|
||||||
@ -216,7 +217,7 @@ int main(int argc, char *argv[]) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (fclose(files[1].files[j]) == EOF) {
|
if (fclose(files[1].files[j]) == EOF) {
|
||||||
fprintf(
|
(void)fprintf(
|
||||||
stderr,
|
stderr,
|
||||||
"%s: %s: %s\n",
|
"%s: %s: %s\n",
|
||||||
program_name,
|
program_name,
|
||||||
@ -226,7 +227,7 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* massage out the tense muscle */
|
/* massage out the tense muscle */
|
||||||
for(k = j--; k < files[1].s - 1; ++k){
|
for(size_t k = j--; k < files[1].s - 1; ++k){
|
||||||
files[1].files[k] = files[1].files[k+1];
|
files[1].files[k] = files[1].files[k+1];
|
||||||
files[1].names[k] = files[1].names[k+1];
|
files[1].names[k] = files[1].names[k+1];
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user