2011年12月20日火曜日

システムプログラミング:シグナル利用

Ctr+Z(SIGTSTP)を押したら経過時間を表示するプログラム


#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
time_t start;
int main(){
  void stop ();
  time (&start);
  // SIGTSTPが発生したら関数stopを実行
  signal (SIGTSTP, stop);
  while (1){
  sleep (1);
  printf (“ . “);
  fflush (stdout);
  }
  return EXIT_FAILURE;
}

void stop (){
  time_t end;
  time (&end);
  printf (“\n”);
  printf (“elapsed time= %ld seconds\n”, end-start);
  exit (EXIT_SUCCESS);
}

atmark@atde3:~/Desktop/work$ ./timer
 .  .  .  .  .  .  .  .  .  . ^Z\nelapsed time= 10 seconds

システムプログラミング:プロセス間通信(pipe利用)

親プログラムで入力したものを、子プログラムを処理し親プログラムに返す

[parent.c]
#include <stdio.h>
#include <stdlib.h>
#include <="" span="">types.h>
#include <="" span="">wait.h>
#include <unistd.h> 
int main(){
  char line[32];
  char read_fd[3], write_fd[3];
  int number, result;
  int fd[2];
  int st;
  if (pipe(fd) <0){
    perror("pipe");
    exit (EXIT_FAILURE);
  }

  snprintf (read_fd, sizeof (read_fd),"%d", fd[0]);
  snprintf (write_fd, sizeof (write_fd),"%d", fd[1]);
  fgets (line, sizeof (line), stdin);
  if (sscanf (line,"%d", &number) >0){
    if (fork () == 0){
      if (execl ("child", "child", read_fd, write_fd, NULL) <0){
        exit (EXIT_FAILURE);
      }
    }
    write (fd[1], &number, sizeof (number));
    wait (&st);
    read (fd[0], &result, sizeof (result));
    printf ("%d x %d = %d\n", number, number, result);
    close (fd[0]);
    close (fd[1]);
  }
  return EXIT_SUCCESS;
}


[child.c]
#include <stdlib.h>


#include <unistd.h>
int main (int argc, char *argv[]){
  int number, result;
  int read_fd, write_fd;
  // 引数の文字列を整数に変換
  read_fd = atoi (argv[1]);
  write_fd = atoi (argv[2]);
  // パイプラインからデータを読み込む
  read (read_fd, &number, sizeof (number));
  result = number*number;
  // パイプラインにデータを書き込む
  write (write_fd, &result, sizeof (result));
  close (read_fd);
  close (write_fd);
  return EXIT_SUCCESS;
}


atmark@atde3:~/Desktop/work$ ./parent
3
3 x 3 = 9\natmark@atde3:~/Desktop/work$

システムプログラミング:環境変数表示(envp[]利用)


環境変数を標準出力に出力

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char * argv[],char *envp[]){
  int i;
  for(i = 0; envp[i] != NULL; i++){
  printf("%s\n", envp[i]);
  }
  return EXIT_SUCCESS;
}

atmark@atde3:~/Desktop/work$ gcc -o newenv newenv.c
atmark@atde3:~/Desktop/work$ ./newenv

システムプログラミング:簡単シェル(execl利用)


forkで子プロセスを生成し、そこでexeclを使ってコマンドを実行する。

#include <stdio.h>
#include <stdlib.h>
#include wait.h>
#include <unistd.h>
int main(){
  char command[256],line[256];
  int st;
  static char prompt[64] = "> ";
  fprintf(stderr,"%s",prompt);
  while(fgets(line,sizeof(line),stdin) != NULL){
    if(sscanf(line,"%s",command) > 0){
      if(fork() == 0){
        if(execl(command,command,NULL) < 0){
          exit(EXIT_FAILURE);
        }
      }
else{
        wait(&st);
      }
    }
    fprintf(stderr,"%s",prompt);
  }
  return EXIT_SUCCESS;
}

atmark@atde3:~/work$ gcc -o nsh nsh.c
atmark@atde3:~/work$ ./nsh
> /bin/ls
lv  lv.c  lv2  lv2.c  nsh  nsh.c  nsh.c~