質問するログイン新規登録

質問編集履歴

13

質問訂正

2017/11/20 01:56

投稿

ijuya_yika
ijuya_yika

スコア50

title CHANGED
File without changes
body CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  ###発生している問題・エラーメッセージ
6
6
  <コード訂正後>
7
- `removeProcess`で`arr_pid`配列のプロセスIDが子プロセス終了後-1に書き換えが行われない
7
+ `removeProcess`で`arr_pid`配列のプロセスIDが子プロセス終了後-1に書き換えが行われない => 今まで行った全てのプロセスのプロセスIDが表示されてしまう
8
8
 
9
9
  <コード訂正前>
10
10
  (1)HELP1で子プロセスを配列に格納する際に親プロセスと同じプロセスIDが格納されてしまう

12

質問訂正

2017/11/20 01:56

投稿

ijuya_yika
ijuya_yika

スコア50

title CHANGED
File without changes
body CHANGED
@@ -9,7 +9,7 @@
9
9
  <コード訂正前>
10
10
  (1)HELP1で子プロセスを配列に格納する際に親プロセスと同じプロセスIDが格納されてしまう
11
11
  (2)HELP2でセグメンテーション違反が起こる
12
- =>指摘を受けポインタを使いまわすのをやめる&int型ポインタの配列をint型配列に変更するし解決
12
+ =>指摘を受けポインタを使いまわすのをやめる&int型ポインタの配列をint型配列に変更し解決
13
13
 
14
14
 
15
15
  ###該当のソースコード

11

質問訂正

2017/11/20 01:49

投稿

ijuya_yika
ijuya_yika

スコア50

title CHANGED
File without changes
body CHANGED
@@ -3,9 +3,15 @@
3
3
 
4
4
 
5
5
  ###発生している問題・エラーメッセージ
6
+ <コード訂正後>
7
+ `removeProcess`で`arr_pid`配列のプロセスIDが子プロセス終了後-1に書き換えが行われない
8
+
9
+ <コード訂正前>
6
10
  (1)HELP1で子プロセスを配列に格納する際に親プロセスと同じプロセスIDが格納されてしまう
7
11
  (2)HELP2でセグメンテーション違反が起こる
12
+ =>指摘を受けポインタを使いまわすのをやめる&int型ポインタの配列をint型配列に変更するし解決
8
13
 
14
+
9
15
  ###該当のソースコード
