簡易lnコマンド

ln -s source destとln source destの形式に対応。

#include < unistd.h >
#include < stdio.h >
#include < string.h >

int main(int argc, char **argv)
{
    int s_flag;
    
    if (
        argc <= 2 || argc >= 5 ||
        (s_flag = (strcmp(argv[1], "-s")==0), argc == 3 && s_flag)|| (argc == 4 && !s_flag))
    {
        fprintf(stderr, "Usage: %s [-s] source dest\n", argv[0]);
        return 1;
    }
    if (s_flag){
        if (symlink(argv[2], argv[3]) < 0){
            perror("symlink");
            return 1;
        }
    } else {
        if (link(argv[1], argv[2])< 0){
            perror("link");
            return 1;
        }
    }
    return 0;
}

簡易cp -pコマンド

コピー元のファイルのタイムスタンプ、ファイル所有者、ファイルモードをコピー先のファイルに設定。

#include < sys/types.h >
#include < sys/stat.h >
#include < fcntl.h >
#include < unistd.h >
#include < utime.h >
#include < stdio.h >

int main(int argc, char **argv)
{
    int fd_r, fd_w;
    ssize_t n;
    int err = 0;
    struct stat s_buf;
    struct utimbuf u_buf;
    char buf[4096];
    
    if (argc != 3){
        fprintf(stderr, "Usage: %s source dest\n", argv[0]);
        return 1;
    }
    
    if ((fd_r = open(argv[1], O_RDONLY)) < 0){
        perror(argv[1]);
        return 1;
    }
    
    if (fstat(fd_r, &s_buf) < 0){
        perror(argv[1]);
        return 1;
    }
    
    if ((fd_w = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0){
        perror(argv[2]);
        return 1;
    }
    
    while((n = read(fd_r, buf, sizeof buf)) > 0){
        if (write(fd_w, buf, n)< 0){
            perror(argv[2]);
            return 1;
        }
    }
    if (n < 0){
        perror(argv[1]);
        return 1;
}
    u_buf.actime = s_buf.st_atime;
    u_buf.modtime = s_buf.st_mtime;
    
    if (utime(argv[2], &u_buf)){
        perror(argv[2]);
        err = 1;
    }
    
    fchown(fd_w, s_buf.st_uid, s_buf.st_gid);
    
    if (fchmod(fd_w, s_buf.st_mode)<0){
        perror(argv[2]);
        err = 1;
    }
    return err;
}

簡易cpコマンド

#include < sys/types.h >
#include < sys/stat.h >
#include < fcntl.h >
#include < unistd.h >
#include < stdio.h >

int main (int argc, char ** argv)
{
    int fd_r, fd_w;
    ssize_t n;
    char buf[4096];
    
    if (argc != 3){
        fprintf(stderr, "Usage: %s source dest\n", argv[0]);
        return 1;
    }
    
    if ((fd_r = open(argv[1], O_RDONLY)) < 0){
        perror(argv[1]);
        return 1;
    }
    
    if ((fd_w = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0){
        perror(argv[2]);
        return 1;
    }
    while ((n = read(fd_r, buf, sizeof buf)) > 0){
        if(write(fd_w,buf, n)< 0){
            perror(argv[2]);
            return 1;
        }
    }
    if (n < 0){
        perror(argv[1]);
        return 1;
    }
    return 0;
}

簡易catコマンドの改良

#include < sys/types.h >
#include < sys/stat.h >
#include < fcntl.h >
#include < unistd.h >
#include < stdio.h >

static int
cat(int fd, char *file)
{
    ssize_t n;
    char buf[4096];
    
    while ((n = read(fd, buf, sizeof buf)) > 0){
        if(write(1, buf, n) < 0){
            perror("write");
            return 1;
        }
    }
    if (n < 0){
        perror(file);
        return 1;
    }
    return 0;
}

int main(int argc, char **argv)
{
    int i;
    int fd;
    int err = 0;
    
    if (argc <= 1){
        return cat(0, "stdin");
    }
    
    for (i = 1; i < argc; i++){
        if ((fd = open(argv[i], O_RDONLY)) < 0){
            perror(argv[i]);
            err = 1;
            continue;
        }
        err != cat(fd, argv[i]);
        
        if (close(fd) < 0){
            perror(argv[i]);
            err = 1;
        }
    }
    return err;
}

簡易catコマンド

#include < unistd.h >
#include < stdio.h >

int main(){
    ssize_t n;
    char buf[4096];
    
    while ((n = read(0, buf, sizeof buf)) > 0){
        if (write(1, buf, n)< 0){
            perror("write");
            return 1;
        }
    }
    if (n < 0){
        perror("read");
        return 1;
    }
    return 0;
}

簡易echoコマンド

#include < unistd.h >
#include < string.h >

int main(int argc, char **argv)
{
    int i;
    
    if (argc >= 2){
        for (i = 1;;){
            write (1, argv[i], strlen(argv[i]));
            if (++i >= argc){
                break;
            }
            write (1, " ", 1);
        }
    }
    write(1, "\n", 1);
    return 0;
}

接続先または自分のソケットアドレスを取得

#include < sys/socket.h >
#include < netinet/in.h >

#include < unistd.h >
#include < stdio.h >
#include < string.h >
#include < arpa/inet.h >

int main()
{
    struct sockaddr_in sv_addr, cl_addr;
    socklen_t sv_len, cl_len;
    
    sv_len = sizeof sv_addr;
    if(getsockname(0, (struct sockaddr *)&sv_addr, &sv_len) < 0){
        perror("getsockname");
        return 1;
    }
    
    fprintf(stderr, "getsockname: addr = %s, port = %d\n",
            inet_ntoa(sv_addr.sin_addr),
            ntohs(sv_addr.sin_port));
    
    cl_len = sizeof cl_addr;
    if (getpeername(0, (struct sockaddr *)&cl_addr, &cl_len)<0){
        perror("getpeername");
        return 1;
    }
    
    fprintf(stderr, "getpeername: addr = %s, port = %d\n",
            inet_ntoa(cl_addr.sin_addr),
            ntohs(cl_addr.sin_port));
    write(1, "Hello\n", 6);
    return 0;
}

sendto

#include < sys/types.h >
#include < sys/socket.h >
#include < netinet/in.h >

#include 
#include 

int main()
{
    int sock_fd;
    struct sockaddr_in sv_addr;
    ssize_t n;
    
    if ((sock_fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0){
        perror("socket");
        return 1;
    }
    
    memset(&sv_addr, 0, sizeof sv_addr);
    sv_addr.sin_family = AF_INET;
    sv_addr.sin_addr.s_addr =htonl(INADDR_LOOPBACK);
    sv_addr.sin_port = htons(12345);
    
    if ((n = sendto(sock_fd, "Hello\n", 6, 0,
                    (struct sockaddr *)&sv_addr, sizeof sv_addr)) < 0){
        perror("sendto");
        return 1;
    }
    return 0;
}

recvfrom

#include < sys/types.h >
#include < sys/socket.h >
#include < netinet/in.h >

#include < unistd.h >
#include < stdio.h >
#include < string.h >
#include < arpa/inet.h >

int main()
{
    int sock_fd;
    struct sockaddr_in sv_addr, cl_addr;
    socklen_t cl_len;
    ssize_t n;
    char buf[4096];
    if((sock_fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0){
        perror("socket");
        return 1;
    }
    
    memset(&sv_addr, 0, sizeof sv_addr);
    sv_addr.sin_family = AF_INET;
    sv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    sv_addr.sin_port = htons(12345);
    
    if (bind(sock_fd, (struct sockaddr *)&sv_addr, sizeof sv_addr)<0){
        perror("bind");
        return 1;
    }
    cl_len = sizeof cl_addr;
    
    if ((n = recvfrom(sock_fd, buf, sizeof buf, 0,
                      (struct sockaddr *)&cl_addr, &cl_len)) < 0){
        perror("recvfrom");
        return 1;
    }
    fprintf(stderr, "UDP from addr = %s, port = %d\n",
            inet_ntoa(cl_addr.sin_addr),
            ntohs(cl_addr.sin_port));
    write(1, buf, n);
    return 0;
}

ホスト名を取得

#include 
#include 

int main(){
    char name[256];
    
    if(gethostname(name, sizeof name)<0){
        perror("gethostname");
        return 1;
    }
    printf("%s\n", name);
    return 0;
}