質問編集履歴

13

質問訂正

2017/11/20 01:56

投稿

ijuya_yika
ijuya_yika

スコア50

test CHANGED
File without changes
test CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  <コード訂正後>
12
12
 
13
- `removeProcess`で`arr_pid`配列のプロセスIDが子プロセス終了後-1に書き換えが行われない
13
+ `removeProcess`で`arr_pid`配列のプロセスIDが子プロセス終了後-1に書き換えが行われない => 今まで行った全てのプロセスのプロセスIDが表示されてしまう
14
14
 
15
15
 
16
16
 

12

質問訂正

2017/11/20 01:56

投稿

ijuya_yika
ijuya_yika

スコア50

test CHANGED
File without changes
test CHANGED
@@ -20,7 +20,7 @@
20
20
 
21
21
  (2)HELP2でセグメンテーション違反が起こる
22
22
 
23
- =>指摘を受けポインタを使いまわすのをやめる&int型ポインタの配列をint型配列に変更するし解決
23
+ =>指摘を受けポインタを使いまわすのをやめる&int型ポインタの配列をint型配列に変更し解決
24
24
 
25
25
 
26
26
 

11

質問訂正

2017/11/20 01:49

投稿

ijuya_yika
ijuya_yika

スコア50

test CHANGED
File without changes
test CHANGED
@@ -8,10 +8,22 @@
8
8
 
9
9
  ###発生している問題・エラーメッセージ
10
10
 
11
+ <コード訂正後>
12
+
13
+ `removeProcess`で`arr_pid`配列のプロセスIDが子プロセス終了後-1に書き換えが行われない
14
+
15
+
16
+
17
+ <コード訂正前>
18
+
11
19
  (1)HELP1で子プロセスを配列に格納する際に親プロセスと同じプロセスIDが格納されてしまう
12
20
 
13
21
  (2)HELP2でセグメンテーション違反が起こる
14
22
 
23
+ =>指摘を受けポインタを使いまわすのをやめる&int型ポインタの配列をint型配列に変更するし解決
24
+
25
+
26
+
15
27
 
16
28
 
17
29
  ###該当のソースコード
@@ -38,7 +50,7 @@
38
50
 
39
51
 
40
52
 
