<html>

<head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Chaoes</title>
<style>
<!--
table.MsoTableGrid
	{border:1.0pt solid windowtext;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.0pt;
	font-family:"Times New Roman"}
	table td.body{ 
		border-bottom: 1px #6699CC dotted;
		text-align: left;
		font-family: Verdana, sans-serif, Arial;
		font-weight: normal;
		font-size: 14px;
		color: #3A6BA5;
		background-color: #fafafa;
		padding: 6px;
	}
	
-->
</style>
</head>

<body>

<pre>              <b><font size="6" color="#FF0000"> When chaos begin...</font></b></pre>
<pre><font color="#FF0000"><b><span lang="en-ca">1. test dup and lseek:</span></b></font></pre>
<pre><font color="#0000FF"><span lang="en-ca">Question: If you dup an open file with another file-descriptor, does it lseek operation affects the read-write of </span></font></pre>
<pre><font color="#0000FF"><span lang="en-ca">file descriptor which it dups from?</span></font></pre>
<pre><font color="#0000FF"><span lang="en-ca">Answer: Of course, since they are actually pointing to the same file tables.</span></font></pre>
<pre><font color="#0000FF"><span lang="en-ca">(Hint: You have to compile it with g++ instead of gcc in &quot;sunset&quot;. Sucks!)</span></font></pre>
<pre>//#include	&lt;sys/types.h&gt;
#include 	&lt;stdio.h&gt;
#include        &lt;stdlib.h&gt;
#include	&lt;string.h&gt;
#include 	&lt;unistd.h&gt;
#include	&lt;fcntl.h&gt;
#include 	&lt;errno.h&gt;
#define  MaxBuf    20

int main(int argc, char *argv[])
{

	int fd1, fd2, n;
	char buf[MaxBuf+1];
	if (argc!=2)
	{
		printf(&quot;usage: file1.o file2\n&quot;);
		exit(errno);
	}
	if ((fd1=open(argv[1], O_RDONLY))==-1)
	{
		//perror(atoi(buf, fd1, 10));
		printf(&quot;open error\n&quot;);
	}

	fd2=dup(fd1);
	printf(&quot;%d read first %d\n&quot;, fd1,  MaxBuf);
	if ((n=read(fd1, buf, MaxBuf))==-1)
	{
		printf(&quot;file descriptor %d read error&quot;, fd1);
	}
	buf[n]='\0';
	printf(&quot;%d read this %s\n&quot;, fd1, buf);
	if ((n=read(fd1, buf, MaxBuf))==-1)
	{
		printf(&quot;file descriptor %d read error&quot;, fd1);
	}
	buf[n]='\0';
			

	printf(&quot;%d should read this line next %s\n&quot;, fd1, buf);
	printf(&quot;%d now seek back %d\n&quot;, fd1, n);
	if (lseek(fd1, -n, SEEK_CUR)==-1)
	{
		printf(&quot;%d seek back error\n&quot;, fd1);
	}
	printf(&quot; %d seek to beginning again\n&quot;, fd2);

	if (lseek(fd2, 0, SEEK_SET)==-1)
	{
		printf(&quot;seek error of %d\n&quot;, fd2);
	}
	printf(&quot;%d begin to read again\n&quot;, fd1);

	if ((n=read(fd1, buf, MaxBuf))==-1)
	{
		printf(&quot;%d read error\n&quot;, fd1);
	}
	buf[n]='\0';
	printf(&quot;%d read this line %s\n&quot;, fd1, buf);
}</pre>
<pre><font color="#FF0000"><b><span lang="en-ca">Result:</span></b></font></pre>
<pre><span lang="en-ca">3 read first 20
3 read this //#include &lt;sys/type
3 should read this line next s.h&gt;
#include &lt;stdi
3 now seek back 20
4 seek to beginning again
3 begin to read again
3 read this line //#include &lt;sys/type
</span></pre>
<pre><font color="#FF0000"><b><span lang="en-ca">2. test dup and lseek:</span></b></font></pre>
<pre><font color="#0000FF"><span lang="en-ca">Question: How do we implement &quot;ls&quot;? Actually this is just a re-do of my comp229 assignment. However, I just implement part of it.</span></font></pre>
<pre>#include &lt;sys/types.h&gt;
#include &lt;dirent.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;errno.h&gt;

const int MaxPathLength=128;
void dirView(char* dirName, char* pathName);
void errHandle(char* msg);
void myls();

