Showing posts with label Linux C. Show all posts
Showing posts with label Linux C. Show all posts
Sunday, February 26, 2012
Wednesday, January 11, 2012
[L] curses
curses里面封装了一下对terminal 还有cursor的用法,从我之前一篇blog也可以看出如果不封装是多么令人肾虚。
需要搞明白一点的是,前面是对terminal进行操作,这个是对X window进行操作。所以从本质上来讲是不一样的。但是用起来感觉没什么大不同。。
1. initscr(), endwin()
init之后,整个屏幕被刷掉,生成一个新屏幕。在这里只能用curses里面的printw,scanw之类的。因为这是它自己的屏幕。之后endwin()退出。
2. move(x,y)
封装得够简单了。
3. attron, attroff
对输出属性进行设置,试一下就知道了。
至于属性设置参考这里:
http://www.mkssoftware.com/docs/man3/curs_attr.3.asp
4. refresh()
把整个屏幕刷新一遍。比如initscr之后,如果不refresh,那么屏幕原来有的还在,很混乱。
本来应该是所有动作之后都应该refresh一下,但是有些试了下不要也行。个人猜测是覆盖的原因。如果有覆盖的话要refresh().
还有一点要注意的就是,必须有change 才会刷新。如果没有change还是不变的。如果没有change硬要刷新的话也行,用touchwin(WINDOW).
5. cbreak(), echo()
前者相当于之前的non-canonical,就是不是一行输入了。变成一个个输入,包括换行。
后者指定是否回显。
实践代码如下,因为都是终端运行即可见了,所以样例也不用贴了。
代码一:
*注意一点:中间getchar()的时候,不论输入什么也不会回显的。这是因为被流弄走了,但是不会保留在window上。而getstr(), getch()则会留在屏幕上,如果不把echo()关掉的话。
/*
* =====================================================================================
*
* Filename: screen1.c
*
* Description: Uses of curses.h
*
* Version: 1.0
* Created: Wednesday, January 11, 2012 02:55:22 HKT
* Revision: none
* Compiler: gcc
*
* Author: Hongchao Deng (fengjingchao), fengjingchao@gmail.com
* Company: Sun Yat-sen University
*
* =====================================================================================
*/
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <curses.h>
#define PW_LEN 256
#define NAME_LEN 256
/*
* === FUNCTION ======================================================================
* Name: main
* Description: main function
* =====================================================================================
*/
int
main ( int argc, char *argv[] )
{
/* Parameters */
char *scan_ptr;
char witch_one[] = "First Witch ";
char witch_two[] = "Second Witch ";
/* TODO */
initscr();
move(5,15);
attron(A_BOLD);
printw("%s", "Macintosh");
attroff(A_BOLD);
refresh();
getchar();
move(8,15);
attron(A_STANDOUT);
printw("Thunder and lighting");
attroff(A_STANDOUT);
refresh();
getchar();
move(10,10);
printw("TEST PRINT");
move(11,23);
printw("TEST PRINT");
refresh();
getchar();
attron(A_DIM);
scan_ptr = witch_one + strlen(witch_one) - 1;
while(scan_ptr != witch_one){
move(10,10);
insch(*--scan_ptr);
}
attroff(A_DIM);
refresh();
getchar();
move(LINES -1, COLS -1);
printw("%s",witch_two);
refresh();
getchar();
clear();
char name[NAME_LEN];
char password[PW_LEN];
char *real_password = "123456";
move(5,10);
printw("Please login");
move(7,10);
printw("User name: ");
getstr(name);
move(8,10);
printw("Password: ");
// refresh();
cbreak();
noecho();
memset(password,0,sizeof(password));
int i=0;
for(;i<PW_LEN;i++){
password[i] = getch();
if( password[i] == '\n') break;
move(8,20+i);
addch('*');
// refresh();
}
echo();
nocbreak();
endwin();
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */
××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
代码二:
展示多个window的情况
/*
* =====================================================================================
*
* Filename: multiw.c
*
* Description: Managing Multiple Windows
*
* Version: 1.0
* Created: Wednesday, January 11, 2012 07:42:44 HKT
* Revision: none
* Compiler: gcc
*
* Author: Hongchao Deng (fengjingchao), fengjingchao@gmail.com
* Company: Sun Yat-sen University
*
* =====================================================================================
*/
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <curses.h>
/*
* === FUNCTION ======================================================================
* Name: main
* Description: main function
* =====================================================================================
*/
int
main ( int argc, char *argv[] )
{
WINDOW *new_window_ptr;
WINDOW *popup_window_ptr;
int x_loop;
int y_loop;
char letter = 'a';
initscr();
move(5,5);
printw("Testing multiple windows");
refresh();
sleep(1);
for ( y_loop = 0;y_loop < LINES -1 ;++y_loop ) {
for (x_loop = 0; x_loop < COLS -1; ++x_loop) {
mvaddch(y_loop,x_loop,letter);
letter++;
if(letter >'z') letter = 'a';
}
}
refresh();
getchar();
new_window_ptr = newwin(10,20,5,5);
mvwprintw(new_window_ptr,2,5,"Testing multiple windows");
mvwprintw(new_window_ptr,5,10,"*********************************************************");
wrefresh(new_window_ptr);
getchar();
letter = '0';
for ( y_loop = 0;y_loop < LINES -1 ;++y_loop ) {
for (x_loop = 0; x_loop < COLS -1; ++x_loop) {
mvaddch(y_loop,x_loop,letter);
letter++;
if(letter >'9') letter = '0';
}
}
refresh();
getchar();
wrefresh(new_window_ptr);
getchar();
touchwin(new_window_ptr);
wrefresh(new_window_ptr);
getchar();
endwin();
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */
需要搞明白一点的是,前面是对terminal进行操作,这个是对X window进行操作。所以从本质上来讲是不一样的。但是用起来感觉没什么大不同。。
1. initscr(), endwin()
init之后,整个屏幕被刷掉,生成一个新屏幕。在这里只能用curses里面的printw,scanw之类的。因为这是它自己的屏幕。之后endwin()退出。
2. move(x,y)
封装得够简单了。
3. attron, attroff
对输出属性进行设置,试一下就知道了。
至于属性设置参考这里:
http://www.mkssoftware.com/docs/man3/curs_attr.3.asp
4. refresh()
把整个屏幕刷新一遍。比如initscr之后,如果不refresh,那么屏幕原来有的还在,很混乱。
本来应该是所有动作之后都应该refresh一下,但是有些试了下不要也行。个人猜测是覆盖的原因。如果有覆盖的话要refresh().
还有一点要注意的就是,必须有change 才会刷新。如果没有change还是不变的。如果没有change硬要刷新的话也行,用touchwin(WINDOW).
5. cbreak(), echo()
前者相当于之前的non-canonical,就是不是一行输入了。变成一个个输入,包括换行。
后者指定是否回显。
实践代码如下,因为都是终端运行即可见了,所以样例也不用贴了。
代码一:
*注意一点:中间getchar()的时候,不论输入什么也不会回显的。这是因为被流弄走了,但是不会保留在window上。而getstr(), getch()则会留在屏幕上,如果不把echo()关掉的话。
/*
* =====================================================================================
*
* Filename: screen1.c
*
* Description: Uses of curses.h
*
* Version: 1.0
* Created: Wednesday, January 11, 2012 02:55:22 HKT
* Revision: none
* Compiler: gcc
*
* Author: Hongchao Deng (fengjingchao), fengjingchao@gmail.com
* Company: Sun Yat-sen University
*
* =====================================================================================
*/
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <curses.h>
#define PW_LEN 256
#define NAME_LEN 256
/*
* === FUNCTION ======================================================================
* Name: main
* Description: main function
* =====================================================================================
*/
int
main ( int argc, char *argv[] )
{
/* Parameters */
char *scan_ptr;
char witch_one[] = "First Witch ";
char witch_two[] = "Second Witch ";
/* TODO */
initscr();
move(5,15);
attron(A_BOLD);
printw("%s", "Macintosh");
attroff(A_BOLD);
refresh();
getchar();
move(8,15);
attron(A_STANDOUT);
printw("Thunder and lighting");
attroff(A_STANDOUT);
refresh();
getchar();
move(10,10);
printw("TEST PRINT");
move(11,23);
printw("TEST PRINT");
refresh();
getchar();
attron(A_DIM);
scan_ptr = witch_one + strlen(witch_one) - 1;
while(scan_ptr != witch_one){
move(10,10);
insch(*--scan_ptr);
}
attroff(A_DIM);
refresh();
getchar();
move(LINES -1, COLS -1);
printw("%s",witch_two);
refresh();
getchar();
clear();
char name[NAME_LEN];
char password[PW_LEN];
char *real_password = "123456";
move(5,10);
printw("Please login");
move(7,10);
printw("User name: ");
getstr(name);
move(8,10);
printw("Password: ");
// refresh();
cbreak();
noecho();
memset(password,0,sizeof(password));
int i=0;
for(;i<PW_LEN;i++){
password[i] = getch();
if( password[i] == '\n') break;
move(8,20+i);
addch('*');
// refresh();
}
echo();
nocbreak();
endwin();
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */
××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
代码二:
展示多个window的情况
/*
* =====================================================================================
*
* Filename: multiw.c
*
* Description: Managing Multiple Windows
*
* Version: 1.0
* Created: Wednesday, January 11, 2012 07:42:44 HKT
* Revision: none
* Compiler: gcc
*
* Author: Hongchao Deng (fengjingchao), fengjingchao@gmail.com
* Company: Sun Yat-sen University
*
* =====================================================================================
*/
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <curses.h>
/*
* === FUNCTION ======================================================================
* Name: main
* Description: main function
* =====================================================================================
*/
int
main ( int argc, char *argv[] )
{
WINDOW *new_window_ptr;
WINDOW *popup_window_ptr;
int x_loop;
int y_loop;
char letter = 'a';
initscr();
move(5,5);
printw("Testing multiple windows");
refresh();
sleep(1);
for ( y_loop = 0;y_loop < LINES -1 ;++y_loop ) {
for (x_loop = 0; x_loop < COLS -1; ++x_loop) {
mvaddch(y_loop,x_loop,letter);
letter++;
if(letter >'z') letter = 'a';
}
}
refresh();
getchar();
new_window_ptr = newwin(10,20,5,5);
mvwprintw(new_window_ptr,2,5,"Testing multiple windows");
mvwprintw(new_window_ptr,5,10,"*********************************************************");
wrefresh(new_window_ptr);
getchar();
letter = '0';
for ( y_loop = 0;y_loop < LINES -1 ;++y_loop ) {
for (x_loop = 0; x_loop < COLS -1; ++x_loop) {
mvaddch(y_loop,x_loop,letter);
letter++;
if(letter >'9') letter = '0';
}
}
refresh();
getchar();
wrefresh(new_window_ptr);
getchar();
touchwin(new_window_ptr);
wrefresh(new_window_ptr);
getchar();
endwin();
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */
Tuesday, January 10, 2012
[L] termios, curses, Terminal Control
好吧,终于到 terminal 了。那真叫一个纠结,最后还是看完了。。
附上实践:
/*
* =====================================================================================
*
* Filename: menu.c
*
* Description: Reading Each Character,
* Without processing some signal characters even like C-c
* Using Terminal Control
*
* Version: 2.0
* Created: Wednesday, December 28, 2011 11:27:45 HKT
* Revision: none
* Compiler: gcc
*
* Author: Hongchao Deng (fengjingchao), fengjingchao@gmail.com
* Company: Sun Yat-sen University
*
* =====================================================================================
*/
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
#include <term.h>
#include <ncurses.h>
char *menu[] = {
"a - add new record",
"d - delete record" ,
"q - quit",
NULL
};
FILE *output_stream = NULL;
/*
* === FUNCTION ======================================================================
* Name: char_to_terminal
* Description: use output_stream to which the program writes the output.
* Otherwise in the getchoice() function we can use putp();
* =====================================================================================
*/
int
char_to_terminal ( int char_to_write )
{
if (output_stream) putc(char_to_write, output_stream);
return 0;
} /* ----- end of function char_to_terminal ----- */
/*
* === FUNCTION ======================================================================
* Name: getchoice
* Description: get the choice from prompt.
* it will simply discard any invalid input including chars like ^C
* =====================================================================================
*/
int
getchoice ( FILE *input, FILE *output)
{
int choice;
int chosen = 0;
int screenrow = 4, screencol = 10;
char **option;
char *cursor, *clear;
output_stream = output;
setupterm(0,1,0);
cursor = tigetstr("cup");
clear = tigetstr("clear");
tputs(clear, 1, char_to_terminal );
while(!chosen){
tputs(tparm(cursor,screenrow++,screencol), 1, char_to_terminal);
fprintf(output,"Please select an option:\n");
for(option = menu; *option != NULL; option++, screenrow++){
tputs(tparm(cursor,screenrow++,screencol), 1, char_to_terminal);
fprintf(output,"%s\n", *option);
}
for(choice = '\n'; choice == '\n';choice = fgetc(input));
for(option = menu; *option != NULL; option++){
if(choice == *option[0]){
chosen = 1; break;
}
}
if(!chosen) {
tputs(tparm(cursor,screenrow++,screencol), 1, char_to_terminal);
fprintf(output, "Incorrect choice: '%c'\n",choice);
}
}
tputs(clear, 1, char_to_terminal );
return choice;
} /* ----- end of function getchoice ----- */
/*
* === FUNCTION ======================================================================
* Name: main
* Description: main function
* =====================================================================================
*/
int
main ( int argc, char *argv[] )
{
int choice = 0;
FILE *input; /* input-file pointer */
input = fopen( "/dev/tty", "r" );
FILE *output;
output = fopen( "/dev/tty", "w");
if ( input == NULL || output == NULL ) {
fprintf ( stderr, "couldn't open file '%s'; %s\n",
"/dev/tty", strerror(errno) );
exit (EXIT_FAILURE);
}
struct termios initialSetting, newSetting;
tcgetattr(fileno(stdin),&initialSetting);
newSetting = initialSetting;
newSetting.c_lflag &= ~ISIG;
newSetting.c_lflag &= ~ECHO;
newSetting.c_cc[VMIN] = 1;
newSetting.c_cc[VTIME]= 0;
newSetting.c_lflag &= ~ICANON;
if(tcsetattr(fileno(stdin), TCSANOW , &newSetting) != 0)
fprintf(stderr, "Could not set terminal attributes!");
for(choice = 0; choice != 'q';){
choice = getchoice(input, output);
printf("You have chosen %c\n",choice);
sleep(1);
}
tcsetattr(fileno(stdin), TCSANOW , &initialSetting);
if( fclose(input) == EOF || fclose(output) == EOF ) {/* close input file */
fprintf ( stderr, "couldn't close file '%s'; %s\n",
"/dev/tty", strerror(errno) );
exit (EXIT_FAILURE);
}
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */
输出可以当场试,都已经是 terminal 了。。
总结一下:
功能:
1. 能调整光标的行列。
2. 能使得输入输出不显示,操作输入输出怎么读写。
经验:
1. setupterm就直接 setupterm(0,1,0), 不知道第二个参数 (flie descriptor) 干嘛用的。
2. 逃过stdout , 用‘/dev/tty’ .. 但是注意对terminal输出控制的时候不能用putp()了,要用tputs().
3. 其实操作terminal都是一堆字符输过去的,而且不同类型的terminal还有不同的控制方法,所以才有 curses这个库。
4. 父进程会直接将stdin这些copy到子进程里面,就是说如果不回复过来的话,那么terminal就变成那样了。。所以对std 三剑客in,out,err做修改之前一定要保存一份,程序结束后回复。
我也不太懂。。下次弄个牛逼一点的再写份好点的总结。这次算记录。。
Thursday, December 22, 2011
[C] Resource Limit in Linux
之前开会大师兄问了下 'ulimit' 在底层用什么搞的,今天刚好遇到,就顺便写下来了。
内部有个“sys/resource.h”的库,里面主要有3个重要功能:
1. rlimit
2. rusage
3. priority
rlimit 挺好理解。rusage 跟 priority 不太懂,跟系统底层有关:一个是相关信息,一个是调度的优先级。
下面直接贴代码:
/*
* =====================================================================================
*
* Filename: rlimit.c
*
* Description: Resources limit test
*
* Version: 1.0
* Created: Thursday, December 22, 2011 07:20:02 HKT
* Revision: none
* Compiler: gcc
*
* Author: Hongchao Deng (fengjingchao), fengjingchao@gmail.com
* Company: Sun Yat-sen University
*
* =====================================================================================
*/
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <unistd.h>
/*
* === FUNCTION ======================================================================
* Name: work
* Description: This function writes a string to a temporary file 10,000 times and then
* performs some arithmetic to generate load on CPU. HOW BAD...
* =====================================================================================
*/
void
work ( )
{
FILE *f;
int i;
double x = 4.5;
f = tmpfile();
// Writing about 10K to the tmp file
for (i = 0; i < 10000; i++) {
/* code */
fprintf(f, "Do some output.\n");
if( ferror(f) )
{
fprintf(stderr,"Error while writing to temporary file.\n");
exit(EXIT_FAILURE);
}
}
for (i = 0; i < 1000000; i++) {
/* code */
x = log(x*x+3.21);
}
} /* ----- end of function work ----- */
/*
* === FUNCTION ======================================================================
* Name: rusage_test
* Description:
* =====================================================================================
*/
void
rusage_test ( )
{
struct rusage r_usage;
work();
getrusage(RUSAGE_SELF, &r_usage);
printf("\n**************************************\n");
printf ( "rusage information:\n" );
printf ( " ru_utime:\n tv_sec.tv_usec: %ld.%06ld (s)\n",
r_usage.ru_utime.tv_sec, r_usage.ru_utime.tv_usec );
printf ( " ru_stime:\n tv_sec.tv_usec: %ld.%06ld (s)\n",
r_usage.ru_stime.tv_sec, r_usage.ru_stime.tv_usec );
} /* ----- end of function rusage_test ----- */
/*
* === FUNCTION ======================================================================
* Name: main
* Description: main function
* =====================================================================================
*/
int
main ( int argc, char *argv[] )
{
// parameters
struct rlimit r_limit;
// todo
rusage_test();
rusage_test();
rusage_test();
printf("\n**************************************\n");
printf("priority information:\n");
printf(" process priority: %d\n", getpriority(PRIO_PROCESS,getpid()));
printf(" group priority: %d\n", getpriority(PRIO_PGRP,getgid()));
printf(" user priority: %d\n", getpriority(PRIO_PGRP,getuid()));
printf("\n**************************************\n");
printf("rlimit information: (RLIM_INFINITY=%ld)\n", RLIM_INFINITY);
getrlimit(RLIMIT_CPU, &r_limit);
printf ( " rlimit_cpu:\n s: %ld ; h: %ld\n", r_limit.rlim_cur, r_limit.rlim_max );
getrlimit(RLIMIT_DATA, &r_limit);
printf ( " rlimit_data:\n s: %ld ; h: %ld\n", r_limit.rlim_cur, r_limit.rlim_max );
getrlimit(RLIMIT_FSIZE, &r_limit);
printf ( " rlimit_fsize:\n s: %ld ; h: %ld\n", r_limit.rlim_cur, r_limit.rlim_max );
getrlimit(RLIMIT_NOFILE, &r_limit);
printf ( " rlimit_nofile:\n s: %ld ; h: %ld\n", r_limit.rlim_cur, r_limit.rlim_max );
getrlimit(RLIMIT_NPROC, &r_limit);
printf ( " rlimit_nproc:\n s: %ld ; h: %ld\n", r_limit.rlim_cur, r_limit.rlim_max );
printf("\nNow try to set some limits:\n");
r_limit.rlim_cur = 1024; r_limit.rlim_max = RLIM_INFINITY;
setrlimit(RLIMIT_FSIZE, &r_limit);
work();
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */
输出样例:
**************************************
rusage information:
ru_utime:
tv_sec.tv_usec: 0.040002 (s)
ru_stime:
tv_sec.tv_usec: 0.000000 (s)
**************************************
rusage information:
ru_utime:
tv_sec.tv_usec: 0.084005 (s)
ru_stime:
tv_sec.tv_usec: 0.000000 (s)
**************************************
rusage information:
ru_utime:
tv_sec.tv_usec: 0.128008 (s)
ru_stime:
tv_sec.tv_usec: 0.000000 (s)
**************************************
priority information:
process priority: 0
group priority: -1
user priority: -1
**************************************
rlimit information: (RLIM_INFINITY=-1)
rlimit_cpu:
s: -1 ; h: -1
rlimit_data:
s: -1 ; h: -1
rlimit_fsize:
s: -1 ; h: -1
rlimit_nofile:
s: 1024 ; h: 4096
rlimit_nproc:
s: 15915 ; h: 15915
Now try to set some limits:
File size limit exceeded
感悟:
1. 调用getrusage的时候,只是得到当前耗掉的时间,这点在上面我用了几次work中体现出来了。
2. priority是数值越小,优先越高。
3. 普通人set的时候只能变弱,即priority+,limit - 。superuser有能力set,但是在内核限制的范围内。
4. 为什么要有soft & hard limit 两种呢?查了下,是因为soft 是能提高的,但是hard普通用户只能减少,这样有个限度。
References:
http://linux.about.com/library/cmd/blcmdl2_setrlimit.htm
http://linux.die.net/man/2/getrusage
http://linux.die.net/man/2/gettimeofday
http://linux.die.net/man/2/setpriority
http://linux.die.net/man/2/nice
内部有个“sys/resource.h”的库,里面主要有3个重要功能:
1. rlimit
2. rusage
3. priority
rlimit 挺好理解。rusage 跟 priority 不太懂,跟系统底层有关:一个是相关信息,一个是调度的优先级。
下面直接贴代码:
/*
* =====================================================================================
*
* Filename: rlimit.c
*
* Description: Resources limit test
*
* Version: 1.0
* Created: Thursday, December 22, 2011 07:20:02 HKT
* Revision: none
* Compiler: gcc
*
* Author: Hongchao Deng (fengjingchao), fengjingchao@gmail.com
* Company: Sun Yat-sen University
*
* =====================================================================================
*/
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <unistd.h>
/*
* === FUNCTION ======================================================================
* Name: work
* Description: This function writes a string to a temporary file 10,000 times and then
* performs some arithmetic to generate load on CPU. HOW BAD...
* =====================================================================================
*/
void
work ( )
{
FILE *f;
int i;
double x = 4.5;
f = tmpfile();
// Writing about 10K to the tmp file
for (i = 0; i < 10000; i++) {
/* code */
fprintf(f, "Do some output.\n");
if( ferror(f) )
{
fprintf(stderr,"Error while writing to temporary file.\n");
exit(EXIT_FAILURE);
}
}
for (i = 0; i < 1000000; i++) {
/* code */
x = log(x*x+3.21);
}
} /* ----- end of function work ----- */
/*
* === FUNCTION ======================================================================
* Name: rusage_test
* Description:
* =====================================================================================
*/
void
rusage_test ( )
{
struct rusage r_usage;
work();
getrusage(RUSAGE_SELF, &r_usage);
printf("\n**************************************\n");
printf ( "rusage information:\n" );
printf ( " ru_utime:\n tv_sec.tv_usec: %ld.%06ld (s)\n",
r_usage.ru_utime.tv_sec, r_usage.ru_utime.tv_usec );
printf ( " ru_stime:\n tv_sec.tv_usec: %ld.%06ld (s)\n",
r_usage.ru_stime.tv_sec, r_usage.ru_stime.tv_usec );
} /* ----- end of function rusage_test ----- */
/*
* === FUNCTION ======================================================================
* Name: main
* Description: main function
* =====================================================================================
*/
int
main ( int argc, char *argv[] )
{
// parameters
struct rlimit r_limit;
// todo
rusage_test();
rusage_test();
rusage_test();
printf("\n**************************************\n");
printf("priority information:\n");
printf(" process priority: %d\n", getpriority(PRIO_PROCESS,getpid()));
printf(" group priority: %d\n", getpriority(PRIO_PGRP,getgid()));
printf(" user priority: %d\n", getpriority(PRIO_PGRP,getuid()));
printf("\n**************************************\n");
printf("rlimit information: (RLIM_INFINITY=%ld)\n", RLIM_INFINITY);
getrlimit(RLIMIT_CPU, &r_limit);
printf ( " rlimit_cpu:\n s: %ld ; h: %ld\n", r_limit.rlim_cur, r_limit.rlim_max );
getrlimit(RLIMIT_DATA, &r_limit);
printf ( " rlimit_data:\n s: %ld ; h: %ld\n", r_limit.rlim_cur, r_limit.rlim_max );
getrlimit(RLIMIT_FSIZE, &r_limit);
printf ( " rlimit_fsize:\n s: %ld ; h: %ld\n", r_limit.rlim_cur, r_limit.rlim_max );
getrlimit(RLIMIT_NOFILE, &r_limit);
printf ( " rlimit_nofile:\n s: %ld ; h: %ld\n", r_limit.rlim_cur, r_limit.rlim_max );
getrlimit(RLIMIT_NPROC, &r_limit);
printf ( " rlimit_nproc:\n s: %ld ; h: %ld\n", r_limit.rlim_cur, r_limit.rlim_max );
printf("\nNow try to set some limits:\n");
r_limit.rlim_cur = 1024; r_limit.rlim_max = RLIM_INFINITY;
setrlimit(RLIMIT_FSIZE, &r_limit);
work();
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */
输出样例:
**************************************
rusage information:
ru_utime:
tv_sec.tv_usec: 0.040002 (s)
ru_stime:
tv_sec.tv_usec: 0.000000 (s)
**************************************
rusage information:
ru_utime:
tv_sec.tv_usec: 0.084005 (s)
ru_stime:
tv_sec.tv_usec: 0.000000 (s)
**************************************
rusage information:
ru_utime:
tv_sec.tv_usec: 0.128008 (s)
ru_stime:
tv_sec.tv_usec: 0.000000 (s)
**************************************
priority information:
process priority: 0
group priority: -1
user priority: -1
**************************************
rlimit information: (RLIM_INFINITY=-1)
rlimit_cpu:
s: -1 ; h: -1
rlimit_data:
s: -1 ; h: -1
rlimit_fsize:
s: -1 ; h: -1
rlimit_nofile:
s: 1024 ; h: 4096
rlimit_nproc:
s: 15915 ; h: 15915
Now try to set some limits:
File size limit exceeded
感悟:
1. 调用getrusage的时候,只是得到当前耗掉的时间,这点在上面我用了几次work中体现出来了。
2. priority是数值越小,优先越高。
3. 普通人set的时候只能变弱,即priority+,limit - 。superuser有能力set,但是在内核限制的范围内。
4. 为什么要有soft & hard limit 两种呢?查了下,是因为soft 是能提高的,但是hard普通用户只能减少,这样有个限度。
References:
http://linux.about.com/library/cmd/blcmdl2_setrlimit.htm
http://linux.die.net/man/2/getrusage
http://linux.die.net/man/2/gettimeofday
http://linux.die.net/man/2/setpriority
http://linux.die.net/man/2/nice
Monday, December 19, 2011
[C] ‘getopt()' function in Linux
先贴个网站(没错,是万恶又全能的Linux man page):
http://linux.die.net/man/3/getopt
再晒下自己代码:
测试用例:
好玩吧。。说说感悟:
1. 匹配出错的时候 '当前option' 放在 'optopt' 这个变量里面。
2. optind是一个个move的。。你看上面那个 '-f' 出错的时候直接 " -- optind " 解决了。
3. option有value 的话放在 'optarg' 里面.
4. getopt()的第三个参数 optstring 前面有个 "+" | "-" , 还有个什么POSIX*****之类的环境变量,无视他们。。用最基础的就行。顺便说说加了个 ‘:’(注意如果有 +-, +- 要放前面),主要是关注出错的时候是 1.没有value, 还是 2. option不识别。
5. getopt()是自动permute的,注意最后所有变量都放在 optind -- argc之间。。
getiopt_long() 是GNU扩展版。看了man page 的样例后说说感想:
1. optstring可以有数字字符,即 [0-9], 其他的不知道,也没必要知道。你看Linux命令有 '-*', '-%'这样的吗。。。
2. optarg: 如果没有 arg, optarg = 0. 这个特性可以方便编程。
http://linux.die.net/man/3/getopt
再晒下自己代码:
/*
* =====================================================================================
*
* Filename: argopt.c
*
* Description: Test example for 'getopt' function
*
* Version: 1.0
* Created: Monday, December 19, 2011 04:54:49 HKT
* Revision: none
* Compiler: gcc
*
* Author: Hongchao Deng (fengjingchao), fengjingchao@gmail.com
* Company: Sun Yat-sen University
*
* =====================================================================================
*/
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/*
* === FUNCTION ======================================================================
* Name: main
* Description: main function
* =====================================================================================
*/
int
main ( int argc, char *argv[] )
{
int opt;
while ( (opt = getopt(argc, argv, ":if:lr")) != -1 )
{
switch ( opt ) {
case 'i':
case 'l':
case 'r':
printf("option: %c\n",opt);
break;
case 'f':
if(optarg[0] != '-') printf ( "filename: %s\n",optarg );
else{
--optind;
printf ( "Option '-f' needs a value\n" );
}
break;
case ':':
printf ( "Option '-%c' needs a value\n", optopt );
break;
case '?':
printf ( "Unknown option: %c\n", optopt );
break;
default:
break;
} /* ----- end switch ----- */
}
for ( ; optind < argc; ++optind)
{
printf ( "argument: %s\n", argv[optind] );
}
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */
测试用例:
./argopt -i -lr -f -i -f filename -q "Hello,world"
option: i
option: l
option: r
Option '-f' needs a value
option: i
filename: filename
Unknown option: q
argument: Hello,world
好玩吧。。说说感悟:
1. 匹配出错的时候 '当前option' 放在 'optopt' 这个变量里面。
2. optind是一个个move的。。你看上面那个 '-f' 出错的时候直接 " -- optind " 解决了。
3. option有value 的话放在 'optarg' 里面.
4. getopt()的第三个参数 optstring 前面有个 "+" | "-" , 还有个什么POSIX*****之类的环境变量,无视他们。。用最基础的就行。顺便说说加了个 ‘:’(注意如果有 +-, +- 要放前面),主要是关注出错的时候是 1.没有value, 还是 2. option不识别。
5. getopt()是自动permute的,注意最后所有变量都放在 optind -- argc之间。。
getiopt_long() 是GNU扩展版。看了man page 的样例后说说感想:
1. optstring可以有数字字符,即 [0-9], 其他的不知道,也没必要知道。你看Linux命令有 '-*', '-%'这样的吗。。。
2. optarg: 如果没有 arg, optarg = 0. 这个特性可以方便编程。
Subscribe to:
Posts (Atom)