41
- void removeProcess(int sig){
53
+ void removeProcess(int signal){
42
54
 
43
55
  pid_t pid;
44
56
 
@@ -48,7 +60,7 @@
48
60
 
49
61
  for(int i=0; arr_pid[i] != 0; ++i){ /** HELP2 **/
50
62
 
51
- if(sig == arr_pid[i]){
63
+ if(arr_pid[i] == signal){
52
64
 
53
65
  arr_pid[i] = -1;
54
66
 

10

コード修正

2017/11/20 01:48

投稿

ijuya_yika
ijuya_yika

スコア50

test CHANGED
File without changes
test CHANGED
@@ -140,7 +140,7 @@
140
140
 
141
141
  /* 入力がmy_psなrプロセスを出力 */
142
142
 
143
- if((strcmp(token[0], "my_ps")!=0)){
143
+ if((strcmp(token[0], "my_ps")==0)){
144
144
 
145
145
  printProcess();
146
146
 

9

コード修正

2017/11/20 01:36

投稿

ijuya_yika
ijuya_yika

スコア50

test CHANGED
File without changes
test CHANGED
@@ -140,7 +140,7 @@
140
140
 
141
141
  /* 入力がmy_psなrプロセスを出力 */
142
142
 
143
- if((strcmp(argv[0], "my_ps")!=0)){
143
+ if((strcmp(token[0], "my_ps")!=0)){
144
144
 
145
145
  printProcess();
146
146
 

8

コード修正

2017/11/20 01:34

投稿

ijuya_yika
ijuya_yika

スコア50

test CHANGED
File without changes
test CHANGED
@@ -34,7 +34,7 @@
34
34
 
35
35
 
36
36
 
37
- int* arr_pid[S] = {}; /* ここにプロセスが呼ばれる度新しいプロセスIDを登録 */
37
+ int arr_pid[S] = {}; /* ここにプロセスが呼ばれる度新しいプロセスIDを登録 */
38
38
 
39
39
 
40
40
 
@@ -46,11 +46,11 @@
46
46
 
47
47
  /* 子プロセスが終了したら子プロセスのPIDを-1に変える */
48
48
 
49
- for(int i=0; arr_pid[i] != NULL; ++i){ /** HELP2 **/
49
+ for(int i=0; arr_pid[i] != 0; ++i){ /** HELP2 **/
50
50
 
51
- if(sig == *(arr_pid[i])){
51
+ if(sig == arr_pid[i]){
52
52
 
53
- *(arr_pid[i]) = -1;
53
+ arr_pid[i] = -1;
54
54
 
55
55
  }
56
56
 
@@ -66,11 +66,11 @@
66
66
 
67
67
  int i;
68
68
 
69
- for(i=0; arr_pid[i] != NULL; ++i){
69
+ for(i=0; arr_pid[i] != 0; ++i){
70
70
 
71
- if(*(arr_pid[i]) != -1){
71
+ if(arr_pid[i] != -1){
72
72
 
73
- printf("PID: %d\n", *(arr_pid[i]));
73
+ printf("PID: %d\n", arr_pid[i]);
74
74
 
75
75
  }
76
76
 
@@ -98,7 +98,7 @@
98
98
 
99
99
  pid = getpid();
100
100
 
101
- arr_pid[num_p++] = &pid; /* 親プロセスのプロセスIDを取得しarr_pidに入れる */
101
+ arr_pid[num_p++]= pid; /* 親プロセスのプロセスIDを取得しarr_pidに入れる */
102
102
 
103
103
  signal(SIGCHLD, &removeProcess); /* 子プロセスが終了=>SIGCHLDシグナルが送られる度配列に入れたプロセスIDを-1に変更 */
104
104
 
@@ -172,17 +172,13 @@
172
172
 
173
173
  /* 子プロセスのプロセスIDを配列に格納 */
174
174
 
175
- pid_t temp = getpid();
175
+ arr_pid[num_p++] = pid;
176
176
 
177
- arr_pid[num_p++] = &temp;
178
-
179
- if(and==NULL){
177
+ if(and==NULL)
180
-
181
- printf("&が入力されなかったので子プロセスが終わるまで待ちます\n");
182
178
 
183
179
  wait(&status);
184
180
 
185
- }
181
+
186
182
 
187
183
  }
188
184
 

7

コード修正

2017/11/20 01:30

投稿

ijuya_yika
ijuya_yika

スコア50

test CHANGED
File without changes
test CHANGED
@@ -140,7 +140,7 @@
140
140
 
141
141
  /* 入力がmy_psなrプロセスを出力 */
142
142
 
143
- if((strcmp(argv[0], "my_ps")==0)){
143
+ if((strcmp(argv[0], "my_ps")!=0)){
144
144
 
145
145
  printProcess();
146
146
 

6

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

2017/11/20 01:15

投稿

ijuya_yika
ijuya_yika

スコア50

test CHANGED
File without changes
test CHANGED
@@ -34,7 +34,7 @@
34
34
 
35
35
 
36
36
 
37
- int* arr_pid[S] = {NULL}; /* ここにプロセスが呼ばれる度新しいプロセスIDを登録 */
37
+ int* arr_pid[S] = {}; /* ここにプロセスが呼ばれる度新しいプロセスIDを登録 */
38
38
 
39
39
 
40
40
 
@@ -48,9 +48,9 @@
48
48
 
49
49
  for(int i=0; arr_pid[i] != NULL; ++i){ /** HELP2 **/
50
50
 
51
- if((strcmp(arr_pid[i], sig))==0){
51
+ if(sig == *(arr_pid[i])){
52
52
 
53
- strcpy(arr_pid[i], -1);
53
+ *(arr_pid[i]) = -1;
54
54
 
55
55
  }
56
56
 
@@ -68,9 +68,9 @@
68
68
 
69
69
  for(i=0; arr_pid[i] != NULL; ++i){
70
70
 
71
- if(strcmp(arr_pid[i], -1)){
71
+ if(*(arr_pid[i]) != -1){
72
72
 
73
- printf("PID: %d\n", arr_pid[i]);
73
+ printf("PID: %d\n", *(arr_pid[i]));
74
74
 
75
75
  }
76
76
 

5

コード訂正

2017/11/20 01:07

投稿

ijuya_yika
ijuya_yika

スコア50

test CHANGED
File without changes
test CHANGED
@@ -96,9 +96,9 @@
96
96
 
97
97
 
98
98
 
99
- pid = getpid(); /* 親プロセスのプロセスIDを取得しarr_pidに入れる */
99
+ pid = getpid();
100
100
 
101
- arr_pid[num_p++] = &pid;
101
+ arr_pid[num_p++] = &pid; /* 親プロセスのプロセスIDを取得しarr_pidに入れる */
102
102
 
103
103
  signal(SIGCHLD, &removeProcess); /* 子プロセスが終了=>SIGCHLDシグナルが送られる度配列に入れたプロセスIDを-1に変更 */
104
104
 
@@ -172,7 +172,9 @@
172
172
 
173
173
  /* 子プロセスのプロセスIDを配列に格納 */
174
174
 
175
+ pid_t temp = getpid();
176
+
175
- arr_pid[num_p++] = &pid;
177
+ arr_pid[num_p++] = &temp;
176
178
 
177
179
  if(and==NULL){
178
180
 
@@ -194,10 +196,4 @@
194
196
 
195
197
  }
196
198
 
197
-
198
-
199
-
200
-
201
-
202
-
203
199
  ```

4

コード訂正

2017/11/20 00:48

投稿

ijuya_yika
ijuya_yika

スコア50

test CHANGED
File without changes
test CHANGED
@@ -160,30 +160,28 @@
160
160
 
161
161
  else if(pid==0){
162
162
 
163
+ if(execvp(token[0], token)<0){
164
+
165
+ printf("エラー : %s\n", strerror(errno));
166
+
167
+ exit(1);
168
+
169
+ }
170
+
171
+ } else {
172
+
163
173
  /* 子プロセスのプロセスIDを配列に格納 */
164
174
 
165
- pid_t temp = getpid(); /** HELP1 **/
166
-
167
- arr_pid[num_p++] = &temp;
175
+ arr_pid[num_p++] = &pid;
168
-
176
+
169
- if(execvp(token[0], token)<0){
177
+ if(and==NULL){
170
-
178
+
171
- printf("エラー : %s\n", strerror(errno));
179
+ printf("&が入力されなかったので子プロセスが終わるまで待ちます\n");
172
-
180
+
173
- exit(1);
181
+ wait(&status);
174
182
 
175
183
  }
176
184
 
177
- } else {
178
-
179
- if(and==NULL){
180
-
181
- printf("&が入力されなかったので子プロセスが終わるまで待ちます\n");
182
-
183
- wait(&status);
184
-
185
- }
186
-
187
185
  }
188
186
 
189
187
  }
@@ -200,4 +198,6 @@
200
198
 
201
199
 
202
200
 
201
+
202
+
203
203
  ```

3

コード訂正

2017/11/19 23:46

投稿

ijuya_yika
ijuya_yika

スコア50

test CHANGED
File without changes
test CHANGED
@@ -152,6 +152,8 @@
152
152
 
153
153
 
154
154
 
155
+
156
+
155
157
  if(pid==-1)
156
158
 
157
159
  exit(-1);
@@ -160,9 +162,9 @@
160
162
 
161
163
  /* 子プロセスのプロセスIDを配列に格納 */
162
164
 
163
- arr_pid[num_p++] = &pid; /** HELP1 **/
165
+ pid_t temp = getpid(); /** HELP1 **/
166
+
164
-
167
+ arr_pid[num_p++] = &temp;
165
-
166
168
 
167
169
  if(execvp(token[0], token)<0){
168
170
 
@@ -196,4 +198,6 @@
196
198
 
197
199
 
198
200
 
201
+
202
+
199
203
  ```

2

コード訂正

2017/11/19 23:43

投稿

ijuya_yika
ijuya_yika

スコア50

test CHANGED
File without changes
test CHANGED
@@ -150,8 +150,6 @@
150
150
 
151
151
  pid = fork();
152
152
 
153
- arr_pid[num_p++] = &pid;
154
-
155
153
 
156
154
 
157
155
  if(pid==-1)
@@ -161,8 +159,6 @@
161
159
  else if(pid==0){
162
160
 
163
161
  /* 子プロセスのプロセスIDを配列に格納 */
164
-
165
- pid = getpid();
166
162
 
167
163
  arr_pid[num_p++] = &pid; /** HELP1 **/
168
164
 

1

質問訂正

2017/11/19 23:34

投稿

ijuya_yika
ijuya_yika

スコア50

test CHANGED
@@ -1 +1 @@
1
- 自作シェルでpsコマンドを自作したい
1
+ 自作シェルでシグナルハンドラを使ってpsコマンドを自作したい
test CHANGED
@@ -1,7 +1,203 @@
1
1
  ###前提・実現したいこと
2
2
 
3
- C言語の自作シェル内でpsコマンドを使わずに現在動いてるプロセスとコマンド内容を表示する機能せたのですが、どのように実装すればよいでしょうか。
3
+ C言語の自作シェル内でシグナルハンドラを使って自作`psコマンド`(現在動いてるプロセスのIDを表示するという簡単な関数)作成したい
4
+
5
+
6
+
7
+
8
+
4
-
9
+ ###発生している問題・エラーメッセージ
10
+
5
-
11
+ (1)HELP1で子プロセスを配列に格納する際に親プロセスと同じプロセスIDが格納されてしまう
12
+
6
-
13
+ (2)HELP2でセグメンテーション違反が起こる
14
+
15
+
16
+
17
+ ###該当のソースコード
18
+
19
+ ```C
20
+
21
+ #include <stdio.h>
22
+
23
+ #include <stdlib.h>
24
+
25
+ #include <unistd.h>
26
+
27
+ #include <string.h>
28
+
29
+ #include <sys/wait.h>
30
+
31
+ #include <errno.h>
32
+
33
+ #define S 1000
34
+
35
+
36
+
37
+ int* arr_pid[S] = {NULL}; /* ここにプロセスが呼ばれる度新しいプロセスIDを登録 */
38
+
39
+
40
+
41
+ void removeProcess(int sig){
42
+
43
+ pid_t pid;
44
+
45
+ while((pid = waitpid(-1, NULL, WNOHANG)) > 0){
46
+
47
+ /* 子プロセスが終了したら子プロセスのPIDを-1に変える */
48
+
49
+ for(int i=0; arr_pid[i] != NULL; ++i){ /** HELP2 **/
50
+
51
+ if((strcmp(arr_pid[i], sig))==0){
52
+
53
+ strcpy(arr_pid[i], -1);
54
+
55
+ }
56
+
57
+ }
58
+
59
+ }
60
+
61
+ }
62
+
63
+
64
+
65
+ void printProcess(){
66
+
67
+ int i;
68
+
69
+ for(i=0; arr_pid[i] != NULL; ++i){
70
+
71
+ if(strcmp(arr_pid[i], -1)){
72
+
73
+ printf("PID: %d\n", arr_pid[i]);
74
+
75
+ }
76
+
77
+ }
78
+
79
+ }
80
+
81
+
82
+
83
+ int main(int argc, char *argv[]){
84
+
85
+ char* token[S];
86
+
87
+ char* eof;
88
+
89
+ char* and;
90
+
91
+ char usrin[S];
92
+
93
+ int pid, status, count, num_p = 0;
94
+
95
+
96
+
97
+
98
+
7
- 親プロセスに関しては`getpid()`でプロセスIDを、`argv[0]`で実行ファイル名を取得を出来ますが子プロセス関して何かよい方法があば教えて頂きたいです。
99
+ pid = getpid(); /* 親プロセスのプロセスIDを取得しarr_pidる */
100
+
101
+ arr_pid[num_p++] = &pid;
102
+
103
+ signal(SIGCHLD, &removeProcess); /* 子プロセスが終了=>SIGCHLDシグナルが送られる度配列に入れたプロセスIDを-1に変更 */
104
+
105
+
106
+
107
+ while(1){
108
+
109
+ printf(">>");
110
+
111
+ eof = fgets(usrin, sizeof(usrin), stdin);
112
+
113
+
114
+
115
+ if(eof==NULL)
116
+
117
+ exit(0);
118
+
119
+
120
+
121
+ usrin[strlen(usrin)-1] = '\0';
122
+
123
+ and = strchr(usrin, '&');
124
+
125
+
126
+
127
+ token[0] = strtok(usrin, " ");
128
+
129
+ for(count=1; count<S; ++count){
130
+
131
+ token[count] = strtok(NULL, " ");
132
+
133
+ if(token[count]==NULL)
134
+
135
+ break;
136
+
137
+ }
138
+
139
+
140
+
141
+ /* 入力がmy_psなrプロセスを出力 */
142
+
143
+ if((strcmp(argv[0], "my_ps")==0)){
144
+
145
+ printProcess();
146
+
147
+ } else {
148
+
149
+ /* my_ps 以外なら入力されたコマンドを実行 */
150
+
151
+ pid = fork();
152
+
153
+ arr_pid[num_p++] = &pid;
154
+
155
+
156
+
157
+ if(pid==-1)
158
+
159
+ exit(-1);
160
+
161
+ else if(pid==0){
162
+
163
+ /* 子プロセスのプロセスIDを配列に格納 */
164
+
165
+ pid = getpid();
166
+
167
+ arr_pid[num_p++] = &pid; /** HELP1 **/
168
+
169
+
170
+
171
+ if(execvp(token[0], token)<0){
172
+
173
+ printf("エラー : %s\n", strerror(errno));
174
+
175
+ exit(1);
176
+
177
+ }
178
+
179
+ } else {
180
+
181
+ if(and==NULL){
182
+
183
+ printf("&が入力されなかったので子プロセスが終わるまで待ちます\n");
184
+
185
+ wait(&status);
186
+
187
+ }
188
+
189
+ }
190
+
191
+ }
192
+
193
+ }
194
+
195
+
196
+
197
+ return 0;
198
+
199
+ }
200
+
201
+
202
+
203
+ ```