10
16
  ```C
11
17
  #include <stdio.h>
@@ -18,12 +24,12 @@
18
24
 
19
25
  int arr_pid[S] = {}; /* ここにプロセスが呼ばれる度新しいプロセスIDを登録 */
20
26
 
21
- void removeProcess(int sig){
27
+ void removeProcess(int signal){
22
28
  pid_t pid;
23
29
  while((pid = waitpid(-1, NULL, WNOHANG)) > 0){
24
30
  /* 子プロセスが終了したら子プロセスのPIDを-1に変える */
25
31
  for(int i=0; arr_pid[i] != 0; ++i){ /** HELP2 **/
26
- if(sig == arr_pid[i]){
32
+ if(arr_pid[i] == signal){
27
33
  arr_pid[i] = -1;
28
34
  }
29
35
  }

10

コード修正

2017/11/20 01:48

投稿

ijuya_yika
ijuya_yika

スコア50

title CHANGED
File without changes
body CHANGED
@@ -69,7 +69,7 @@
69
69
  }
70
70
 
71
71
  /* 入力がmy_psなrプロセスを出力 */
72
- if((strcmp(token[0], "my_ps")!=0)){
72
+ if((strcmp(token[0], "my_ps")==0)){
73
73
  printProcess();
74
74
  } else {
75
75
  /* my_ps 以外なら入力されたコマンドを実行 */

9

コード修正

2017/11/20 01:36

投稿

ijuya_yika
ijuya_yika

スコア50

title CHANGED
File without changes
body CHANGED
@@ -69,7 +69,7 @@
69
69
  }
70
70
 
71
71
  /* 入力がmy_psなrプロセスを出力 */
72
- if((strcmp(argv[0], "my_ps")!=0)){
72
+ if((strcmp(token[0], "my_ps")!=0)){
73
73
  printProcess();
74
74
  } else {
75
75
  /* my_ps 以外なら入力されたコマンドを実行 */

8

コード修正

2017/11/20 01:34

投稿

ijuya_yika
ijuya_yika

スコア50

title CHANGED
File without changes
body CHANGED
@@ -16,15 +16,15 @@
16
16
  #include <errno.h>
17
17
  #define S 1000
18
18
 
19
- int* arr_pid[S] = {}; /* ここにプロセスが呼ばれる度新しいプロセスIDを登録 */
19
+ int arr_pid[S] = {}; /* ここにプロセスが呼ばれる度新しいプロセスIDを登録 */
20
20
 
21
21
  void removeProcess(int sig){
22
22
  pid_t pid;
23
23
  while((pid = waitpid(-1, NULL, WNOHANG)) > 0){
24
24
  /* 子プロセスが終了したら子プロセスのPIDを-1に変える */
25
- for(int i=0; arr_pid[i] != NULL; ++i){ /** HELP2 **/
25
+ for(int i=0; arr_pid[i] != 0; ++i){ /** HELP2 **/
26
- if(sig == *(arr_pid[i])){
26
+ if(sig == arr_pid[i]){
27
- *(arr_pid[i]) = -1;
27
+ arr_pid[i] = -1;
28
28
  }
29
29
  }
30
30
  }
@@ -32,9 +32,9 @@
32
32
 
33
33
  void printProcess(){
34
34
  int i;
35
- for(i=0; arr_pid[i] != NULL; ++i){
35
+ for(i=0; arr_pid[i] != 0; ++i){
36
- if(*(arr_pid[i]) != -1){
36
+ if(arr_pid[i] != -1){
37
- printf("PID: %d\n", *(arr_pid[i]));
37
+ printf("PID: %d\n", arr_pid[i]);
38
38
  }
39
39
  }
40
40
  }
@@ -48,7 +48,7 @@
48
48
 
49
49
 
50
50
  pid = getpid();
51
- arr_pid[num_p++] = &pid; /* 親プロセスのプロセスIDを取得しarr_pidに入れる */
51
+ arr_pid[num_p++]= pid; /* 親プロセスのプロセスIDを取得しarr_pidに入れる */
52
52
  signal(SIGCHLD, &removeProcess); /* 子プロセスが終了=>SIGCHLDシグナルが送られる度配列に入れたプロセスIDを-1に変更 */
53
53
 
54
54
  while(1){
@@ -85,12 +85,10 @@
85
85
  }
86
86
  } else {
87
87
  /* 子プロセスのプロセスIDを配列に格納 */
88
- pid_t temp = getpid();
89
- arr_pid[num_p++] = &temp;
88
+ arr_pid[num_p++] = pid;
90
- if(and==NULL){
89
+ if(and==NULL)
91
- printf("&が入力されなかったので子プロセスが終わるまで待ちます\n");
92
90
  wait(&status);
93
- }
91
+
94
92
  }
95
93
  }
96
94
  }

7

コード修正

2017/11/20 01:30

投稿

ijuya_yika
ijuya_yika

スコア50

title CHANGED
File without changes
body CHANGED
@@ -69,7 +69,7 @@
69
69
  }
70
70
 
71
71
  /* 入力がmy_psなrプロセスを出力 */
72
- if((strcmp(argv[0], "my_ps")==0)){
72
+ if((strcmp(argv[0], "my_ps")!=0)){
73
73
  printProcess();
74
74
  } else {
75
75
  /* my_ps 以外なら入力されたコマンドを実行 */

6

コード訂正(int型へのポインタの配列にstrcpy等を使っていた為修正)

2017/11/20 01:15

投稿

ijuya_yika
ijuya_yika

スコア50

title CHANGED
File without changes
body CHANGED
@@ -16,15 +16,15 @@
16
16
  #include <errno.h>
17
17
  #define S 1000
18
18
 
19
- int* arr_pid[S] = {NULL}; /* ここにプロセスが呼ばれる度新しいプロセスIDを登録 */
19
+ int* arr_pid[S] = {}; /* ここにプロセスが呼ばれる度新しいプロセスIDを登録 */
20
20
 
21
21
  void removeProcess(int sig){
22
22
  pid_t pid;
23
23
  while((pid = waitpid(-1, NULL, WNOHANG)) > 0){
24
24
  /* 子プロセスが終了したら子プロセスのPIDを-1に変える */
25
25
  for(int i=0; arr_pid[i] != NULL; ++i){ /** HELP2 **/
26
- if((strcmp(arr_pid[i], sig))==0){
26
+ if(sig == *(arr_pid[i])){
27
- strcpy(arr_pid[i], -1);
27
+ *(arr_pid[i]) = -1;
28
28
  }
29
29
  }
30
30
  }
@@ -33,8 +33,8 @@
33
33
  void printProcess(){
34
34
  int i;
35
35
  for(i=0; arr_pid[i] != NULL; ++i){
36
- if(strcmp(arr_pid[i], -1)){
36
+ if(*(arr_pid[i]) != -1){
37
- printf("PID: %d\n", arr_pid[i]);
37
+ printf("PID: %d\n", *(arr_pid[i]));
38
38
  }
39
39
  }
40
40
  }

5

コード訂正

2017/11/20 01:07

投稿

ijuya_yika
ijuya_yika

スコア50

title CHANGED
File without changes
body CHANGED
@@ -47,8 +47,8 @@
47
47
  int pid, status, count, num_p = 0;
48
48
 
49
49
 
50
+ pid = getpid();
50
- pid = getpid(); /* 親プロセスのプロセスIDを取得しarr_pidに入れる */
51
+ arr_pid[num_p++] = &pid; /* 親プロセスのプロセスIDを取得しarr_pidに入れる */
51
- arr_pid[num_p++] = &pid;
52
52
  signal(SIGCHLD, &removeProcess); /* 子プロセスが終了=>SIGCHLDシグナルが送られる度配列に入れたプロセスIDを-1に変更 */
53
53
 
54
54
  while(1){
@@ -85,7 +85,8 @@
85
85
  }
86
86
  } else {
87
87
  /* 子プロセスのプロセスIDを配列に格納 */
88
+ pid_t temp = getpid();
88
- arr_pid[num_p++] = &pid;
89
+ arr_pid[num_p++] = &temp;
89
90
  if(and==NULL){
90
91
  printf("&が入力されなかったので子プロセスが終わるまで待ちます\n");
91
92
  wait(&status);
@@ -96,7 +97,4 @@
96
97
 
97
98
  return 0;
98
99
  }
99
-
100
-
101
-
102
100
  ```

