Archive

Archive for the ‘书山有路’ Category

APUE2e Exercise 8.2: vfork v.s. fork

November 10th, 2011 No comments
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
 * exercise8-2.c
 *
 *  Created on: Nov 10, 2011
 *      Author: zhuhuang
 */
 
#include <apueerr.h>
 
int glob = 6;
 
int callvfork(void)
{
	int var=88;
	pid_t pid;
 
	//compare the running results using vfork and fork
 
	/* Using fork
	in main first:4656
	before callvfork
	in callvfork parent:4656
	glob: 6, var: 88
	in main second:4656
	after callvfork
	before anothercall
	in anothercall:4656
	after anothercall
	in callvfork child:4661
	in main second:4661
	after callvfork
	before anothercall
	in anothercall:4661
	after anothercall
	*/
 
	/* Using vfork
	in main first:4608
	before callvfork
	in callvfork child:4613
	in main second:4613
	after callvfork
	before anothercall
	in anothercall:4613
	after anothercall
	in callvfork parent:4608
	glob: 7, var: 2077184
	*/
 
	if((pid = fork()) < 0){
		err_sys("vfork error");
	}else if(pid == 0){
		//the increasing of the variables done by the child changes the values in the parent
		glob++;
		printf("in callvfork child:%dn", getpid());
		return 0;
	}
 
	printf("in callvfork parent:%dn", getpid());
	printf("glob: %d, var: %dn", glob, var);  //var is
}
 
int anothercall(void)
{
	int i;
	int buf[100];
 
	for(i=0;i<100;i++)
		buf[i]=1;
 
	printf("in anothercall:%dn", getpid());
}
 
int main(void)
{
	printf("in main first:%dn", getpid());
 
	printf("before callvforkn");
	callvfork();
 
	//Using vfork: child process continues to execute the following code. But parent process doesn't.
	//Using fork: both child and parent processes execute the following code.
	printf("in main second:%dn", getpid());
 
	printf("after callvforkn");
	printf("before anothercalln");
	anothercall();
	printf("after anothercalln");
 
	exit(0);
}
Categories: 书山有路 Tags: , ,

Question1.6: Rotate an NxN matrix by 90 degrees – Cracking the Coding Interview

October 28th, 2011 No comments
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*
 * question1-6.c
 *
 *  Created on: Oct 28, 2011
 *      Author: zhuhuang
 */
 
//Give an image represented by an NxN matrix, where each pixel in the image is 4 bytes, write a method to rotate the image by
//90 degrees. Can you do this in place?
 
//Solution1: Consider the matrix as embedded circles, we rotate the circle one by one until reaching the center.
//Solution2: Build another matrix with the same size, copy elements from one to the other according to a formula
 
//In this program, we use solution 1.
#include <stdio.h>
#define NUM 6
 
int arrayA[][5] = {{1,2,3,4,5},
                  {6,7,8,9,10},
                  {11,12,13,14,15},
                  {16,17,18,19,20},
                  {21,22,23,24,25}
                 };
 
int arrayB[][6] = {{1,2,3,4,5,-1},
                  {6,7,8,9,10,-1},
                  {11,12,13,14,15,-1},
                  {16,17,18,19,20,-1},
                  {21,22,23,24,25,-1},
                  {26,27,28,29,30,-1}
                 };
 
void printMatrix(int matrix[][NUM], int sidelength)
{
	int i, j;
	for(i=0;i<sidelength;i++)
	{
		for(j=0;j<sidelength;j++)
		{
			printf("%d ",matrix[i][j]);
		}
		printf("n");
	}
}
 
void AntiClockWiseRotate(int matrix[][NUM], int sidelength)
{
	int N = sidelength;
	int i=0, j=0;
	int temp;
 
	//matrix[i][j] (before rotation)  => matrix[N-1-j][i] (after rotation)
	//Consider the matrix as embedded circles, we rotate the circle one by one until reaching the center.
	//How many circles: N/2. When N%2=1, N/2+1 circles; when N%2=0, N/2 circles.
	for(i=0; i<N/2; i++){
		//Rotate a row cause rotating the circle.
		//A row in the circle: i ~ N-1-i. The element in (N-1-i) will be the one in (i) after rotation.
		for(j=i;j<N-1-i;j++){
			//when i==N-1-i, only one element in the circle (the center), do nothing. This happens when N%2!=0.
			temp = matrix[i][j];
			matrix[i][j] = matrix[j][N-1-i];
			matrix[j][N-1-i] = matrix[N-1-i][N-1-j];
			matrix[N-1-i][N-1-j] = matrix[N-1-j][i];
			matrix[N-1-j][i] = temp;
		}
	}
}
 
