My apologies for using the following Unix-related program as an
example, but as my question is a simple one pertaining purely to C, I
feel I may be forgiven.... Anyway, I've noticed that when I write
simple programs using pointers, I inevitably get core dumps unless I
use malloc to assign memory first. However, the following program,
from a book by Stevens, uses pointers with gay abandon - but never
once uses malloc or any similar function. And it doesn't dump core.
Why is this?
Thanks,
David King
/*
* Example of server using UNIX domain stream protocol
*/
#include "uniks.h"
int readline(int, char *, int);
int writen(int, char *, int);
main(int argc, char *argv[])
{
int sockfd, newsockfd, clilen, childpid, servlen;
struct sockaddr_un cli_addr, serv_addr;
pname = argv[0];
/*
* Open a socket (a UNIX domain stream socket).
*/
if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
printf("server: can't open stream socket\n");
/*
* Bind our local address so that the client can send to us.
*/
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sun_family = AF_UNIX;
strcpy(serv_addr.sun_path, UNIXSTR_PATH);
servlen = sizeof(serv_addr.sun_family) + strlen(serv_addr.sun_path);
if (bind(sockfd, (struct sockaddr *) &serv_addr, servlen) < 0)
printf("server: can't bind local address\n");
listen(sockfd, 5);
for ( ; ;) {
clilen = sizeof(cli_addr);
if (newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen)
< 0)
printf("server: accept error\n");
if (childpid = fork() < 0)
printf("server: fork error\n");
else if (childpid == 0) { /* child process */
close(sockfd);
str_echo(newsockfd);
exit(0);
}
close(newsockfd);
}
Quote:
}
/*
* Read a stream socket one line at a time, and write each line back
* to the sender. Return when the connection is terminated.
*/
#define MAXLINE 512
str_echo(int sockfd)
{
int n;
char line[MAXLINE];
for( ; ; )
{
n = readline(sockfd, line, MAXLINE);
if (n == 0)
return; /* connection terminated */
else if (n < 0)
printf("str_echo: readline error\n");
if (writen(sockfd, line, n) != n)
printf("str_echo: writen error\n");
}
Quote:
}
/*
* Read a line from a descriptor. Read the line one byte at a time,
* looking for the newline. We store the newline in the buffer, then
* follow it with a null. We return the number of characters up to but
* not including the null.
*/
int readline(fd, ptr, maxlen)
register int fd;
register char *ptr;
register int maxlen;
{
int n, rc;
char c;
for(n = 1; n < maxlen; n++)
{
if ((rc = read(fd, &c, 1)) == 1)
{
*ptr++ = c;
if (c == '\n')
break;
}
else if (rc == 0)
{
if (n == 1)
return(0); /* EOF, no data read */
else
break;
}
else
return(-1); /* error */
}
*ptr = 0;
return(n);
Quote:
}
/* write n bytes to a descriptor. Use in place of write()
* when fd is a stream socket.
*/
int writen(register int fd, register char *ptr, register int nbytes)
{
int nleft, nwritten;
nleft = nbytes;
while (nleft > 0)
{
nwritten = write(fd, ptr, nleft);
if (nwritten <= 0)
return(nwritten); /* error */
nleft -= nwritten;
ptr += nwritten;
}
return(nbytes - nleft);
Quote:
}