4

コード訂正

2017/11/20 00:48

投稿

ijuya_yika
ijuya_yika

スコア50

title CHANGED
File without changes
body CHANGED
@@ -79,14 +79,13 @@
79
79
  if(pid==-1)
80
80
  exit(-1);
81
81
  else if(pid==0){
82
- /* 子プロセスのプロセスIDを配列に格納 */
83
- pid_t temp = getpid(); /** HELP1 **/
84
- arr_pid[num_p++] = &temp;
85
82
  if(execvp(token[0], token)<0){
86
83
  printf("エラー : %s\n", strerror(errno));
87
84
  exit(1);
88
85
  }
89
86
  } else {
87
+ /* 子プロセスのプロセスIDを配列に格納 */
88
+ arr_pid[num_p++] = &pid;
90
89
  if(and==NULL){
91
90
  printf("&が入力されなかったので子プロセスが終わるまで待ちます\n");
92
91
  wait(&status);
@@ -99,4 +98,5 @@
99
98
  }
100
99
 
101
100
 
101
+
102
102
  ```

3

コード訂正

2017/11/19 23:46

投稿

ijuya_yika
ijuya_yika

スコア50

title CHANGED
File without changes
body CHANGED
@@ -75,12 +75,13 @@
75
75
  /* my_ps 以外なら入力されたコマンドを実行 */
76
76
  pid = fork();
77
77
 
78
+
78
79
  if(pid==-1)
79
80
  exit(-1);
80
81
  else if(pid==0){
81
82
  /* 子プロセスのプロセスIDを配列に格納 */
82
- arr_pid[num_p++] = &pid; /** HELP1 **/
83
+ pid_t temp = getpid(); /** HELP1 **/
83
-
84
+ arr_pid[num_p++] = &temp;
84
85
  if(execvp(token[0], token)<0){
85
86
  printf("エラー : %s\n", strerror(errno));
86
87
  exit(1);
@@ -97,4 +98,5 @@
97
98
  return 0;
98
99
  }
99
100
 
101
+
100
102
  ```

2

コード訂正

2017/11/19 23:43

投稿

ijuya_yika
ijuya_yika

スコア50

title CHANGED
File without changes
body CHANGED
@@ -74,13 +74,11 @@
74
74
  } else {
75
75
  /* my_ps 以外なら入力されたコマンドを実行 */
76
76
  pid = fork();
77
- arr_pid[num_p++] = &pid;
78
77
 
79
78
  if(pid==-1)
80
79
  exit(-1);
81
80
  else if(pid==0){
82
81
  /* 子プロセスのプロセスIDを配列に格納 */
83
- pid = getpid();
84
82
  arr_pid[num_p++] = &pid; /** HELP1 **/
85
83
 
86
84
  if(execvp(token[0], token)<0){

1

質問訂正

2017/11/19 23:34

投稿

ijuya_yika
ijuya_yika

スコア50

title CHANGED
@@ -1,1 +1,1 @@
1
- 自作シェルでpsコマンドを自作したい
1
+ 自作シェルでシグナルハンドラを使ってpsコマンドを自作したい
body CHANGED
@@ -1,4 +1,102 @@
1
1
  ###前提・実現したいこと
2
- C言語の自作シェル内でpsコマンドを使わずに現在動いてるプロセスとコマンド内容を表示する機能をもたせたのですが、どのよに実装すればよいでょうか。
2
+ C言語の自作シェル内でシグナルハンドラを使って自作`psコマンド`(現在動いてるプロセスのIDを表示するいう簡単な関数)を作成たい
3
3
 
4
+
5
+ ###発生している問題・エラーメッセージ
6
+ (1)HELP1で子プロセスを配列に格納する際に親プロセスと同じプロセスIDが格納されてしまう
7
+ (2)HELP2でセグメンテーション違反が起こる
8
+
9
+ ###該当のソースコード
10
+ ```C
11
+ #include <stdio.h>
12
+ #include <stdlib.h>
13
+ #include <unistd.h>
14
+ #include <string.h>
15
+ #include <sys/wait.h>
16
+ #include <errno.h>
17
+ #define S 1000
18
+
19
+ int* arr_pid[S] = {NULL}; /* ここにプロセスが呼ばれる度新しいプロセスIDを登録 */
20
+
21
+ void removeProcess(int sig){
22
+ pid_t pid;
23
+ while((pid = waitpid(-1, NULL, WNOHANG)) > 0){
24
+ /* 子プロセスが終了したら子プロセスのPIDを-1に変える */
25
+ for(int i=0; arr_pid[i] != NULL; ++i){ /** HELP2 **/
26
+ if((strcmp(arr_pid[i], sig))==0){
27
+ strcpy(arr_pid[i], -1);
28
+ }
29
+ }
30
+ }
31
+ }
32
+
33
+ void printProcess(){
34
+ int i;
35
+ for(i=0; arr_pid[i] != NULL; ++i){
36
+ if(strcmp(arr_pid[i], -1)){
37
+ printf("PID: %d\n", arr_pid[i]);
38
+ }
39
+ }
40
+ }
41
+
42
+ int main(int argc, char *argv[]){
43
+ char* token[S];
44
+ char* eof;
45
+ char* and;
46
+ char usrin[S];
47
+ int pid, status, count, num_p = 0;
48
+
49
+
4
- 親プロセスに関しては`getpid()`でプロセスIDを、`argv[0]`で実行ファイル名を取得を出来ますが子プロセスに関て何かよい方法があば教えて頂きたいです。
50
+ pid = getpid(); /* 親プロセスプロセスIDを取得しarr_pidに入る */
51
+ arr_pid[num_p++] = &pid;
52
+ signal(SIGCHLD, &removeProcess); /* 子プロセスが終了=>SIGCHLDシグナルが送られる度配列に入れたプロセスIDを-1に変更 */
53
+
54
+ while(1){
55
+ printf(">>");
56
+ eof = fgets(usrin, sizeof(usrin), stdin);
57
+
58
+ if(eof==NULL)
59
+ exit(0);
60
+
61
+ usrin[strlen(usrin)-1] = '\0';
62
+ and = strchr(usrin, '&');
63
+
64
+ token[0] = strtok(usrin, " ");
65
+ for(count=1; count<S; ++count){
66
+ token[count] = strtok(NULL, " ");
67
+ if(token[count]==NULL)
68
+ break;
69
+ }
70
+
71
+ /* 入力がmy_psなrプロセスを出力 */
72
+ if((strcmp(argv[0], "my_ps")==0)){
73
+ printProcess();
74
+ } else {
75
+ /* my_ps 以外なら入力されたコマンドを実行 */
76
+ pid = fork();
77
+ arr_pid[num_p++] = &pid;
78
+
79
+ if(pid==-1)
80
+ exit(-1);
81
+ else if(pid==0){
82
+ /* 子プロセスのプロセスIDを配列に格納 */
83
+ pid = getpid();
84
+ arr_pid[num_p++] = &pid; /** HELP1 **/
85
+
86
+ if(execvp(token[0], token)<0){
87
+ printf("エラー : %s\n", strerror(errno));
88
+ exit(1);
89
+ }
90
+ } else {
91
+ if(and==NULL){
92
+ printf("&が入力されなかったので子プロセスが終わるまで待ちます\n");
93
+ wait(&status);
94
+ }
95
+ }
96
+ }
97
+ }
98
+
99
+ return 0;
100
+ }
101
+
102
+ ```