int main(void)
{
	if(NUM==5)
	{
		printf("Matrix A before ratation:n");
		printMatrix(arrayA, 5);
 
		AntiClockWiseRotate(arrayA,5);
 
		printf("Matrix A after ratation:n");
		printMatrix(arrayA, 5);
	}
 
	if(NUM==6)
	{
		printf("Matrix B before ratation:n");
		printMatrix(arrayB, 6);
 
		AntiClockWiseRotate(arrayB,6);
 
		printf("Matrix B after ratation:n");
		printMatrix(arrayB, 6);
	}
 
	return 1;
}

APUE2e Exercise3.2

September 11th, 2011 2 comments

My implementation for APUE2e Exercise3.2: implement my own dup2 function that performs the same service as the dup2 function. Based on a little testing, it seems to work and behave as the provided dup2 function. I used the dup function to implement mydup2 function. However, I didn’t work on the error handling part, just succeed or fail.
Read more…

Categories: 书山有路 Tags: , ,

APUE2e Exercise3.6

September 11th, 2011 No comments

I was working exercise3.6 of APUE2e and the code was simple. But when I tried to use fgets and fputs to print out the file content, I got problems. Then I tried to figure out the reason. It turned out to be the null or ‘’ byte of C string, which prevent fgets and fputs from behaving as I expected (fgets appends null byte to the end of input buffer, while fputs prints null-terminated string). I solved the problem by preventing write function to write the null or ‘‘ byte for a C string to the file. This was done by restricting the number of bytes to be writen (using sizeof(buffer)-1, rather than sizeof(buffer)). These findings reminded me of my careless reading, because the problem was caused by a really small mistake. Now I learned the lesson. I prefer reading to writing codes. But through writing and testing, I learn more than just reading. I think I must do more coding and don’t get satisfied just by reading the books and codes.

Attaching is the code I wrote for exercise3.6.
Read more…

A test on mkstemp

September 2nd, 2011 No comments
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
 * testmkstemp.c
 *
 *  Created on: Aug 31, 2011
 *      Author: zhuhuang
 */
 
//int mkstemp(char *template);
 
#include <apueerr.h>
int main(void)
{
	int filedes;
	char *temp1 = "/home/zhuhuang/try1XXXXXX";
	char temp2[] = "/home/zhuhuang/try2XXXXXX";
 
	if((filedes = mkstemp(temp2)) == -1) //Succeed.
		err_sys("mkstemp error");
	printf("temp2: %sn", temp2);
 
	if((filedes = mkstemp(temp1)) == -1) //Fail!!!!!
		err_sys("mkstemp error");
	printf("temp1: %sn", temp1);
 
	exit(0);
}

The output is shown below:

temp2: /home/zhuhuang/try2anKX9s

Pay attention to the second call of mkstemp on temp1. It failed. Check the definition of temp1 and temp2, we will know the reason. For temp1, it is a pointer to a string literal “/home/zhuhuang/try1XXXXXX”, which is placed somewhere in the memory. The string literal is a constant. We can not use pointers that point to it to change its contents. That’s why mkstemp failed, since it tried to modify the contents pointed by temp1 to the name it has generated. For temp2, it is an array of characters. The string literal “/home/zhuhuang/try2XXXXXX” is used to initialized array temp2. But the contents of the array can be changed. So first call of mkstemp on temp2 succeeded.

Here is a page that will be useful for understanding character pointers: http://c-faq.com/~scs/cclass/krnotes/sx8e.html

Categories: 书山有路 Tags: , , ,

Something about setbuf

September 1st, 2011 2 comments

When I worked on Exercise 5.1 of APUE.2e, I made some discoveries about function setbuf : void setbuf(FILE *restrict fp, char *restrict buf).

First, setbuf doesn’t check whether buf has a size of BUFSIZ. It leaves the work to users to make sure that buf has a size of BUFSIZ. I thought it would check!!!

Second, when the stream to be set is associated with a terminal device, such as stdin, stdout and stderr, setbuf doesn’t set them to line buffered (when buf is not NULL), but fully buffered. My system is Ubuntu 10.04 (2.6.32-33-generic).