int main(int argc, char* argv[])
{
	char fullPath[MaxPathLength];
	if (argc!=2)
	{
		printf(&quot;usage: dirview dirName\n&quot;);
		exit(1);
	}
	if (getcwd(fullPath, MaxPathLength)==NULL)
	{
		errHandle(&quot;getcwd error\n&quot;);
	}
	dirView(argv[1], fullPath);

	return 0;
}
	


void myls()
{
	char fullPath[MaxPathLength];
	if (getcwd(fullPath, MaxPathLength)==NULL)
	{
		errHandle(&quot;getcwd error\n&quot;);
	}
	dirView(&quot;.&quot;, fullPath);
}


void dirView(char* dirName, char* pathName)
{
	char fullPath[MaxPathLength];
	char fileName[MaxPathLength];
	DIR* dp;
	char* ptr;
	dirent* dirNode;
	struct stat statBuf;
	strcpy(fullPath, pathName);
	ptr=fullPath+strlen(fullPath);
	*ptr='/';
	ptr++;
	*ptr='\0';
	strcat(fullPath, dirName);
	if ((dp=opendir(fullPath))==NULL)
	{
		printf(&quot;fullpath=%s\n&quot;, fullPath);
		errHandle(&quot;error open directory\n&quot;);
	}
	printf(&quot;print directory of %s\n&quot;, fullPath);
	while ((dirNode=readdir(dp))!=NULL)
	{
		if (strcmp(dirNode-&gt;d_name, &quot;.&quot;)==0
		|| strcmp(dirNode-&gt;d_name, &quot;..&quot;)==0)
		{
			continue;
		}
		strcpy(fileName, fullPath);
		ptr=fileName+strlen(fileName);
		*ptr='/';
		ptr++;
		*ptr='\0';
		strcat(fileName, dirNode-&gt;d_name);
		if (lstat(fileName, &amp;statBuf)&lt;0)
		{
			printf(&quot;fileName=%s\n&quot;, fileName);
			errHandle(&quot;lstat error\n&quot;);
		}
		if (S_ISDIR(statBuf.st_mode))
		{
			//now fullPath is including the name
			dirView(dirNode-&gt;d_name, fullPath);
		}
		else
		{
			printf(&quot;regular file: %s\n&quot;, dirNode-&gt;d_name);
		}
	}
}
		
		
void errHandle(char* msg)
{
	perror(msg);
	exit(errno);
}
</pre>
<pre><font color="#FF0000"><b><span lang="en-ca">Result:</span></b></font></pre>
<pre><span lang="en-ca">print directory of /nfs/home/q/qingz_hu/comp444/files/mytest/mydir
regular file: arena.cpp
regular file: arena.o
regular file: arena.txt
regular file: dirview.c
regular file: dirview.o
regular file: io.c
regular file: io.c~
regular file: io.out
regular file: myhead.h
regular file: myhead.h~
regular file: mylib.c
regular file: mylib.c~
regular file: mylib.h
regular file: ourhdr.h
regular file: result.txt
regular file: test.txt
regular file: test.txt~
print directory of /nfs/home/q/qingz_hu/comp444/files/mytest/mydir/mynewdir
regular file: dirview.c
regular file: io.c
regular file: mylib.c<b><font color="#FF0000">
</font></b></span></pre>
<pre>　</pre>
<pre></pre>
<pre><font color="#FF0000"><b><span lang="en-ca"><a name="copyfile"></a>3. copy files:</span></b></font></pre>
<pre><font color="#0000FF"><span lang="en-ca">Question: Does a copy file system call exist in UNIX? Amazingly the answer is NO! And it is fairly straight-forward to do it.</span></font></pre>
<pre><span lang="en-ca"><font color="#0000FF">The only difference between my implementation and standard &quot;cp&quot; is that I will generate an error if target file already exists.</font></span></pre>
<pre>#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;errno.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;unistd.h&gt;


const int MaxBufLength=1024;
const int MaxPathLength=128;
//const int MaxMsgLength=32;
void copyfile(char* fullPath, char* newPath);

void errHandle(char* msg); 

//char msg[MaxMsgLength];


int main(int argc, char* argv[])
{
	if (argc!=3)
	{
		errHandle(&quot;usage: copyfile source target&quot;);
	}
	
	copyfile(argv[1], argv[2]);
	return 0;
}


void errHandle(char* msg)
{
	perror(msg);
	exit(errno);
}



void copyfile(char* fullPath, char* newPath)
{
	int fdOld, fdNew, n;
	char buf[MaxBufLength];
	struct stat statBuf;
	if ((fdOld=open(fullPath, O_RDONLY))&lt;0)
	{
		//perror(&quot;file not exists&quot;);
		//exit(errno);
		errHandle(&quot;file not exists&quot;);
	}
	if (lstat(fullPath, &amp;statBuf)&lt;0)
	{
		errHandle(&quot;stat error&quot;);
	}
		
	if ((fdNew=open(newPath, O_WRONLY|O_CREAT |O_EXCL, statBuf.st_mode))==-1)
	{
		errHandle(&quot;creat error or file already exists&quot;);
	}
	  
	while ((n=read(fdOld, buf, MaxBufLength))!=0)
	{
		if (n&lt;0)
		{
			errHandle(&quot;read old file error&quot;);
		}
		if (write(fdNew, buf, n)!=n)
		{
			errHandle(&quot;write new file error&quot;);
		}
	}
	if (close(fdOld)&lt;0)
	{
		errHandle(&quot;cannot close old file&quot;);
	}
	if (close(fdNew)&lt;0)
	{
		errHandle(&quot;cannot close new file&quot;);
	}
}
	
</pre>
<pre><font color="#FF0000"><b><span lang="en-ca">Result: Originally I worried a lot about the path of both source and target file because I am not sure if I need</span></b></font></pre>
<pre><span lang="en-ca"><font color="#FF0000"><b>require user to give full path name of both source and target because it would be inconvenient to ask user to copy</b></font></span></pre>
<pre><span lang="en-ca"><font color="#FF0000"><b>some file in current working directory and give the long path name. After testing I was relieved since &quot;lstat&quot; is</b></font></span></pre>
<pre><span lang="en-ca"><font color="#FF0000"><b>NOT a basic system call and it can do a simple parsing job to see if the file name is relative or absolute. This </b></font></span></pre>
<pre><span lang="en-ca"><font color="#FF0000"><b>is something I discovered unexpectedly.</b></font></span></pre>
<pre><span lang="en-ca"><font color="#FF0000"><b>To run, just type ./copyfile.o source target</b></font></span></pre>
<pre>　</pre>
<pre><font color="#FF0000"><b><span lang="en-ca"><a name="binary"></a>4. binary formats:</span></b></font></pre>
<pre><font color="#0000FF"><span lang="en-ca">Question: I suspect that the UNIX programmers are either lazy or arrogant because they even didn't bother to implement a simple </span></font></pre>
<pre><span lang="en-ca"><font color="#0000FF">format of &quot;printf()&quot; which print the binary format of an integer. I use it quite often on windows version of &quot;printf()&quot; and </font></span></pre>
<pre><span lang="en-ca"><font color="#0000FF">logically assume it is also implemented in UNIX. It is not. So, I just practice by writing a simple one. The only reason I mention</font></span></pre>
<pre><span lang="en-ca"><font color="#0000FF">this simple code is that the problem of signed and unsigned integer. It takes me nearly one hour to figure out the problem is </font></span></pre>
<pre><span lang="en-ca"><font color="#0000FF">the &quot;atoi&quot; only return signed integer. Therefore in argument to &quot;main&quot; from command line, I cannot pass the biggest unsigned </font></span></pre>
<pre><span lang="en-ca"><font color="#0000FF">integer  4294967295. Before find this, I nearly begin suspect my memory about 2's complement. And indeed my memory  is as bad as</font></span></pre>
<pre><span lang="en-ca"><font color="#0000FF">that. You see, I even call this &quot;Euclid algorithm&quot;. What a joke? It is not GCD problem! Sigh... My memory!</font></span></pre>
<pre>　</pre>
<pre>#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;

void binary(unsigned int number, char* buf);

int main(int argc, char* argv[])
{
	unsigned int num=4294967295;
	char* buf=(char*)malloc(sizeof(int)*8+1);
	if (argc==1)
	{
		printf(&quot;because atoi function will not work with unsigned int, I cannot input biggest int by argument\n&quot;);
		binary(num, buf);
		printf(&quot;So, I have to display the largest number:%d like this %s\n&quot;, num, buf);
		exit(0);
	}
	if (argc==2)
	{
		num=atoi(argv[1]);
		printf(&quot;%u\n&quot;, num);
		//one byte equals 8 bits and extral byte for NULL	
		binary(num, buf);
		printf(&quot;%s\n&quot;);
	}
	
	return 0;
}

void binary(unsigned int number, char* buf)
{
	unsigned int size=sizeof(int)*8;
	unsigned int quotion=number, modulo=0;
	buf[size]='\0';
	//euclid algorithm goes from end to beginning
	do
	{
		size--;
		modulo=quotion%2;
		quotion/=2;
		buf[size]='0'+modulo;
	}
	while (size&gt;0);
}
	
</pre>
<pre>　</pre>
<pre>　</pre>
<pre>　</pre>
<pre><font color="#FF0000"><span lang="en-ca">This is the contents of running script file &quot;test&quot;:</span></font></pre>
<pre><span lang="en-ca">./printftest.o 12
./printftest.o 1024
./printftest.o 4294967295
./printftest.o
</span></pre>
<pre><font color="#FF0000"><span lang="en-ca">And I run it to redirect result to a result file:</span></font></pre>
<pre><span lang="en-ca">[qingz_hu@alamanni ~/mywork] % chmod +x test
[qingz_hu@alamanni ~/mywork] % ./test &gt;myresult.txt
</span></pre>
<pre><font color="#FF0000"><span lang="en-ca">Then you will see the running result as following:</span></font></pre>
<pre><font color="#FF0000"><span lang="en-ca">(Please note that the biggest unsigned int 4294967295 is interpreted by &quot;atoi&quot; as a signed int as </span>2147483647<span lang="en-ca"> which is roughly half</span></font></pre>
<pre><font color="#FF0000"><span lang="en-ca">of original one. I cannot find a unsigned version of &quot;atoi&quot;. I cannot even find help by &quot;man atoi&quot;. ????)</span></font></pre>
<pre>12
00000000000000000000000000001100
1024
00000000000000000000010000000000
2147483647
01111111111111111111111111111111
because atoi function will not work with unsigned int, I cannot input biggest int by argument
So, I have to display the largest number:-1 like this 11111111111111111111111111111111
</pre>
<pre><span lang="en-ca">	<a name="readlink"></a></span><b><font color="#FF0000"><span lang="en-ca">T</span>he strange behaviour of &quot;readlink&quot; </font></b>
</pre>
<pre><span lang="en-ca">In class professor showed us the strange behaviour of &quot;readlink&quot;. But I cannot re-do it myself:</span></pre>
<pre>I feel very curious of the strange behaviour of &quot;readlink&quot; during demo. So, I tried to redo it myself as following:

Create a symbolic link and then read the contents of it. However, it seems that &quot;readlink&quot; behaves normally by returning the number of bytes it read. Since the source code is not posted, I wonder if I missed something:

</pre>
<pre>#include &quot;myhead.h&quot;
//I don't like Steven's head file, so I define my own little one with included headers, constants
 
void myreadlink(char* pathName);

int main(int argc, char* argv[])
{
        //this little test first create a symbolic link and then read it
        if (argc!=3)
        {
                errHandle(&quot;usage: myreadlink.o targetPath, symlinkname\n&quot;);
        }
        if (symlink(argv[1], argv[2])&lt;0)
        {
                errHandle(&quot;symlink error\n&quot;);
        }
        printf(&quot;now read symbolic link %s\n&quot;, argv[2]);
        myreadlink(argv[2]);
        return 0;
}
 
void myreadlink(char* pathName)
{
        char buf[BuffSize];
        int n;
        if ((n=readlink(pathName, buf, BuffSize))&lt;0)
        {
                errHandle(&quot;readlink error\n&quot;);
        }
        buf[n]='\0';
        printf(&quot;%s is a softlink with contents of length of %d:%s\n&quot;, pathName,n, buf);
}
 
</pre>
<pre>

The running result is like this:

[qingz_hu@alamanni ~/mywork] % gcc myreadlink.c -o myreadlink.o

[qingz_hu@alamanni ~/mywork] % ./myreadlink.o ./nicktest mynewlink

now read symbolic link mynewlink

mynewlink is a softlink with contents of length of 10:./nicktest

[qingz_hu@alamanni ~/mywork] % 

</pre>
<pre>#include &lt;sys/types.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;errno.h&gt;
#include &lt;dirent.h&gt;
#include &lt;unistd.h&gt;

const int BuffSize=128;

void errHandle(char* msg);

void errHandle(char* msg)
{
        if (msg!=NULL)
        {
                perror(msg);
        }
        else
        {
                strerror(errno);
        }
        exit(errno);
}
</pre>
<pre>　</pre>
<pre>　</pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="logic.htm">      







                       <img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   
<a href="index.htm">
<img src="picture/up.gif" style="border: medium none" alt="up.gif (335 bytes)" width="35" height="32"></a>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<a href="Matrix.htm">
<img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35">            


</a>            


</p>

</body>

</html>