Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
e00baa9f
提交
e00baa9f
9月 07, 2006
创建
作者:
kaashoek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
get precedence of <, >, and | right
simplify
上级
1133b215
显示空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
52 行增加
和
60 行删除
+52
-60
main.c
main.c
+1
-1
sh.c
sh.c
+51
-59
没有找到文件。
main.c
浏览文件 @
e00baa9f
...
@@ -78,7 +78,7 @@ main0(void)
...
@@ -78,7 +78,7 @@ main0(void)
// enable interrupts on the local APIC
// enable interrupts on the local APIC
lapic_enableintr
();
lapic_enableintr
();
//
E
nable interrupts on this processor.
//
e
nable interrupts on this processor.
cpus
[
cpu
()].
nlock
--
;
cpus
[
cpu
()].
nlock
--
;
sti
();
sti
();
...
...
sh.c
浏览文件 @
e00baa9f
...
@@ -16,27 +16,26 @@ struct ionode {
...
@@ -16,27 +16,26 @@ struct ionode {
int
token
;
int
token
;
char
*
s
;
char
*
s
;
};
};
struct
ionode
iolist
[
MAXNODE
];
int
nextio
;
struct
cmd
{
struct
cmd
{
char
*
argv
[
MAXARGS
];
char
*
argv
[
MAXARGS
];
char
argv0buf
[
BUFSIZ
];
char
argv0buf
[
BUFSIZ
];
int
argc
;
int
argc
;
int
token
;
int
token
;
struct
ionode
iolist
[
MAXNODE
];
struct
ionode
*
io
;
};
};
struct
cmd
cmdlist
[
MAXCMD
];
struct
cmd
cmdlist
[
MAXCMD
];
int
next
cmd
;
struct
cmd
*
cmd
;
char
buf
[
BUFSIZ
];
char
buf
[
BUFSIZ
];
int
debug
=
0
;
int
debug
=
0
;
int
parse
(
char
*
s
);
int
parse
(
char
*
s
);
void
runcmd
(
void
);
void
runcmd
(
void
);
int
ioredirection
(
void
);
int
ioredirection
(
struct
ionode
*
iolist
,
int
nio
);
int
gettoken
(
char
*
s
,
char
**
token
);
int
gettoken
(
char
*
s
,
char
**
token
);
int
_gettoken
(
char
*
s
,
char
**
p1
,
char
**
p2
);
int
_gettoken
(
char
*
s
,
char
**
p1
,
char
**
p2
);
void
addio
(
int
token
,
char
*
s
);
int
int
main
(
void
)
main
(
void
)
...
@@ -59,21 +58,21 @@ parse(char *s)
...
@@ -59,21 +58,21 @@ parse(char *s)
gettoken
(
s
,
0
);
gettoken
(
s
,
0
);
nextio
=
0
;
cmd
=
&
cmdlist
[
0
];;
nextcmd
=
0
;
for
(
i
=
0
;
i
<
MAXCMD
;
i
++
)
{
for
(
i
=
0
;
i
<
MAXCMD
;
i
++
)
{
cmdlist
[
i
].
argc
=
0
;
cmdlist
[
i
].
argc
=
0
;
cmdlist
[
i
].
token
=
0
;
cmdlist
[
i
].
token
=
0
;
cmdlist
[
i
].
io
=
cmdlist
[
i
].
iolist
;
}
}
while
(
1
)
{
while
(
1
)
{
switch
((
c
=
gettoken
(
0
,
&
t
)))
{
switch
((
c
=
gettoken
(
0
,
&
t
)))
{
case
'w'
:
// Add an argument
case
'w'
:
// Add an argument
if
(
cmd
list
[
nextcmd
].
argc
>=
MAXARGS
)
{
if
(
cmd
->
argc
>=
MAXARGS
)
{
printf
(
2
,
"too many arguments
\n
"
);
printf
(
2
,
"too many arguments
\n
"
);
return
-
1
;
return
-
1
;
}
}
cmd
list
[
nextcmd
].
argv
[
cmdlist
[
nextcmd
].
argc
++
]
=
t
;
cmd
->
argv
[
cmd
->
argc
++
]
=
t
;
break
;
break
;
case
'<'
:
// Input redirection
case
'<'
:
// Input redirection
...
@@ -82,7 +81,9 @@ parse(char *s)
...
@@ -82,7 +81,9 @@ parse(char *s)
printf
(
2
,
"syntax error: < not followed by word
\n
"
);
printf
(
2
,
"syntax error: < not followed by word
\n
"
);
return
-
1
;
return
-
1
;
}
}
addio
(
'<'
,
t
);
cmd
->
io
->
token
=
'<'
;
cmd
->
io
->
s
=
t
;
cmd
->
io
++
;
break
;
break
;
case
'>'
:
// Output redirection
case
'>'
:
// Output redirection
...
@@ -91,13 +92,15 @@ parse(char *s)
...
@@ -91,13 +92,15 @@ parse(char *s)
printf
(
2
,
"syntax error: > not followed by word
\n
"
);
printf
(
2
,
"syntax error: > not followed by word
\n
"
);
return
-
1
;
return
-
1
;
}
}
addio
(
'>'
,
t
);
cmd
->
io
->
token
=
'>'
;
cmd
->
io
->
s
=
t
;
cmd
->
io
++
;
break
;
break
;
case
';'
:
// command sequence
case
';'
:
// command sequence
case
'|'
:
// pipe
case
'|'
:
// pipe
cmd
list
[
nextcmd
].
token
=
c
;
cmd
->
token
=
c
;
next
cmd
++
;
cmd
++
;
break
;
break
;
case
0
:
// String is complete
case
0
:
// String is complete
...
@@ -115,8 +118,10 @@ parse(char *s)
...
@@ -115,8 +118,10 @@ parse(char *s)
void
void
runcmd
(
void
)
runcmd
(
void
)
{
{
int
c
,
i
,
r
,
pid
,
tfd
;
int
i
,
r
,
pid
,
tfd
;
int
fdarray
[
2
];
int
fdarray
[
2
];
struct
cmd
*
c
;
struct
ionode
*
io
;
// Return immediately if command line was empty.
// Return immediately if command line was empty.
if
(
cmdlist
[
0
].
argc
==
0
)
{
if
(
cmdlist
[
0
].
argc
==
0
)
{
...
@@ -125,43 +130,43 @@ runcmd(void)
...
@@ -125,43 +130,43 @@ runcmd(void)
return
;
return
;
}
}
for
(
c
=
0
;
c
<=
next
cmd
;
c
++
)
{
for
(
c
=
&
cmdlist
[
0
];
c
<=
cmd
;
c
++
)
{
// Clean up command line.
// Clean up command line.
// Read all commands from the filesystem: add an initial '/' to
// Read all commands from the filesystem: add an initial '/' to
// the command name.
// the command name.
// This essentially acts like 'PATH=/'.
// This essentially acts like 'PATH=/'.
if
(
c
mdlist
[
c
].
argv
[
0
][
0
]
!=
'/'
)
{
if
(
c
->
argv
[
0
][
0
]
!=
'/'
)
{
c
mdlist
[
c
].
argv0buf
[
0
]
=
'/'
;
c
->
argv0buf
[
0
]
=
'/'
;
strcpy
(
c
mdlist
[
c
].
argv0buf
+
1
,
cmdlist
[
c
].
argv
[
0
]);
strcpy
(
c
->
argv0buf
+
1
,
c
->
argv
[
0
]);
c
mdlist
[
c
].
argv
[
0
]
=
cmdlist
[
c
].
argv0buf
;
c
->
argv
[
0
]
=
c
->
argv0buf
;
}
}
c
mdlist
[
c
].
argv
[
cmdlist
[
c
].
argc
]
=
0
;
c
->
argv
[
c
->
argc
]
=
0
;
// Print the command.
// Print the command.
if
(
debug
)
{
if
(
debug
)
{
printf
(
2
,
"[%d] SPAWN:"
,
getpid
());
printf
(
2
,
"[%d] SPAWN:"
,
getpid
());
for
(
i
=
0
;
c
mdlist
[
c
].
argv
[
i
];
i
++
)
for
(
i
=
0
;
c
->
argv
[
i
];
i
++
)
printf
(
2
,
" %s"
,
c
mdlist
[
c
].
argv
[
i
]);
printf
(
2
,
" %s"
,
c
->
argv
[
i
]);
for
(
i
=
0
;
i
<
nextio
;
i
++
)
{
for
(
i
o
=
c
->
iolist
;
io
<=
c
->
io
;
io
++
)
{
printf
(
2
,
"%c %s"
,
io
list
[
i
].
token
,
iolist
[
i
].
s
);
printf
(
2
,
"%c %s"
,
io
->
token
,
io
->
s
);
}
}
printf
(
2
,
"
\n
"
);
printf
(
2
,
"
\n
"
);
}
}
if
(
strcmp
(
c
mdlist
[
c
].
argv
[
0
],
"/cd"
)
==
0
)
{
if
(
strcmp
(
c
->
argv
[
0
],
"/cd"
)
==
0
)
{
if
(
debug
)
if
(
debug
)
printf
(
2
,
"/cd %s is build in
\n
"
,
c
mdlist
[
c
].
argv
[
1
]);
printf
(
2
,
"/cd %s is build in
\n
"
,
c
->
argv
[
1
]);
chdir
(
c
mdlist
[
c
].
argv
[
1
]);
chdir
(
c
->
argv
[
1
]);
return
;
return
;
}
}
if
(
c
mdlist
[
c
].
token
==
'|'
)
if
(
c
->
token
==
'|'
)
if
(
pipe
(
fdarray
)
<
0
)
if
(
pipe
(
fdarray
)
<
0
)
printf
(
2
,
"cmd %d pipe failed
\n
"
,
c
);
printf
(
2
,
"cmd %d pipe failed
\n
"
,
c
);
pid
=
fork
();
pid
=
fork
();
if
(
pid
==
0
)
{
if
(
pid
==
0
)
{
if
(
c
mdlist
[
c
].
token
==
'|'
)
{
if
(
c
->
token
==
'|'
)
{
if
(
close
(
1
)
<
0
)
if
(
close
(
1
)
<
0
)
printf
(
2
,
"close 1 failed
\n
"
);
printf
(
2
,
"close 1 failed
\n
"
);
if
((
tfd
=
dup
(
fdarray
[
1
]))
<
0
)
if
((
tfd
=
dup
(
fdarray
[
1
]))
<
0
)
...
@@ -171,7 +176,7 @@ runcmd(void)
...
@@ -171,7 +176,7 @@ runcmd(void)
if
(
close
(
fdarray
[
1
])
<
0
)
if
(
close
(
fdarray
[
1
])
<
0
)
printf
(
2
,
"close fdarray[1] failed
\n
"
);
printf
(
2
,
"close fdarray[1] failed
\n
"
);
}
}
if
(
c
>
0
&&
cmdlist
[
c
-
1
].
token
==
'|'
)
{
if
(
c
>
cmdlist
&&
(
c
-
1
)
->
token
==
'|'
)
{
if
(
close
(
0
)
<
0
)
if
(
close
(
0
)
<
0
)
printf
(
2
,
"close 0 failed
\n
"
);
printf
(
2
,
"close 0 failed
\n
"
);
if
((
tfd
=
dup
(
fdarray
[
0
]))
<
0
)
if
((
tfd
=
dup
(
fdarray
[
0
]))
<
0
)
...
@@ -181,10 +186,10 @@ runcmd(void)
...
@@ -181,10 +186,10 @@ runcmd(void)
if
(
close
(
fdarray
[
1
])
<
0
)
if
(
close
(
fdarray
[
1
])
<
0
)
printf
(
2
,
"close fdarray[1] failed
\n
"
);
printf
(
2
,
"close fdarray[1] failed
\n
"
);
}
}
if
(
ioredirection
()
<
0
)
if
(
ioredirection
(
c
->
iolist
,
c
->
io
-
c
->
iolist
)
<
0
)
exit
();
exit
();
if
((
r
=
exec
(
c
mdlist
[
c
].
argv0buf
,
(
char
**
)
cmdlist
[
c
].
argv
))
<
0
)
{
if
((
r
=
exec
(
c
->
argv0buf
,
(
char
**
)
c
->
argv
))
<
0
)
{
printf
(
2
,
"exec %s: %d
\n
"
,
c
mdlist
[
c
].
argv
[
0
],
r
);
printf
(
2
,
"exec %s: %d
\n
"
,
c
->
argv
[
0
],
r
);
exit
();
exit
();
}
}
}
else
if
(
pid
>
0
)
{
}
else
if
(
pid
>
0
)
{
...
@@ -192,11 +197,11 @@ runcmd(void)
...
@@ -192,11 +197,11 @@ runcmd(void)
if
(
debug
)
if
(
debug
)
printf
(
2
,
"[%d] FORKED child %d
\n
"
,
getpid
(),
pid
);
printf
(
2
,
"[%d] FORKED child %d
\n
"
,
getpid
(),
pid
);
if
(
c
>
0
&&
cmdlist
[
c
-
1
].
token
==
'|'
)
{
if
(
c
>
cmdlist
&&
(
c
-
1
)
->
token
==
'|'
)
{
close
(
fdarray
[
0
]);
close
(
fdarray
[
0
]);
close
(
fdarray
[
1
]);
close
(
fdarray
[
1
]);
}
}
if
(
c
mdlist
[
c
].
token
!=
'|'
)
{
if
(
c
->
token
!=
'|'
)
{
if
(
debug
)
if
(
debug
)
printf
(
2
,
"[%d] WAIT for children
\n
"
,
getpid
());
printf
(
2
,
"[%d] WAIT for children
\n
"
,
getpid
());
do
{
do
{
...
@@ -212,51 +217,38 @@ runcmd(void)
...
@@ -212,51 +217,38 @@ runcmd(void)
}
}
int
int
ioredirection
(
void
)
ioredirection
(
struct
ionode
*
iolist
,
int
nio
)
{
{
int
i
,
fd
;
int
fd
;
struct
ionode
*
io
;
for
(
i
=
0
;
i
<
nextio
;
i
++
)
{
for
(
i
o
=
iolist
;
io
<
&
iolist
[
nio
];
io
++
)
{
switch
(
io
list
[
i
].
token
)
{
switch
(
io
->
token
)
{
case
'<'
:
case
'<'
:
if
(
close
(
0
)
<
0
)
if
(
close
(
0
)
<
0
)
printf
(
2
,
"close 0 failed
\n
"
);
printf
(
2
,
"close 0 failed
\n
"
);
if
((
fd
=
open
(
io
list
[
i
].
s
,
O_RDONLY
))
<
0
)
{
if
((
fd
=
open
(
io
->
s
,
O_RDONLY
))
<
0
)
{
printf
(
2
,
"failed to open %s for read: %d"
,
io
list
[
i
].
s
,
fd
);
printf
(
2
,
"failed to open %s for read: %d"
,
io
->
s
,
fd
);
return
-
1
;
return
-
1
;
}
}
if
(
debug
)
if
(
debug
)
printf
(
2
,
"redirect 0 from %s
\n
"
,
io
list
[
i
].
s
);
printf
(
2
,
"redirect 0 from %s
\n
"
,
io
->
s
);
break
;
break
;
case
'>'
:
case
'>'
:
if
(
close
(
1
)
<
0
)
if
(
close
(
1
)
<
0
)
printf
(
2
,
"close 1 failed
\n
"
);
printf
(
2
,
"close 1 failed
\n
"
);
if
((
fd
=
open
(
io
list
[
i
].
s
,
O_WRONLY
|
O_CREATE
))
<
0
)
{
if
((
fd
=
open
(
io
->
s
,
O_WRONLY
|
O_CREATE
))
<
0
)
{
printf
(
2
,
"failed to open %s for write: %d"
,
io
list
[
i
].
s
,
fd
);
printf
(
2
,
"failed to open %s for write: %d"
,
io
->
s
,
fd
);
exit
();
exit
();
}
}
if
(
debug
)
if
(
debug
)
printf
(
2
,
"redirect 1 to %s
\n
"
,
io
list
[
i
].
s
);
printf
(
2
,
"redirect 1 to %s
\n
"
,
io
->
s
);
break
;
break
;
}
}
}
}
return
0
;
return
0
;
}
}
void
addio
(
int
token
,
char
*
s
)
{
if
(
nextio
>=
MAXNODE
)
{
printf
(
2
,
"addio: ran out of nodes
\n
"
);
return
;
}
iolist
[
nextio
].
token
=
token
;
iolist
[
nextio
].
s
=
s
;
nextio
++
;
}
// gettoken(s, 0) prepares gettoken for subsequent calls and returns 0.
// gettoken(s, 0) prepares gettoken for subsequent calls and returns 0.
// gettoken(0, token) parses a shell token from the previously set string,
// gettoken(0, token) parses a shell token from the previously set string,
// null-terminates that token, stores the token pointer in '*token',
// null-terminates that token, stores the token pointer in '*token',
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论