Below is the program I worked out. A litter messy.
Read more…

Categories: 书山有路 Tags: , , , ,

读书笔记 – APUE2e Chap4(2)

May 27th, 2011 2 comments

/////////////////////////////////////////////

stat, fstat, lstat

Specification:

#include<sys/stat.h>

int stat (const char *restrict pathname, struct stat *restrict buf);

int fstat(int filedes, struct stat *buf);

int lstat(const char *restrict pathname, struct stat *buf);

Return:

All three return: 0 if OK, –1 on error.

Comment:

Given a pathname, the stat function returns a structure of information about the named file.

The fstat function obtains information about the file that is already open on the descriptor filedes.

The lstat function is similar to stat, but when the named file is a symbolic link, lstat returns information about the symbolic link, not the file referenced by the symbolic link.

The returned information is filled in the structure pointed by buf. See 读书笔记 – APUE2e Chap4(1) for detail about struct stat.

 

/////////////////////////////////////////////

access

Specification:

#include<unistd.h>

int access(const char *pathname, int mode);

Return:

0 if OK, –1 on error.

Comment:

When we open a file, the kernel performs its access tests based on the effective user and group IDs. access allows testing the file accessibility based on the real user and group IDs. Similar strategies is used in the testing (Four steps). See 读书笔记 – APUE2e Chap4(1) File Access Test (replace effective with real in these four steps.)

The mode is bitwise OR of any of the following constants:

  • R_OK: test for read permission
  • W_OK: test for write permission
  • X_OK: test for execute permission
  • F_OK: test for existence of file

Read more…

读书笔记 – APUE2e Chap4(1)

May 19th, 2011 No comments

STAT

struct stat{

mode_t st_mode;  //file types and mode (permissions)

ino_t st_ino;  //i-node number (serial number)

dev_t st_dev;   //device number (file system)

dev_t st_rdev;  //device number for special files

nlink_t st_nlink;  //number of links

uid_t st_uid;  //user id of owner

gid_t st_gid;  //group id of owner

off_t st_size;   //size in bytes, for regular files

time_t st_atime;  //time of last access

time_t st_mtime;  //time of last modification

time_t st_ctime  //time of last file status change

blksize_t st_blksize;  //best I/O block size

blkcnt_t st_blocks;   //number of disk blocks allocated

}

//////////////////////////////////////////////////////////////////

File Types

Regular File: The most common type of file, which contains data of some form. There is no distinction to the UNIX kernel whether this data is text or binary.

Directory File: A file that contains the names of other files and pointers to information on these files.

Block Special File: A type of file providing buffered I/O access in fixed size units to devices such as disk drives.

Character Special File: A type of file providing unbuffered I/O access in variable-sized units to devices. (All devices on a system are either block special files or character special files.)

FIFO: A type of file used for communication between processes. It is sometimes called a named pipe.

Socket: A type of file used for network communication between processes.

Symbolic Link: A type of file that points to another file.

Read more…

读书笔记 – APUE2e Chap3(2)

May 14th, 2011 No comments

PREAD

Header: #include <unistd.h>

Declaration: ssize_t pread(int filedes, void *buf, size_t nbytes, off_t offset);

Return: number of bytes read, 0 if end of file, –1 on error

Parameters:

filedes: file descriptor

buf: buffer to store the contents that have been read

nbytes: number of bytes to be read

offset: offset from the start of the file

Comments:

Equivalent to: lseek+read, except that pread is atomic.

Reads up to nbytes bytes from file descriptor filedes at offset offset (from the start of the file) into the buffer starting at buf. The file offset is not changed.

The file referenced by filedes must be capable of seeking.

Read more…

读书笔记 – APUE2e Chap3(1)

May 13th, 2011 No comments

**********************************************

Unbuffered I/O (File I/O): each read or write invokes a system call in the kernel. Part of POSIX.1 and the Single Unix Specification, but not part of ISO C. Including open, read, write, lseek, close. (Different from Standard I/O)

**********************************************

file descriptor (say, filedes): 0<= filedes <= OPEN_MAX

0 (STDIN_FILENO in POSIX): standard input

1 (STDOUT_FILENO in POSIX): standard output

2 (STDERR_FILENO in POSIX): standard error

Read more…