Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
rust
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
redox-os
rust
Commits
7cd7bb5f
Verified
Commit
7cd7bb5f
authored
6 years ago
by
jD91mZM2
Committed by
Jeremy Soller
6 years ago
Browse files
Options
Downloads
Patches
Plain Diff
Interpret shebangs on redox
This is no longer handled on the kernel side
parent
d0b9dcd4
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/libstd/sys/redox/process.rs
+76
-12
76 additions, 12 deletions
src/libstd/sys/redox/process.rs
with
76 additions
and
12 deletions
src/libstd/sys/redox/process.rs
+
76
−
12
View file @
7cd7bb5f
...
...
@@ -10,15 +10,17 @@
use
env
::{
split_paths
};
use
ffi
::{
CStr
,
OsStr
};
use
fs
::
File
;
use
os
::
unix
::
ffi
::
OsStrExt
;
use
fmt
;
use
io
::{
self
,
Error
,
ErrorKind
};
use
iter
;
use
io
::{
self
,
prelude
::
*
,
BufReader
,
Error
,
ErrorKind
,
SeekFrom
};
use
libc
::{
EXIT_SUCCESS
,
EXIT_FAILURE
};
use
path
::{
Path
,
PathBuf
};
use
ptr
;
use
sys
::
ext
::
fs
::
MetadataExt
;
use
sys
::
ext
::
io
::
AsRawFd
;
use
sys
::
fd
::
FileDesc
;
use
sys
::
fs
::{
File
,
OpenOptions
};
use
sys
::
fs
::{
File
as
SysFile
,
OpenOptions
};
use
sys
::
os
::{
ENV_LOCK
,
environ
};
use
sys
::
pipe
::{
self
,
AnonPipe
};
use
sys
::{
cvt
,
syscall
};
...
...
@@ -315,22 +317,85 @@ macro_rules! t {
None
};
let
fd
=
if
let
Some
(
program
)
=
program_opt
{
t!
(
cvt
(
syscall
::
open
(
program
.as_os_str
()
.as_bytes
(),
syscall
::
O_RDONLY
|
syscall
::
O_CLOEXEC
)
))
let
mut
file
=
if
let
Some
(
program
)
=
program_opt
{
t!
(
File
::
open
(
program
.as_os_str
()))
}
else
{
return
io
::
Error
::
from_raw_os_error
(
syscall
::
ENOENT
);
};
self
.env
.apply
();
let
mut
args
:
Vec
<
[
usize
;
2
]
>
=
Vec
::
new
();
// Push all the arguments
let
mut
args
:
Vec
<
[
usize
;
2
]
>
=
Vec
::
with_capacity
(
1
+
self
.args
.len
());
let
interpreter
=
{
let
mut
reader
=
BufReader
::
new
(
&
file
);
let
mut
shebang
=
[
0
;
2
];
let
mut
read
=
0
;
loop
{
match
t!
(
reader
.read
(
&
mut
shebang
[
read
..
]))
{
0
=>
break
,
n
=>
read
+=
n
,
}
}
if
&
shebang
==
b"#!"
{
// This is an interpreted script.
// First of all, since we'll be passing another file to
// fexec(), we need to manually check that we have permission
// to execute this file:
let
uid
=
t!
(
cvt
(
syscall
::
getuid
()));
let
gid
=
t!
(
cvt
(
syscall
::
getgid
()));
let
meta
=
t!
(
file
.metadata
());
let
mode
=
if
uid
==
meta
.uid
()
as
usize
{
meta
.mode
()
>>
3
*
2
&
0o7
}
else
if
gid
==
meta
.gid
()
as
usize
{
meta
.mode
()
>>
3
*
1
&
0o7
}
else
{
meta
.mode
()
&
0o7
};
if
mode
&
1
==
0
{
return
io
::
Error
::
from_raw_os_error
(
syscall
::
EPERM
);
}
// Second of all, we need to actually read which interpreter it wants
let
mut
interpreter
=
Vec
::
new
();
t!
(
reader
.read_until
(
b'\n'
,
&
mut
interpreter
));
// Pop one trailing newline, if any
if
interpreter
.ends_with
(
&
[
b'\n'
])
{
interpreter
.pop
()
.unwrap
();
}
// TODO: Here we could just reassign `file` directly, if it
// wasn't for lexical lifetimes. Remove the whole `let
// interpreter = { ... };` hack once NLL lands.
// NOTE: Although DO REMEMBER to make sure the interpreter path
// still lives long enough to reach fexec.
Some
(
interpreter
)
}
else
{
None
}
};
if
let
Some
(
ref
interpreter
)
=
interpreter
{
let
path
:
&
OsStr
=
OsStr
::
from_bytes
(
&
interpreter
);
file
=
t!
(
File
::
open
(
path
));
args
.push
([
interpreter
.as_ptr
()
as
usize
,
interpreter
.len
()]);
}
else
{
t!
(
file
.seek
(
SeekFrom
::
Start
(
0
)));
}
args
.push
([
self
.program
.as_ptr
()
as
usize
,
self
.program
.len
()]);
for
arg
in
self
.args
.iter
()
{
args
.push
([
arg
.as_ptr
()
as
usize
,
arg
.len
()]);
}
// Push all the variables
let
mut
vars
:
Vec
<
[
usize
;
2
]
>
=
Vec
::
new
();
unsafe
{
{
let
_guard
=
ENV_LOCK
.lock
();
let
mut
environ
=
*
environ
();
while
*
environ
!=
ptr
::
null
()
{
...
...
@@ -340,8 +405,7 @@ macro_rules! t {
}
}
if
let
Err
(
err
)
=
syscall
::
fexec
(
fd
,
&
args
,
&
vars
)
{
let
_
=
syscall
::
close
(
fd
);
if
let
Err
(
err
)
=
syscall
::
fexec
(
file
.as_raw_fd
(),
&
args
,
&
vars
)
{
io
::
Error
::
from_raw_os_error
(
err
.errno
as
i32
)
}
else
{
panic!
(
"return from exec without err"
);
...
...
@@ -408,7 +472,7 @@ fn to_child_stdio(&self, readable: bool)
let
mut
opts
=
OpenOptions
::
new
();
opts
.read
(
readable
);
opts
.write
(
!
readable
);
let
fd
=
File
::
open
(
Path
::
new
(
"null:"
),
&
opts
)
?
;
let
fd
=
Sys
File
::
open
(
Path
::
new
(
"null:"
),
&
opts
)
?
;
Ok
((
ChildStdio
::
Owned
(
fd
.into_fd
()),
None
))
}
}
...
...
@@ -421,8 +485,8 @@ fn from(pipe: AnonPipe) -> Stdio {
}
}
impl
From
<
File
>
for
Stdio
{
fn
from
(
file
:
File
)
->
Stdio
{
impl
From
<
Sys
File
>
for
Stdio
{
fn
from
(
file
:
Sys
File
)
->
Stdio
{
Stdio
::
Fd
(
file
.into_fd
())
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment