Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
d1c6a037
Commit
d1c6a037
authored
Apr 26, 1999
by
Bruce Korb
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
properly handle child processes
From-SVN: r26644
parent
039d4bce
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
185 additions
and
105 deletions
+185
-105
gcc/fixinc/fixincl.c
+175
-98
gcc/fixinc/server.c
+9
-6
gcc/fixinc/server.h
+1
-1
No files found.
gcc/fixinc/fixincl.c
View file @
d1c6a037
...
@@ -147,9 +147,11 @@ pid_t process_chain_head = (pid_t) -1;
...
@@ -147,9 +147,11 @@ pid_t process_chain_head = (pid_t) -1;
const
char
incl_quote_pat
[]
=
"^[
\t
]*#[
\t
]*include[
\t
]*
\"
[^/]"
;
const
char
incl_quote_pat
[]
=
"^[
\t
]*#[
\t
]*include[
\t
]*
\"
[^/]"
;
regex_t
incl_quote_re
;
regex_t
incl_quote_re
;
char
*
load_file
(
const
char
*
pzFile
);
char
*
load_file
(
const
char
*
);
void
process
(
char
*
data
,
const
char
*
file
);
void
process
(
char
*
,
const
char
*
);
void
run_compiles
(
void
);
void
run_compiles
();
void
wait_for_pid
(
pid_t
,
int
);
void
initialize
();
#include "fixincl.x"
#include "fixincl.x"
...
@@ -164,8 +166,6 @@ main (argc, argv)
...
@@ -164,8 +166,6 @@ main (argc, argv)
{
{
static
const
char
gnu_lib_mark
[]
=
static
const
char
gnu_lib_mark
[]
=
"This file is part of the GNU C Library"
;
"This file is part of the GNU C Library"
;
static
const
char
var_not_found
[]
=
"fixincl ERROR: %s environment variable not defined
\n
"
;
#ifndef NO_BOGOSITY_LIMITS
#ifndef NO_BOGOSITY_LIMITS
# define BOGUS_LIMIT MINIMUM_MAXIMUM_LINES
# define BOGUS_LIMIT MINIMUM_MAXIMUM_LINES
...
@@ -212,6 +212,113 @@ main (argc, argv)
...
@@ -212,6 +212,113 @@ main (argc, argv)
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
initialize
();
#ifndef NO_BOGOSITY_LIMITS
/* Some systems only allow so many calls to fork(2).
This is inadequate for this program. Consequently,
we must let a grandfather process spawn children
that then spawn all the processes that do the real work.
*/
for
(;;)
{
file_name_ct
=
0
;
{
char
*
pz_buf
=
file_name_buf
;
/* Only the parent process can read from stdin without confusing
the world. (How does the child tell the parent to skip
forward? Pipes and files behave differently.) */
while
(
(
file_name_ct
<
BOGUS_LIMIT
)
&&
(
pz_buf
<
(
file_name_buf
+
NAME_TABLE_SIZE
-
MAXPATHLEN
)))
{
if
(
fgets
(
pz_buf
,
MAXPATHLEN
,
stdin
)
==
(
char
*
)
NULL
)
break
;
while
(
isspace
(
*
pz_buf
))
pz_buf
++
;
if
((
*
pz_buf
==
'\0'
)
||
(
*
pz_buf
==
'#'
))
continue
;
apz_names
[
file_name_ct
++
]
=
pz_buf
;
pz_buf
+=
strlen
(
pz_buf
);
while
(
isspace
(
pz_buf
[
-
1
]))
pz_buf
--
;
*
pz_buf
++
=
'\0'
;
}
}
/* IF we did not get any files this time thru
THEN we must be done. */
if
(
file_name_ct
==
0
)
return
EXIT_SUCCESS
;
{
pid_t
child
=
fork
();
if
(
child
==
NULLPROCESS
)
break
;
if
(
child
==
NOPROCESS
)
{
fprintf
(
stderr
,
"Error %d (%s) forking in main
\n
"
,
errno
,
strerror
(
errno
));
exit
(
EXIT_FAILURE
);
}
wait_for_pid
(
child
,
file_name_ct
);
}
}
#else
#error "NON-BOGUS LIMITS NOT SUPPORTED?!?!"
#endif
/*
Here we are the child of the grandparent process. The parent
of all the little fixup processes. We ignore the deaths of
our children. */
signal
(
SIGCLD
,
SIG_IGN
);
#ifdef DEBUG
fprintf
(
stderr
,
"Child start -- processing %d files
\n
"
,
file_name_ct
);
#endif
/* For every file specified in stdandard in
(except as throttled for bogus reasons)...
*/
for
(
loop_ct
=
0
;
loop_ct
<
file_name_ct
;
loop_ct
++
)
{
char
*
pz_data
;
char
*
pz_file_name
=
apz_names
[
loop_ct
];
if
(
access
(
pz_file_name
,
R_OK
)
!=
0
)
{
int
erno
=
errno
;
fprintf
(
stderr
,
"Cannot access %s from %s
\n\t
error %d (%s)
\n
"
,
pz_file_name
,
getcwd
((
char
*
)
NULL
,
MAXPATHLEN
),
erno
,
strerror
(
erno
));
}
else
if
(
pz_data
=
load_file
(
pz_file_name
),
(
pz_data
!=
(
char
*
)
NULL
))
{
if
(
strstr
(
pz_data
,
gnu_lib_mark
)
==
(
char
*
)
NULL
)
process
(
pz_data
,
pz_file_name
);
free
((
void
*
)
pz_data
);
}
}
return
EXIT_SUCCESS
;
}
/* * * * * * * * * * * * */
void
initialize
()
{
static
const
char
var_not_found
[]
=
"fixincl ERROR: %s environment variable not defined
\n
"
;
{
{
static
const
char
var
[]
=
"TARGET_MACHINE"
;
static
const
char
var
[]
=
"TARGET_MACHINE"
;
pz_machine
=
getenv
(
var
);
pz_machine
=
getenv
(
var
);
...
@@ -264,110 +371,74 @@ main (argc, argv)
...
@@ -264,110 +371,74 @@ main (argc, argv)
signal
(
SIGALRM
,
SIG_IGN
);
signal
(
SIGALRM
,
SIG_IGN
);
signal
(
SIGTERM
,
SIG_IGN
);
signal
(
SIGTERM
,
SIG_IGN
);
#ifndef NO_BOGOSITY_LIMITS
/*
/* Some systems only allow so many calls to fork(2).
Make sure that if we opened a server process, we close it now.
This is inadequate for this program. Consequently,
This is the grandparent process. We don't need the server anymore
we must let a grandfather process spawn children
and our children should make their own. */
that then spawn all the processes that do the real work.
*/
for
(;;)
{
char
*
pz_buf
;
pid_t
child
;
/* Only the parent process can read from stdin without confusing
the world. (How does the child tell the parent to skip
forward? Pipes and files behave differently.) */
file_name_ct
=
0
;
pz_buf
=
file_name_buf
;
while
(
(
file_name_ct
<
BOGUS_LIMIT
)
&&
(
pz_buf
<
(
file_name_buf
+
NAME_TABLE_SIZE
-
MAXPATHLEN
)))
{
if
(
fgets
(
pz_buf
,
MAXPATHLEN
,
stdin
)
==
(
char
*
)
NULL
)
break
;
while
(
isspace
(
*
pz_buf
))
pz_buf
++
;
if
((
*
pz_buf
==
'\0'
)
||
(
*
pz_buf
==
'#'
))
continue
;
apz_names
[
file_name_ct
++
]
=
pz_buf
;
pz_buf
+=
strlen
(
pz_buf
);
while
(
isspace
(
pz_buf
[
-
1
]))
pz_buf
--
;
*
pz_buf
++
=
'\0'
;
}
/* IF we did not get any files this time thru
THEN we must be done. */
if
(
file_name_ct
==
0
)
return
EXIT_SUCCESS
;
child
=
fork
();
if
(
child
==
NULLPROCESS
)
break
;
if
(
child
==
NOPROCESS
)
close_server
();
{
(
void
)
wait
(
(
int
*
)
NULL
);
fprintf
(
stderr
,
"Error %d (%s) forking in main
\n
"
,
}
errno
,
strerror
(
errno
));
exit
(
EXIT_FAILURE
);
}
#ifndef DEBUG
{
int
status
;
(
void
)
wait
(
&
status
);
}
#else
fprintf
(
stderr
,
"Waiting for %d to complete %d files
\n
"
,
child
,
file_name_ct
);
{
/* * * * * * * * * * * * *
int
status
;
pid_t
dead_kid
=
wait
(
&
status
);
wait_for_pid - Keep calling `wait(2)' until it returns
the process id we are looking for. Not every system has
`waitpid(2)'. We also ensure that the children exit with success. */
if
(
dead_kid
!=
child
)
void
fprintf
(
stderr
,
"fixincl woke up from a strange child %d (not %d)
\n
"
,
wait_for_pid
(
pid_t
child
,
int
file_name_ct
)
dead_kid
,
child
);
{
else
#ifdef DEBUG
fprintf
(
stderr
,
"child finished %d files %s
\n
"
,
file_name_ct
,
fprintf
(
stderr
,
"Waiting for %d to complete %d files
\n
"
,
status
?
strerror
(
status
&
0xFF
)
:
"ok"
);
child
,
file_name_ct
);
}
#endif
}
#else
#error "NON-BOGUS LIMITS NOT SUPPORTED?!?!"
#endif
#endif
signal
(
SIGCLD
,
SIG_IGN
);
for
(;;)
{
int
status
;
pid_t
dead_kid
=
wait
(
&
status
);
if
(
dead_kid
==
child
)
{
if
(
!
WIFEXITED
(
status
))
{
fprintf
(
stderr
,
"child process %d is hung on signal %d
\n
"
,
child
,
WSTOPSIG
(
status
));
exit
(
EXIT_FAILURE
);
}
if
(
WEXITSTATUS
(
status
)
!=
0
)
{
fprintf
(
stderr
,
"child process %d exited with status %d
\n
"
,
child
,
WEXITSTATUS
(
status
));
exit
(
EXIT_FAILURE
);
}
#ifdef DEBUG
#ifdef DEBUG
fprintf
(
stderr
,
"Child start -- processing %d files
\n
"
,
fprintf
(
stderr
,
"child finished %d files %s
\n
"
,
file_name_ct
,
file_name_ct
);
status
?
strerror
(
status
&
0xFF
)
:
"ok"
);
#endif
#endif
break
;
/* normal child completion */
}
/* For every file specified in stdandard in
/*
(except as throttled for bogus reasons)...
IF there is an error, THEN see if it is retryable.
*/
If it is not retryable, then break out of this loop. */
for
(
loop_ct
=
0
;
loop_ct
<
file_name_ct
;
loop_ct
++
)
if
(
dead_kid
==
NOPROCESS
)
{
{
char
*
pz_data
;
switch
(
errno
)
{
char
*
pz_file_name
=
apz_names
[
loop_ct
];
case
EINTR
:
case
EAGAIN
:
break
;
if
(
access
(
pz_file_name
,
R_OK
)
!=
0
)
default
:
{
fprintf
(
stderr
,
"Error %d (%s) waiting for %d to finish
\n
"
,
int
erno
=
errno
;
errno
,
strerror
(
errno
),
child
);
fprintf
(
stderr
,
"Cannot access %s from %s
\n\t
error %d (%s)
\n
"
,
/* FALLTHROUGH */
pz_file_name
,
getcwd
((
char
*
)
NULL
,
MAXPATHLEN
),
erno
,
strerror
(
erno
));
}
else
if
(
pz_data
=
load_file
(
pz_file_name
),
(
pz_data
!=
(
char
*
)
NULL
))
{
if
(
strstr
(
pz_data
,
gnu_lib_mark
)
==
(
char
*
)
NULL
)
process
(
pz_data
,
pz_file_name
);
free
((
void
*
)
pz_data
);
}
}
return
EXIT_SUCCESS
;
case
ECHILD
:
/* no children to wait for?? */
return
;
}
}
}
done_waiting
:
;
}
}
...
@@ -476,6 +547,12 @@ run_compiles ()
...
@@ -476,6 +547,12 @@ run_compiles ()
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
/* Make sure re_compile_pattern does not stumble across invalid
data */
memset
(
(
void
*
)
p_re
,
'\0'
,
REGEX_COUNT
*
sizeof
(
regex_t
)
);
memset
(
(
void
*
)
&
incl_quote_re
,
'\0'
,
sizeof
(
regex_t
)
);
/* The patterns we search for are all egrep patterns.
/* The patterns we search for are all egrep patterns.
In the shell version of this program, we invoke egrep
In the shell version of this program, we invoke egrep
with the supplied pattern. Here, we will run
with the supplied pattern. Here, we will run
...
...
gcc/fixinc/server.c
View file @
d1c6a037
...
@@ -178,14 +178,17 @@ load_data (fp)
...
@@ -178,14 +178,17 @@ load_data (fp)
* Make certain the server process is dead, close the
* Make certain the server process is dead, close the
* pipes to it and from it, finally NULL out the file pointers
* pipes to it and from it, finally NULL out the file pointers
*/
*/
static
void
void
close_server
()
close_server
()
{
{
kill
((
pid_t
)
server_id
,
SIGKILL
);
if
(
server_id
!=
NULLPROCESS
)
server_id
=
NULLPROCESS
;
{
fclose
(
server_pair
.
pf_read
);
kill
((
pid_t
)
server_id
,
SIGKILL
);
fclose
(
server_pair
.
pf_write
);
server_id
=
NULLPROCESS
;
server_pair
.
pf_read
=
server_pair
.
pf_write
=
(
FILE
*
)
NULL
;
fclose
(
server_pair
.
pf_read
);
fclose
(
server_pair
.
pf_write
);
server_pair
.
pf_read
=
server_pair
.
pf_write
=
(
FILE
*
)
NULL
;
}
}
}
/*
/*
...
...
gcc/fixinc/server.h
View file @
d1c6a037
...
@@ -90,5 +90,5 @@ pid_t proc2_open _P_ (( t_fd_pair * p_pair, t_pchar * pp_args));
...
@@ -90,5 +90,5 @@ pid_t proc2_open _P_ (( t_fd_pair * p_pair, t_pchar * pp_args));
int
chain_open
_P_
((
int
in_fd
,
int
chain_open
_P_
((
int
in_fd
,
t_pchar
*
pp_args
,
t_pchar
*
pp_args
,
pid_t
*
p_child
));
pid_t
*
p_child
));
void
close_server
_P_
((
void
));
#endif
/* FIXINC_SERVER_H */
#endif
/* FIXINC_SERVER_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment