mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-28 08:14:24 +02:00
- [OVERVIEW README] typos; green@freebsd
- [ssh-keygen.c] replace xstrdup+strcat with strlcat+fixed buffer, fixes OF (bad me) exit if writing the key fails (no infinit loop) print usage() everytime we get bad options - [ssh-keygen.c] overflow, djm@mindrot.org - [sshd.c] fix sigchld race; cjc5@po.cwru.edu
This commit is contained in:
parent
6162d1215b
commit
431f66b68c
@ -15,7 +15,14 @@
|
|||||||
[channels.c clientloop.c]
|
[channels.c clientloop.c]
|
||||||
SSH_CMSG_MAX_PACKET_SIZE, some clients use this, some need this, niels@
|
SSH_CMSG_MAX_PACKET_SIZE, some clients use this, some need this, niels@
|
||||||
[hope this time my ISP stays alive during commit]
|
[hope this time my ISP stays alive during commit]
|
||||||
|
- [OVERVIEW README] typos; green@freebsd
|
||||||
|
- [ssh-keygen.c]
|
||||||
|
replace xstrdup+strcat with strlcat+fixed buffer, fixes OF (bad me)
|
||||||
|
exit if writing the key fails (no infinit loop)
|
||||||
|
print usage() everytime we get bad options
|
||||||
|
- [ssh-keygen.c] overflow, djm@mindrot.org
|
||||||
|
- [sshd.c] fix sigchld race; cjc5@po.cwru.edu
|
||||||
|
|
||||||
19991120
|
19991120
|
||||||
- Merged more Solaris support from Marc G. Fournier
|
- Merged more Solaris support from Marc G. Fournier
|
||||||
<marc.fournier@acadiau.ca>
|
<marc.fournier@acadiau.ca>
|
||||||
|
2
OVERVIEW
2
OVERVIEW
@ -1,4 +1,4 @@
|
|||||||
This document is inteded for those who wish to read the ssh source
|
This document is intended for those who wish to read the ssh source
|
||||||
code. This tries to give an overview of the structure of the code.
|
code. This tries to give an overview of the structure of the code.
|
||||||
|
|
||||||
Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>
|
Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
|
158
ssh-keygen.c
158
ssh-keygen.c
@ -14,7 +14,7 @@ Identity and host key generation and maintenance.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$Id: ssh-keygen.c,v 1.6 1999/11/20 06:02:56 damien Exp $");
|
RCSID("$Id: ssh-keygen.c,v 1.7 1999/11/21 07:31:57 damien Exp $");
|
||||||
|
|
||||||
#include "rsa.h"
|
#include "rsa.h"
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
@ -50,8 +50,9 @@ int quiet = 0;
|
|||||||
/* Flag indicating that we just want to see the key fingerprint */
|
/* Flag indicating that we just want to see the key fingerprint */
|
||||||
int print_fingerprint = 0;
|
int print_fingerprint = 0;
|
||||||
|
|
||||||
/* This is set to the identity file name if given on the command line. */
|
/* The identity file name, given on the command line or entered by the user. */
|
||||||
char *identity_file = NULL;
|
char identity_file[1024];
|
||||||
|
int have_identity = 0;
|
||||||
|
|
||||||
/* This is set to the passphrase if given on the command line. */
|
/* This is set to the passphrase if given on the command line. */
|
||||||
char *identity_passphrase = NULL;
|
char *identity_passphrase = NULL;
|
||||||
@ -62,51 +63,46 @@ char *identity_new_passphrase = NULL;
|
|||||||
/* This is set to the new comment if given on the command line. */
|
/* This is set to the new comment if given on the command line. */
|
||||||
char *identity_comment = NULL;
|
char *identity_comment = NULL;
|
||||||
|
|
||||||
/* Perform changing a passphrase. The argument is the passwd structure
|
/* argv0 */
|
||||||
for the current user. */
|
extern char *__progname;
|
||||||
|
|
||||||
char *
|
void
|
||||||
get_filename(struct passwd *pw, const char *prompt)
|
ask_filename(struct passwd *pw, const char *prompt)
|
||||||
{
|
{
|
||||||
char buf[1024], default_file[1024];
|
char buf[1024];
|
||||||
|
snprintf(identity_file, sizeof(identity_file), "%s/%s",
|
||||||
/* Read key file name. */
|
pw->pw_dir, SSH_CLIENT_IDENTITY);
|
||||||
if (identity_file != NULL) {
|
printf("%s (%s): ", prompt, identity_file);
|
||||||
return xstrdup(identity_file);
|
fflush(stdout);
|
||||||
} else {
|
if (fgets(buf, sizeof(buf), stdin) == NULL)
|
||||||
snprintf(default_file, sizeof default_file, "%s/%s",
|
exit(1);
|
||||||
pw->pw_dir, SSH_CLIENT_IDENTITY);
|
if (strchr(buf, '\n'))
|
||||||
printf("%s (%s): ", prompt, default_file);
|
*strchr(buf, '\n') = 0;
|
||||||
fflush(stdout);
|
if (strcmp(buf, "") != 0)
|
||||||
if (fgets(buf, sizeof(buf), stdin) == NULL)
|
strlcpy(identity_file, buf, sizeof(identity_file));
|
||||||
exit(1);
|
have_identity = 1;
|
||||||
if (strchr(buf, '\n'))
|
|
||||||
*strchr(buf, '\n') = 0;
|
|
||||||
if (strcmp(buf, "") == 0)
|
|
||||||
return xstrdup(default_file);
|
|
||||||
}
|
|
||||||
return xstrdup(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
do_fingerprint(struct passwd *pw)
|
do_fingerprint(struct passwd *pw)
|
||||||
{
|
{
|
||||||
char *file, *comment;
|
char *comment;
|
||||||
RSA *public_key;
|
RSA *public_key;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
file = get_filename(pw, "Enter file in which the key is");
|
if (!have_identity)
|
||||||
if (stat(file, &st) < 0)
|
ask_filename(pw, "Enter file in which the key is");
|
||||||
|
if (stat(identity_file, &st) < 0)
|
||||||
{
|
{
|
||||||
perror(file);
|
perror(identity_file);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
public_key = RSA_new();
|
public_key = RSA_new();
|
||||||
if (!load_public_key(file, public_key, &comment)) {
|
if (!load_public_key(identity_file, public_key, &comment)) {
|
||||||
char *cp, line[1024];
|
char *cp, line[1024];
|
||||||
BIGNUM *e, *n;
|
BIGNUM *e, *n;
|
||||||
int dummy, invalid = 0;
|
int dummy, invalid = 0;
|
||||||
FILE *f = fopen(file, "r");
|
FILE *f = fopen(identity_file, "r");
|
||||||
n = BN_new();
|
n = BN_new();
|
||||||
e = BN_new();
|
e = BN_new();
|
||||||
if (f && fgets(line, sizeof(line), f)) {
|
if (f && fgets(line, sizeof(line), f)) {
|
||||||
@ -123,7 +119,7 @@ do_fingerprint(struct passwd *pw)
|
|||||||
invalid = 1;
|
invalid = 1;
|
||||||
}
|
}
|
||||||
if (invalid) {
|
if (invalid) {
|
||||||
printf("%s is not a valid key file.\n", file);
|
printf("%s is not a valid key file.\n", identity_file);
|
||||||
BN_free(e);
|
BN_free(e);
|
||||||
BN_free(n);
|
BN_free(n);
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -137,29 +133,32 @@ do_fingerprint(struct passwd *pw)
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Perform changing a passphrase. The argument is the passwd structure
|
||||||
|
for the current user. */
|
||||||
|
|
||||||
void
|
void
|
||||||
do_change_passphrase(struct passwd *pw)
|
do_change_passphrase(struct passwd *pw)
|
||||||
{
|
{
|
||||||
char *file, *comment;
|
char *comment;
|
||||||
char *old_passphrase, *passphrase1, *passphrase2;
|
char *old_passphrase, *passphrase1, *passphrase2;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
RSA *private_key;
|
RSA *private_key;
|
||||||
|
|
||||||
file = get_filename(pw, "Enter file in which the key is");
|
if (!have_identity)
|
||||||
|
ask_filename(pw, "Enter file in which the key is");
|
||||||
/* Check if the file exists. */
|
/* Check if the file exists. */
|
||||||
if (stat(file, &st) < 0)
|
if (stat(identity_file, &st) < 0)
|
||||||
{
|
{
|
||||||
perror(file);
|
perror(identity_file);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to load the public key from the file the verify that it is
|
/* Try to load the public key from the file the verify that it is
|
||||||
readable and of the proper format. */
|
readable and of the proper format. */
|
||||||
public_key = RSA_new();
|
public_key = RSA_new();
|
||||||
if (!load_public_key(file, public_key, NULL))
|
if (!load_public_key(identity_file, public_key, NULL))
|
||||||
{
|
{
|
||||||
printf("%s is not a valid key file.\n", file);
|
printf("%s is not a valid key file.\n", identity_file);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
/* Clear the public key since we are just about to load the whole file. */
|
/* Clear the public key since we are just about to load the whole file. */
|
||||||
@ -167,14 +166,14 @@ do_change_passphrase(struct passwd *pw)
|
|||||||
|
|
||||||
/* Try to load the file with empty passphrase. */
|
/* Try to load the file with empty passphrase. */
|
||||||
private_key = RSA_new();
|
private_key = RSA_new();
|
||||||
if (!load_private_key(file, "", private_key, &comment)) {
|
if (!load_private_key(identity_file, "", private_key, &comment)) {
|
||||||
/* Read passphrase from the user. */
|
/* Read passphrase from the user. */
|
||||||
if (identity_passphrase)
|
if (identity_passphrase)
|
||||||
old_passphrase = xstrdup(identity_passphrase);
|
old_passphrase = xstrdup(identity_passphrase);
|
||||||
else
|
else
|
||||||
old_passphrase = read_passphrase("Enter old passphrase: ", 1);
|
old_passphrase = read_passphrase("Enter old passphrase: ", 1);
|
||||||
/* Try to load using the passphrase. */
|
/* Try to load using the passphrase. */
|
||||||
if (!load_private_key(file, old_passphrase, private_key, &comment))
|
if (!load_private_key(identity_file, old_passphrase, private_key, &comment))
|
||||||
{
|
{
|
||||||
memset(old_passphrase, 0, strlen(old_passphrase));
|
memset(old_passphrase, 0, strlen(old_passphrase));
|
||||||
xfree(old_passphrase);
|
xfree(old_passphrase);
|
||||||
@ -215,10 +214,10 @@ do_change_passphrase(struct passwd *pw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Save the file using the new passphrase. */
|
/* Save the file using the new passphrase. */
|
||||||
if (!save_private_key(file, passphrase1, private_key, comment))
|
if (!save_private_key(identity_file, passphrase1, private_key, comment))
|
||||||
{
|
{
|
||||||
printf("Saving the key failed: %s: %s.\n",
|
printf("Saving the key failed: %s: %s.\n",
|
||||||
file, strerror(errno));
|
identity_file, strerror(errno));
|
||||||
memset(passphrase1, 0, strlen(passphrase1));
|
memset(passphrase1, 0, strlen(passphrase1));
|
||||||
xfree(passphrase1);
|
xfree(passphrase1);
|
||||||
RSA_free(private_key);
|
RSA_free(private_key);
|
||||||
@ -240,33 +239,34 @@ do_change_passphrase(struct passwd *pw)
|
|||||||
void
|
void
|
||||||
do_change_comment(struct passwd *pw)
|
do_change_comment(struct passwd *pw)
|
||||||
{
|
{
|
||||||
char new_comment[1024], *file, *comment;
|
char new_comment[1024], *comment;
|
||||||
RSA *private_key;
|
RSA *private_key;
|
||||||
char *passphrase;
|
char *passphrase;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char *tmpbuf;
|
char *tmpbuf;
|
||||||
|
|
||||||
file = get_filename(pw, "Enter file in which the key is");
|
if (!have_identity)
|
||||||
|
ask_filename(pw, "Enter file in which the key is");
|
||||||
/* Check if the file exists. */
|
/* Check if the file exists. */
|
||||||
if (stat(file, &st) < 0)
|
if (stat(identity_file, &st) < 0)
|
||||||
{
|
{
|
||||||
perror(file);
|
perror(identity_file);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to load the public key from the file the verify that it is
|
/* Try to load the public key from the file the verify that it is
|
||||||
readable and of the proper format. */
|
readable and of the proper format. */
|
||||||
public_key = RSA_new();
|
public_key = RSA_new();
|
||||||
if (!load_public_key(file, public_key, NULL))
|
if (!load_public_key(identity_file, public_key, NULL))
|
||||||
{
|
{
|
||||||
printf("%s is not a valid key file.\n", file);
|
printf("%s is not a valid key file.\n", identity_file);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private_key = RSA_new();
|
private_key = RSA_new();
|
||||||
/* Try to load the file with empty passphrase. */
|
/* Try to load the file with empty passphrase. */
|
||||||
if (load_private_key(file, "", private_key, &comment))
|
if (load_private_key(identity_file, "", private_key, &comment))
|
||||||
passphrase = xstrdup("");
|
passphrase = xstrdup("");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -279,7 +279,7 @@ do_change_comment(struct passwd *pw)
|
|||||||
else
|
else
|
||||||
passphrase = read_passphrase("Enter passphrase: ", 1);
|
passphrase = read_passphrase("Enter passphrase: ", 1);
|
||||||
/* Try to load using the passphrase. */
|
/* Try to load using the passphrase. */
|
||||||
if (!load_private_key(file, passphrase, private_key, &comment))
|
if (!load_private_key(identity_file, passphrase, private_key, &comment))
|
||||||
{
|
{
|
||||||
memset(passphrase, 0, strlen(passphrase));
|
memset(passphrase, 0, strlen(passphrase));
|
||||||
xfree(passphrase);
|
xfree(passphrase);
|
||||||
@ -310,10 +310,10 @@ do_change_comment(struct passwd *pw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Save the file using the new passphrase. */
|
/* Save the file using the new passphrase. */
|
||||||
if (!save_private_key(file, passphrase, private_key, new_comment))
|
if (!save_private_key(identity_file, passphrase, private_key, new_comment))
|
||||||
{
|
{
|
||||||
printf("Saving the key failed: %s: %s.\n",
|
printf("Saving the key failed: %s: %s.\n",
|
||||||
file, strerror(errno));
|
identity_file, strerror(errno));
|
||||||
memset(passphrase, 0, strlen(passphrase));
|
memset(passphrase, 0, strlen(passphrase));
|
||||||
xfree(passphrase);
|
xfree(passphrase);
|
||||||
RSA_free(private_key);
|
RSA_free(private_key);
|
||||||
@ -328,11 +328,11 @@ do_change_comment(struct passwd *pw)
|
|||||||
|
|
||||||
/* Save the public key in text format in a file with the same name but
|
/* Save the public key in text format in a file with the same name but
|
||||||
.pub appended. */
|
.pub appended. */
|
||||||
strcat(file, ".pub");
|
strlcat(identity_file, ".pub", sizeof(identity_file));
|
||||||
f = fopen(file, "w");
|
f = fopen(identity_file, "w");
|
||||||
if (!f)
|
if (!f)
|
||||||
{
|
{
|
||||||
printf("Could not save your public key in %s\n", file);
|
printf("Could not save your public key in %s\n", identity_file);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
fprintf(f, "%d ", BN_num_bits(public_key->n));
|
fprintf(f, "%d ", BN_num_bits(public_key->n));
|
||||||
@ -350,6 +350,14 @@ do_change_comment(struct passwd *pw)
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
printf("ssh-keygen version %s\n", SSH_VERSION);
|
||||||
|
printf("Usage: %s [-b bits] [-p] [-c] [-f file] [-P pass] [-N new-pass] [-C comment]\n", __progname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Main program for key management. */
|
/* Main program for key management. */
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -357,7 +365,7 @@ main(int ac, char **av)
|
|||||||
{
|
{
|
||||||
char buf[16384], buf2[1024], *passphrase1, *passphrase2;
|
char buf[16384], buf2[1024], *passphrase1, *passphrase2;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
char *file, *tmpbuf;
|
char *tmpbuf;
|
||||||
int opt;
|
int opt;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
@ -416,7 +424,8 @@ main(int ac, char **av)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
identity_file = optarg;
|
strlcpy(identity_file, optarg, sizeof(identity_file));
|
||||||
|
have_identity = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'P':
|
case 'P':
|
||||||
@ -437,20 +446,18 @@ main(int ac, char **av)
|
|||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
printf("ssh-keygen version %s\n", SSH_VERSION);
|
usage();
|
||||||
printf("Usage: %s [-b bits] [-p] [-c] [-f file] [-P pass] [-N new-pass] [-C comment]\n", av[0]);
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (optind < ac)
|
if (optind < ac)
|
||||||
{
|
{
|
||||||
printf("Too many arguments.\n");
|
printf("Too many arguments.\n");
|
||||||
exit(1);
|
usage();
|
||||||
}
|
}
|
||||||
if (change_passphrase && change_comment)
|
if (change_passphrase && change_comment)
|
||||||
{
|
{
|
||||||
printf("Can only have one of -p and -c.\n");
|
printf("Can only have one of -p and -c.\n");
|
||||||
exit(1);
|
usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print_fingerprint)
|
if (print_fingerprint)
|
||||||
@ -476,14 +483,13 @@ main(int ac, char **av)
|
|||||||
public_key = RSA_new();
|
public_key = RSA_new();
|
||||||
rsa_generate_key(private_key, public_key, bits);
|
rsa_generate_key(private_key, public_key, bits);
|
||||||
|
|
||||||
ask_file_again:
|
if (!have_identity)
|
||||||
|
ask_filename(pw, "Enter file in which to save the key");
|
||||||
file = get_filename(pw, "Enter file in which to save the key");
|
|
||||||
|
|
||||||
/* If the file aready exists, ask the user to confirm. */
|
/* If the file aready exists, ask the user to confirm. */
|
||||||
if (stat(file, &st) >= 0)
|
if (stat(identity_file, &st) >= 0)
|
||||||
{
|
{
|
||||||
printf("%s already exists.\n", file);
|
printf("%s already exists.\n", identity_file);
|
||||||
printf("Overwrite (y/n)? ");
|
printf("Overwrite (y/n)? ");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
if (fgets(buf2, sizeof(buf2), stdin) == NULL)
|
if (fgets(buf2, sizeof(buf2), stdin) == NULL)
|
||||||
@ -536,14 +542,13 @@ main(int ac, char **av)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Save the key with the given passphrase and comment. */
|
/* Save the key with the given passphrase and comment. */
|
||||||
if (!save_private_key(file, passphrase1, private_key, buf2))
|
if (!save_private_key(identity_file, passphrase1, private_key, buf2))
|
||||||
{
|
{
|
||||||
printf("Saving the key failed: %s: %s.\n",
|
printf("Saving the key failed: %s: %s.\n",
|
||||||
file, strerror(errno));
|
identity_file, strerror(errno));
|
||||||
memset(passphrase1, 0, strlen(passphrase1));
|
memset(passphrase1, 0, strlen(passphrase1));
|
||||||
xfree(passphrase1);
|
xfree(passphrase1);
|
||||||
xfree(file);
|
exit(1);
|
||||||
goto ask_file_again;
|
|
||||||
}
|
}
|
||||||
/* Clear the passphrase. */
|
/* Clear the passphrase. */
|
||||||
memset(passphrase1, 0, strlen(passphrase1));
|
memset(passphrase1, 0, strlen(passphrase1));
|
||||||
@ -554,7 +559,7 @@ main(int ac, char **av)
|
|||||||
arc4random_stir();
|
arc4random_stir();
|
||||||
|
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
printf("Your identification has been saved in %s.\n", file);
|
printf("Your identification has been saved in %s.\n", identity_file);
|
||||||
|
|
||||||
/* Display the public key on the screen. */
|
/* Display the public key on the screen. */
|
||||||
if (!quiet) {
|
if (!quiet) {
|
||||||
@ -570,12 +575,11 @@ main(int ac, char **av)
|
|||||||
|
|
||||||
/* Save the public key in text format in a file with the same name but
|
/* Save the public key in text format in a file with the same name but
|
||||||
.pub appended. */
|
.pub appended. */
|
||||||
file = xrealloc(file, strlen(file) + 5);
|
strlcat(identity_file, ".pub", sizeof(identity_file));
|
||||||
strcat(file, ".pub");
|
f = fopen(identity_file, "w");
|
||||||
f = fopen(file, "w");
|
|
||||||
if (!f)
|
if (!f)
|
||||||
{
|
{
|
||||||
printf("Could not save your public key in %s\n", file);
|
printf("Could not save your public key in %s\n", identity_file);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
fprintf(f, "%d ", BN_num_bits(public_key->n));
|
fprintf(f, "%d ", BN_num_bits(public_key->n));
|
||||||
@ -588,7 +592,7 @@ main(int ac, char **av)
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
printf("Your public key has been saved in %s\n", file);
|
printf("Your public key has been saved in %s\n", identity_file);
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
7
sshd.c
7
sshd.c
@ -18,7 +18,7 @@ agent connections.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$Id: sshd.c,v 1.26 1999/11/21 02:23:53 damien Exp $");
|
RCSID("$Id: sshd.c,v 1.27 1999/11/21 07:31:57 damien Exp $");
|
||||||
|
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
#include "rsa.h"
|
#include "rsa.h"
|
||||||
@ -316,7 +316,10 @@ void main_sigchld_handler(int sig)
|
|||||||
{
|
{
|
||||||
int save_errno = errno;
|
int save_errno = errno;
|
||||||
int status;
|
int status;
|
||||||
wait(&status);
|
|
||||||
|
while (waitpid(-1, &status, WNOHANG) > 0)
|
||||||
|
;
|
||||||
|
|
||||||
signal(SIGCHLD, main_sigchld_handler);
|
signal(SIGCHLD, main_sigchld_handler);
|
||||||
errno = save_errno;
|
errno = save_errno;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user