Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
B
brpc
Project
Project
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
brpc
Commits
cb054071
Commit
cb054071
authored
Nov 14, 2017
by
Zhangyi Chen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add missing file needed by
79f2e7d3
parent
79f2e7d3
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
210 additions
and
0 deletions
+210
-0
popen.cpp
src/butil/popen.cpp
+178
-0
popen.h
src/butil/popen.h
+32
-0
No files found.
src/butil/popen.cpp
0 → 100644
View file @
cb054071
// Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Author: Zhangyi Chen (chenzhangyi01@baidu.com)
// Date: 2017/11/04 17:37:43
#include "butil/build_config.h"
#include "butil/logging.h"
#if defined(OS_LINUX)
// clone is a linux specific syscall
#include <sched.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
extern
"C"
{
uint64_t
BAIDU_WEAK
bthread_usleep
(
uint64_t
microseconds
);
}
namespace
butil
{
const
int
CHILD_STACK_SIZE
=
64
*
1024
;
struct
ChildArgs
{
const
char
*
cmd
;
int
pipe_fd0
;
int
pipe_fd1
;
};
int
launch_child_process
(
void
*
args
)
{
ChildArgs
*
cargs
=
(
ChildArgs
*
)
args
;
dup2
(
cargs
->
pipe_fd1
,
STDOUT_FILENO
);
close
(
cargs
->
pipe_fd0
);
close
(
cargs
->
pipe_fd1
);
execl
(
"/bin/sh"
,
"sh"
,
"-c"
,
cargs
->
cmd
,
NULL
);
_exit
(
1
);
}
int
read_command_output
(
std
::
ostream
&
os
,
const
char
*
cmd
)
{
int
pipe_fd
[
2
];
if
(
pipe
(
pipe_fd
)
!=
0
)
{
PLOG
(
ERROR
)
<<
"Fail to pipe"
;
return
-
1
;
}
int
saved_errno
=
0
;
int
wstatus
=
0
;
pid_t
cpid
;
int
rc
=
0
;
ChildArgs
args
=
{
cmd
,
pipe_fd
[
0
],
pipe_fd
[
1
]
};
char
buffer
[
1024
];
char
*
child_stack
=
NULL
;
char
*
child_stack_mem
=
(
char
*
)
malloc
(
CHILD_STACK_SIZE
);
if
(
!
child_stack_mem
)
{
LOG
(
ERROR
)
<<
"Fail to alloc stack for the child process"
;
rc
=
-
1
;
goto
END
;
}
child_stack
=
child_stack_mem
+
CHILD_STACK_SIZE
;
// ^ Assume stack grows downward
cpid
=
clone
(
launch_child_process
,
child_stack
,
__WCLONE
|
CLONE_VM
|
SIGCHLD
,
&
args
);
if
(
cpid
<
0
)
{
PLOG
(
ERROR
)
<<
"Fail to clone child process"
;
rc
=
-
1
;
goto
END
;
}
close
(
pipe_fd
[
1
]);
pipe_fd
[
1
]
=
-
1
;
for
(;;)
{
const
ssize_t
nr
=
read
(
pipe_fd
[
0
],
buffer
,
sizeof
(
buffer
));
if
(
nr
>
0
)
{
os
.
write
(
buffer
,
nr
);
continue
;
}
else
if
(
nr
==
0
)
{
break
;
}
else
if
(
errno
!=
EINTR
)
{
LOG
(
ERROR
)
<<
"Encountered error while reading for the pipe"
;
break
;
}
}
close
(
pipe_fd
[
0
]);
pipe_fd
[
0
]
=
-
1
;
for
(;;)
{
pid_t
wpid
=
waitpid
(
cpid
,
&
wstatus
,
WNOHANG
);
if
(
wpid
>
0
)
{
break
;
}
if
(
wpid
==
0
)
{
if
(
bthread_usleep
!=
NULL
)
{
bthread_usleep
(
1000
);
}
else
{
usleep
(
1000
);
}
continue
;
}
rc
=
-
1
;
goto
END
;
}
if
(
WIFEXITED
(
wstatus
))
{
rc
=
WEXITSTATUS
(
wstatus
);
goto
END
;
}
if
(
WIFSIGNALED
(
wstatus
))
{
os
<<
"Child process("
<<
cpid
<<
") was killed by signal "
<<
WTERMSIG
(
wstatus
);
}
rc
=
-
1
;
errno
=
ECHILD
;
END:
saved_errno
=
errno
;
if
(
child_stack_mem
)
{
free
(
child_stack_mem
);
}
if
(
pipe_fd
[
0
]
>=
0
)
{
close
(
pipe_fd
[
0
]);
}
if
(
pipe_fd
[
1
]
>=
0
)
{
close
(
pipe_fd
[
1
]);
}
errno
=
saved_errno
;
return
rc
;
}
}
// namespace butil
#else // OS_LINUX
#include <stdio.h>
namespace
butil
{
int
read_command_output
(
std
::
ostream
&
os
,
const
char
*
cmd
)
{
FILE
*
pipe
=
popen
(
cmd
,
"r"
);
if
(
pipe
==
NULL
)
{
return
-
1
;
}
char
buffer
[
1024
];
for
(;;)
{
size_t
nr
=
fread
(
buffer
,
1
,
sizeof
(
buffer
),
pipe
);
if
(
nr
!=
0
)
{
os
.
write
(
buffer
,
nr
);
}
if
(
nr
!=
sizeof
(
buffer
))
{
if
(
feof
(
pipe
))
{
break
;
}
else
if
(
ferror
(
pipe
))
{
LOG
(
ERROR
)
<<
"Encountered error while reading for the pipe"
;
break
;
}
// retry;
}
}
return
pclose
(
pipe
);
}
}
// namespace butil
#endif // OS_LINUX
src/butil/popen.h
0 → 100644
View file @
cb054071
// Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Author: Zhangyi Chen (chenzhangyi01@baidu.com)
// Date: 2017/11/04 17:13:18
#ifndef PUBLIC_COMMON_POPEN_H
#define PUBLIC_COMMON_POPEN_H
#include <ostream>
namespace
butil
{
// Read the stdout of child process executing `cmd'.
// Returns the exit status(0-255) of cmd and all the output is stored in
// |os|. -1 otherwise and errno is set appropriately.
int
read_command_output
(
std
::
ostream
&
os
,
const
char
*
cmd
);
}
#endif //PUBLIC_COMMON_POPEN_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