11102009 Linux
shをつくる
p.341
char *cp, *malloc();
これはi686-apple-darwin9-gcc-4.0.1だとエラーが出る
psh1.c:43: error: conflicting types for ‘malloc’
なので以下のように修正
char *cp;
extern void *malloc();
11102009 Linux
shをつくる
p.341
char *cp, *malloc();
これはi686-apple-darwin9-gcc-4.0.1だとエラーが出る
psh1.c:43: error: conflicting types for ‘malloc’
なので以下のように修正
char *cp;
extern void *malloc();
11102009 Linux
別のプログラムを起動するプログラム
#include <stdio.h>
int main()
{
char *arglist[3];
arglist[0] = "ls";
arglist[1] = "-l";
arglist[2] = 0;
printf("* * * About to exec ls -l\n");
execvp( "ls" , arglist );
printf("* * * ls is done. bye\n");
}
arglist[2]に0が入ってるのがわからん。arglist[0]はプログラム名であり変更できる。
#include <stdio.h>
int main()
{
char *arglist[2];
arglist[0] = "sleeeeeeeeeeeP!";
arglist[1] = "10";
printf("* * * About to exec ls -l\n");
execvp( "sleep" , arglist );
printf("* * * ls is done. bye\n");
}
これを実行してpsで見てみると
$ ps
PID TTY TIME CMD
149 ttys000 0:00.06 -bash
86661 ttys002 0:00.21 -bash
87689 ttys002 0:00.01 sleeeeeeeeeeeP! 10
コマンド名は実行した側が任意につけられるのか。
10102009 Linux
引き続きcursesライブラリを使って。7章は理解しながら読むのにちょっと時間がかかった。
Unixでは非同期入力のためにO_ASYNCを使う方法とaio_readを使う二種類があるらしい。前者は入力が読み出せるようになったときにシグナルを送り、後者は入力を読んだあとにシグナルを送るらしい。
08102009 Linux
シグナル
#include <stdio.h>
#include <signal.h>
#define INPUTLEN 100
int main(int ac, char *av[])
{
void inthandler(int);
void quithandler(int);
char input[INPUTLEN];
int nchars;
signal( SIGINT, inthandler );
signal( SIGQUIT, quithandler );
do {
printf("\nType a message\n");
nchars = read(0, input, (INPUTLEN-1));
if ( nchars == -1 )
perror("read returned an error");
else {
input[nchars] = '\0';
printf("You typed: %s", input);
}
}
while( strncmp( input , "quit" , 4 ) != 0 );
}
void inthandler(int s)
{
printf(" Received signal %d .. waiting\n", s );
sleep(2);
printf(" Leaving inthandler \n");
}
void quithandler(int s)
{
printf(" Received signal %d .. waiting\n", s);
sleep(3);
printf(" Leaving quithandler \n");
}
実行してみる
Type a message
^C Received signal 2 .. waiting
^C^C^C Leaving inthandler
Received signal 2 .. waiting
Leaving inthandler
macbookでやってみると二番目のシグナルはブロックされて、三番目以降のシグナルは無視される。
06102009 Linux
interval timerを使うと定期的にシグナルを送れる。
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <signal.h>
int main()
{
void countdown(int);
signal(SIGALRM, countdown);
if ( set_ticker(50) == -1)
perror("set_ticker");
else
while( 1 )
pause();
return 0;
}
void countdown(int signum)
{
static int num = 10;
printf("%d ..", num--);
fflush(stdout);
if ( num < 0 ){
printf("DONE!\n");
exit(0);
}
}
int set_ticker( int n_msecs )
{
struct itimerval new_timeset;
long n_sec, n_usecs;
n_sec = n_msecs / 1000;
n_usecs = ( n_msecs % 1000 ) * 1000L;
new_timeset.it_interval.tv_sec = n_sec;
new_timeset.it_interval.tv_usec = n_usecs;
new_timeset.it_value.tv_sec = n_sec;
new_timeset.it_value.tv_usec = n_usecs;
return setitimer(ITIMER_REAL, &new_timeset, NULL);
}
sleepは秒単位だけどusleep使えばmicrosecondで一時停止できる
05102009 Linux
端末に関して、カノニカルモードとかノンブロッキングとか。あとシグナル処理。
端末を非カノニカル(cr)モードにするには
ノンブロッキングモードにするには
04102009 Linux
端末ドライバのプログラミング。
writeなんてコマンドがあるのか。
ioctlシステムコールにはほとんど触れてない。
04102009 Linux
pwdコマンドはinodeを親ディレクトリに辿っていく。ルートディレクトリは. と..が同じinodeを指す。
macbookでls -ia。
$ ls -ia /
2 ./ 31452 Users/
2 ../ 22730 Volumes/
ので.と..のinodeをチェックしながら再帰的に辿るという実装。
void printpathto( ino_t this_inode )
{
ino_t my_inode;
char its_name[BUFSIZ];
if ( get_inode( ".." ) != this_inode )
{
chdir( ".." );
inum_to_name(this_inode, its_name, BUFSIZ);
my_inode = get_inode( "." );
printpathto( my_inode );
printf("/%s",its_name );
}
}
03102009 Linux
lsを書く。
ファイルタイプとパーミッションを調べるのにマスキングを使う。
sys/stat.hのファイルタイプのとこ
/* File type */
#define S_IFMT 0170000 /* [XSI] type of file mask */
#define S_IFIFO 0010000 /* [XSI] named pipe (fifo) */
#define S_IFCHR 0020000 /* [XSI] character special */
#define S_IFDIR 0040000 /* [XSI] directory */
#define S_IFBLK 0060000 /* [XSI] block special */
#define S_IFREG 0100000 /* [XSI] regular */
#define S_IFLNK 0120000 /* [XSI] symbolic link */
#define S_IFSOCK 0140000 /* [XSI] socket */
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
#define S_IFWHT 0160000 /* whiteout */
#define S_IFXATTR 0200000 /* extended attribute */
#endif
man ls
b Block special file.
c Character special file.
d Directory.
l Symbolic link.
s Socket link.
p FIFO.
- Regular file.
03102009 Linux
システムコールを使ってcpコマンドを書く。
そのあと、バッファするバージョンのwhoコマンドを書く。