Программирование Linux
man – наше все!
$ man hello HELLO(1)  User Commands  HELLO(1) NAME   hello - friendly greeting program SYNOPSIS   hello [OPTION]... DESCRIPTION   Print a friendly, customizable greeting.   -h, --help   display this help and exit   -v, --version   display version information and exit   -t, --traditional   use traditional greeting format   -n, --next-generation   use next-generation greeting format   -g, --greeting=TEXT   use TEXT as the greeting message
Компиляция
GCC = препроцессор + компилятор + ассемблер + компоновщик cpp cc1, cc1plus, ... as collect2
$ cat hello.c #include <stdio.h> int main() {   printf(&quot;Hello World\n&quot;); } $ gcc -o hello hello.c $ ./hello Hello World
$ cat hello.c #include <stdio.h> int main() {   printf(&quot;Hello World\n&quot;) } $ gcc -o hello hello.c hello.c: In function 'main': hello.c:7: error: syntax error before '}' token
$ cat main.c int main() {   print_hello(); } $ cat hello.c #include <stdio.h> void print_hello() {   printf(&quot;Hello World\n&quot;); }
$ gcc -c main.c $ gcc -c hello.c $ ls hello.c hello.o main.c main.o $ gcc -o hello main.o hello.o $ ls hello* hello.c hello.o main.c main.o  $ ./hello Hello World
$ gcc -o hello hello.c main.c -Wall main.c: In function ‘main’: main.c:1:1: warning: implicit declaration of function ‘print_hello’ main.c:1:1: warning: control reaches end of non-void function  $ nm hello.o 00000000 T print_hello   U puts $ ldd hello linux-vdso.so.1 =>  (0x00110000) libc.so.6 => /lib/libc.so.6 (0x00a57000) /lib/ld-linux.so.2 (0x00a38000)
$ cat Makefile hello: main.o hello.o <--> gcc -o hello main.o hello.o main.o: main.c <--> gcc -c main.c hello.o: hello.c <--> gcc -c hello.c clean: <--> rm -f *.o hello http://habrahabr.ru/blogs/development/111691
$ make gcc -c main.c gcc -c hello.c gcc -o hello main.o hello.o $ ls hello hello.c hello.o main.c main.o Makefile
Логирование
void openlog(char *ident, int option,   int facility); void syslog(int priority, char *format, …); void closelog();
#include <syslog.h> int main() {   int i;   openlog(&quot;test&quot;, LOG_PID, LOG_USER);   syslog(LOG_DEBUG,&quot;try to sending 5 messages&quot;);   for (i = 0; i < 5; ++i)   syslog(LOG_INFO,&quot;info message [i = %i]&quot;,i);   closelog(); };
$ tail /var/log/debug Dec 20 11:25:04 linux test[6222]: try to sending 5 messages $ tail /var/log/messages Dec 20 11:25:04 linux test[6222]: info message [i = 0] Dec 20 11:25:04 linux test[6222]: info message [i = 1] Dec 20 11:25:04 linux test[6222]: info message [i = 2] Dec 20 11:25:04 linux test[6222]: info message [i = 3] Dec 20 11:25:04 linux test[6222]: info message [i = 4]
Библиотеки
$ cat hello.h void h_world(); void g_world(); $ cat hello.c #include <stdio.h> #include &quot;hello.h&quot; void h_world() {   printf(&quot;Hello World\n&quot;); }   void g_world() {   printf (&quot;Goodbye World\n&quot;); }
$ cat main.c #include &quot;hello.h&quot; int main() {   h_world();   g_world(); }
$ gcc -c main.c $ gcc -c hello.c $ ar cr libhello.a hello.o $ gcc -o hello main.o -L. -lhello $ ar t libhello.a  hello.o $ ar x libhello.a hello.o
$ gcc -c -fPIC -o hello.o hello.c $ gcc -shared -o libhello.so hello.o $ gcc -o hello -L. -lhello  main.c $ ./hello  ./hello: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory $ ldd hello   ...   libhello.so => not found   ...
$ gcc -o hello -L. -lhello -Wl,-rpath,. main.o $ ./hello Hello World Goodbye World $ ldd hello   libhello.so => ./libhello.so (0x00a57000) $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD
void *dlopen(char const *filename, int flag); void *dlsym(void *handle, char *symbol); dlclose(void *handle); компоновка -dl
#include <dlfcn.h> double pow(double x, double y); int main() {   void *library;  double (*power)(double, double);  library = dlopen(&quot;/lib/libmath.so&quot;,RTLD_LAZY);   if (!library)   return dlerror();   power = dlsym(library, “pow”);     dlclose(library); };
Переменные окружения
USER - имя текущего пользователя HOME - путь к домашнему каталогу текущего пользователя PATH - список каталогов, разделенных двоеточиями, в которых производится &quot;поиск&quot; программ PWD - текущий каталог OLDPWD - предыдущий текущий каталог SHELL - текущая командная оболочка HOSTNAME - имя машины QTDIR - расположение библиотеки QT LD_LIBRARY_PATH - место &quot;поиска&quot; дополнительных библиотек LANG - язык и кодировка пользователя DISPLAY - текущий дисплей в X11
extern char ** environ;  //declared in unistd.h char *getenv(char const *name); int setenv(char const *name, char const *value,  int overwrite); int unsetenv(char const *name);
Ввод-вывод
int open(char const* filename, int flags); int close(int fd); ssize_t read(int fd, void *buffer, size_t count); ssize_t write(int fd, const void * buffer, size_t count); off_t lseek(int fd, ott_t offset, int against);
#include <stdlib.h> #include <stdio.h> #include <unistd.h> // read(), write(), close() #include <fcntl.h> // open(), O_RDONLY #include <sys/stat.h> //S_IRUSR #include <sys/types.h> // mode_t #define BUFFER_SIZE 64 int main(int argc, char ** argv) {   int fd;   ssize_t read_bytes;   ssize_t written_bytes;   char buffer[BUFFER_SIZE];
if (argc < 2)   {   fprintf(stderr, &quot;Too few arguments\n&quot;);   exit (1);   }   fd = open(argv[1], O_RDONLY);   if (fd < 0)   {   fprintf(stderr, &quot;Cannot open file\n&quot;);   exit (1);   }
while ((read_bytes = read(fd, buffer,  BUFFER_SIZE)) > 0)   {   written_bytes = write(FILENO(stdout),  buffer, read_bytes);   if (written_bytes != read_bytes)   {   fprintf (stderr, &quot;Cannot write\n&quot;);   exit (1);   }   }
if (read_bytes < 0)   {   fprintf(stderr, &quot;myread: Cannot read  file\n&quot;);   exit (1);   }   close (fd);     return 0; }
Процессы
pid_t getpid();  //PID процесса pid_t getppid();  //PID родителя pid_t fork();  //клонирование процесса int execve(char const *path, char * const argv[],  char *const envp[]);  //замена образа
#include <unistd.h> #include <stdio.h> int main() {   char *echo_args[] = { &quot;echo&quot;, &quot;child&quot;, NULL};   if (fork())   printf(&quot;parent&quot;);   else   execve(&quot;/bin/echo&quot;, echo_args, environ);     return 0; }
IPC
int pipe(int pipefd[2]);  //неименованные каналы int mkfifo(char const *pathname,   mode_t mode);  //именованные каналы
#include <stdio.h> #include <string.h> #include <sys/types.h> int main (int argc, char * argv[]) {   int pipedes[2];   pid_t pid;   pipe(pipedes);   pid = fork();
if (pid > 0)   {   char *str = &quot;String passed via pipe\n&quot;;   close(pipedes[0]);   write(pipedes[1], (void *)str,  strlen(str) + 1);   close(pipedes[1]);   }
else   {   char buf[1024];   int len;   close(pipedes[1]);   while ((len = read(pipedes[0], buf,  1024)) != 0)   write(2, buf, len);   close(pipedes[0]);   }   return 0; }
Сокеты
int socket(int domain, int type, int protocol); int connect(int sockfd,   const struct sockaddr *addr,   socklen_t addrlen); int bind(int sockfd, const struct sockaddr *addr,   socklen_t addrlen); int listen(int sockfd, int backlog); int accept(int sockfd, struct sockaddr *addr,  socklen_t *addrlen); struct hostent *gethostbyname(char const *name);
sock = socket(AF_INET, SOCK_STREAM, 0); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(port); bind(sock, (struct sockaddr *)&serv_addr,  sizeof(serv_addr); listen(sock, 1); new_sock = accept(sock,   (struct sockaddr *)&new_addr,   &new_len);
server = gethostbyname(hostname); serv_addr.sin_family = AF_INET; memcpy(&serv_addr.sin_addr.s_addr,   server->h_addr, server->h_length); serv_addr.sin_port = htons(port); connect(sock, &serv_addr, sizeof(serv_addr);
Сигналы
#include <signal.h> void handler(int i) {   printf(&quot;Terminating\n&quot;);   exit(EXIT_FAILURE); } int main(int argc, char *argv[]) {   signal(SIGSEGV, handler);   kill(getpid(), SIGSEGV); }
SIGINT  – прервать выполнение, можно игнорировать SIGKILL – прервать выполнение, нельзя игнорировать SIGTERM – просьба завершиться SIGSEGV – ошибка памяти SIGCHLD – дочерний процесс завершился SIGSTOP – заморозить процесс SIGCONT – разморозить процесс SIGUSR1 – смысл по усмотрению пользователя
Нити
int pthread_create(pthread_t *thread,   pthread_attr_t const *attr,   void *(*start_routine) (void *),   void *arg); int pthread_join(pthread_t thread, void **retval); void pthread_exit(void *retval); int pthread_cancel(pthread_t thread); компоновка -pthread
#include <errno.h> #include <pthread.h> void *thread(void *arg) {   printf(&quot;Thread %i is running\n&quot;, *(int *)arg); }
int main(int argc, char * argv[]) {   int id1 = 1, id2 = 2;   pthread_t thread1, thread2;   pthread_create(&thread1, NULL, thread, &id1);   pthread_create(&thread2, NULL, thread, &id2);   pthread_join(thread1, NULL);   pthread_join(thread2, NULL);   return errno; }
Синхронизации
pthread_mutex_t   pthread_mutex_lock(mutex)   pthread_mutex_trylock(mutex)   pthread_mutex_unlock(mutex) pthread_cond_t   pthread_cond_wait(condition, mutex)   pthread_cond_signal(condition)   pthread_cond_broadcast(condition) pthread_rwlock_t pthread_barrier_t
IDE
QtCreator Code::Blocks Eclipse Vim Emacs NetBeans MonoDevelop ...

Программирование Linux

  • 1.
  • 2.
  • 3.
    $ man helloHELLO(1) User Commands HELLO(1) NAME hello - friendly greeting program SYNOPSIS hello [OPTION]... DESCRIPTION Print a friendly, customizable greeting. -h, --help display this help and exit -v, --version display version information and exit -t, --traditional use traditional greeting format -n, --next-generation use next-generation greeting format -g, --greeting=TEXT use TEXT as the greeting message
  • 4.
  • 5.
    GCC = препроцессор+ компилятор + ассемблер + компоновщик cpp cc1, cc1plus, ... as collect2
  • 6.
    $ cat hello.c#include <stdio.h> int main() { printf(&quot;Hello World\n&quot;); } $ gcc -o hello hello.c $ ./hello Hello World
  • 7.
    $ cat hello.c#include <stdio.h> int main() { printf(&quot;Hello World\n&quot;) } $ gcc -o hello hello.c hello.c: In function 'main': hello.c:7: error: syntax error before '}' token
  • 8.
    $ cat main.cint main() { print_hello(); } $ cat hello.c #include <stdio.h> void print_hello() { printf(&quot;Hello World\n&quot;); }
  • 9.
    $ gcc -cmain.c $ gcc -c hello.c $ ls hello.c hello.o main.c main.o $ gcc -o hello main.o hello.o $ ls hello* hello.c hello.o main.c main.o $ ./hello Hello World
  • 10.
    $ gcc -ohello hello.c main.c -Wall main.c: In function ‘main’: main.c:1:1: warning: implicit declaration of function ‘print_hello’ main.c:1:1: warning: control reaches end of non-void function $ nm hello.o 00000000 T print_hello U puts $ ldd hello linux-vdso.so.1 => (0x00110000) libc.so.6 => /lib/libc.so.6 (0x00a57000) /lib/ld-linux.so.2 (0x00a38000)
  • 11.
    $ cat Makefilehello: main.o hello.o <--> gcc -o hello main.o hello.o main.o: main.c <--> gcc -c main.c hello.o: hello.c <--> gcc -c hello.c clean: <--> rm -f *.o hello http://habrahabr.ru/blogs/development/111691
  • 12.
    $ make gcc-c main.c gcc -c hello.c gcc -o hello main.o hello.o $ ls hello hello.c hello.o main.c main.o Makefile
  • 13.
  • 14.
    void openlog(char *ident,int option, int facility); void syslog(int priority, char *format, …); void closelog();
  • 15.
    #include <syslog.h> intmain() { int i; openlog(&quot;test&quot;, LOG_PID, LOG_USER); syslog(LOG_DEBUG,&quot;try to sending 5 messages&quot;); for (i = 0; i < 5; ++i) syslog(LOG_INFO,&quot;info message [i = %i]&quot;,i); closelog(); };
  • 16.
    $ tail /var/log/debugDec 20 11:25:04 linux test[6222]: try to sending 5 messages $ tail /var/log/messages Dec 20 11:25:04 linux test[6222]: info message [i = 0] Dec 20 11:25:04 linux test[6222]: info message [i = 1] Dec 20 11:25:04 linux test[6222]: info message [i = 2] Dec 20 11:25:04 linux test[6222]: info message [i = 3] Dec 20 11:25:04 linux test[6222]: info message [i = 4]
  • 17.
  • 18.
    $ cat hello.hvoid h_world(); void g_world(); $ cat hello.c #include <stdio.h> #include &quot;hello.h&quot; void h_world() { printf(&quot;Hello World\n&quot;); } void g_world() { printf (&quot;Goodbye World\n&quot;); }
  • 19.
    $ cat main.c#include &quot;hello.h&quot; int main() { h_world(); g_world(); }
  • 20.
    $ gcc -cmain.c $ gcc -c hello.c $ ar cr libhello.a hello.o $ gcc -o hello main.o -L. -lhello $ ar t libhello.a hello.o $ ar x libhello.a hello.o
  • 21.
    $ gcc -c-fPIC -o hello.o hello.c $ gcc -shared -o libhello.so hello.o $ gcc -o hello -L. -lhello main.c $ ./hello ./hello: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory $ ldd hello ... libhello.so => not found ...
  • 22.
    $ gcc -ohello -L. -lhello -Wl,-rpath,. main.o $ ./hello Hello World Goodbye World $ ldd hello libhello.so => ./libhello.so (0x00a57000) $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD
  • 23.
    void *dlopen(char const*filename, int flag); void *dlsym(void *handle, char *symbol); dlclose(void *handle); компоновка -dl
  • 24.
    #include <dlfcn.h> doublepow(double x, double y); int main() { void *library; double (*power)(double, double); library = dlopen(&quot;/lib/libmath.so&quot;,RTLD_LAZY); if (!library) return dlerror(); power = dlsym(library, “pow”); dlclose(library); };
  • 25.
  • 26.
    USER - имятекущего пользователя HOME - путь к домашнему каталогу текущего пользователя PATH - список каталогов, разделенных двоеточиями, в которых производится &quot;поиск&quot; программ PWD - текущий каталог OLDPWD - предыдущий текущий каталог SHELL - текущая командная оболочка HOSTNAME - имя машины QTDIR - расположение библиотеки QT LD_LIBRARY_PATH - место &quot;поиска&quot; дополнительных библиотек LANG - язык и кодировка пользователя DISPLAY - текущий дисплей в X11
  • 27.
    extern char **environ; //declared in unistd.h char *getenv(char const *name); int setenv(char const *name, char const *value, int overwrite); int unsetenv(char const *name);
  • 28.
  • 29.
    int open(char const*filename, int flags); int close(int fd); ssize_t read(int fd, void *buffer, size_t count); ssize_t write(int fd, const void * buffer, size_t count); off_t lseek(int fd, ott_t offset, int against);
  • 30.
    #include <stdlib.h> #include<stdio.h> #include <unistd.h> // read(), write(), close() #include <fcntl.h> // open(), O_RDONLY #include <sys/stat.h> //S_IRUSR #include <sys/types.h> // mode_t #define BUFFER_SIZE 64 int main(int argc, char ** argv) { int fd; ssize_t read_bytes; ssize_t written_bytes; char buffer[BUFFER_SIZE];
  • 31.
    if (argc <2) { fprintf(stderr, &quot;Too few arguments\n&quot;); exit (1); } fd = open(argv[1], O_RDONLY); if (fd < 0) { fprintf(stderr, &quot;Cannot open file\n&quot;); exit (1); }
  • 32.
    while ((read_bytes =read(fd, buffer, BUFFER_SIZE)) > 0) { written_bytes = write(FILENO(stdout), buffer, read_bytes); if (written_bytes != read_bytes) { fprintf (stderr, &quot;Cannot write\n&quot;); exit (1); } }
  • 33.
    if (read_bytes <0) { fprintf(stderr, &quot;myread: Cannot read file\n&quot;); exit (1); } close (fd); return 0; }
  • 34.
  • 35.
    pid_t getpid(); //PID процесса pid_t getppid(); //PID родителя pid_t fork(); //клонирование процесса int execve(char const *path, char * const argv[], char *const envp[]); //замена образа
  • 36.
    #include <unistd.h> #include<stdio.h> int main() { char *echo_args[] = { &quot;echo&quot;, &quot;child&quot;, NULL}; if (fork()) printf(&quot;parent&quot;); else execve(&quot;/bin/echo&quot;, echo_args, environ); return 0; }
  • 37.
  • 38.
    int pipe(int pipefd[2]); //неименованные каналы int mkfifo(char const *pathname, mode_t mode); //именованные каналы
  • 39.
    #include <stdio.h> #include<string.h> #include <sys/types.h> int main (int argc, char * argv[]) { int pipedes[2]; pid_t pid; pipe(pipedes); pid = fork();
  • 40.
    if (pid >0) { char *str = &quot;String passed via pipe\n&quot;; close(pipedes[0]); write(pipedes[1], (void *)str, strlen(str) + 1); close(pipedes[1]); }
  • 41.
    else { char buf[1024]; int len; close(pipedes[1]); while ((len = read(pipedes[0], buf, 1024)) != 0) write(2, buf, len); close(pipedes[0]); } return 0; }
  • 42.
  • 43.
    int socket(int domain,int type, int protocol); int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); int listen(int sockfd, int backlog); int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); struct hostent *gethostbyname(char const *name);
  • 44.
    sock = socket(AF_INET,SOCK_STREAM, 0); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(port); bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr); listen(sock, 1); new_sock = accept(sock, (struct sockaddr *)&new_addr, &new_len);
  • 45.
    server = gethostbyname(hostname);serv_addr.sin_family = AF_INET; memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length); serv_addr.sin_port = htons(port); connect(sock, &serv_addr, sizeof(serv_addr);
  • 46.
  • 47.
    #include <signal.h> voidhandler(int i) { printf(&quot;Terminating\n&quot;); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { signal(SIGSEGV, handler); kill(getpid(), SIGSEGV); }
  • 48.
    SIGINT –прервать выполнение, можно игнорировать SIGKILL – прервать выполнение, нельзя игнорировать SIGTERM – просьба завершиться SIGSEGV – ошибка памяти SIGCHLD – дочерний процесс завершился SIGSTOP – заморозить процесс SIGCONT – разморозить процесс SIGUSR1 – смысл по усмотрению пользователя
  • 49.
  • 50.
    int pthread_create(pthread_t *thread, pthread_attr_t const *attr, void *(*start_routine) (void *), void *arg); int pthread_join(pthread_t thread, void **retval); void pthread_exit(void *retval); int pthread_cancel(pthread_t thread); компоновка -pthread
  • 51.
    #include <errno.h> #include<pthread.h> void *thread(void *arg) { printf(&quot;Thread %i is running\n&quot;, *(int *)arg); }
  • 52.
    int main(int argc,char * argv[]) { int id1 = 1, id2 = 2; pthread_t thread1, thread2; pthread_create(&thread1, NULL, thread, &id1); pthread_create(&thread2, NULL, thread, &id2); pthread_join(thread1, NULL); pthread_join(thread2, NULL); return errno; }
  • 53.
  • 54.
    pthread_mutex_t pthread_mutex_lock(mutex) pthread_mutex_trylock(mutex) pthread_mutex_unlock(mutex) pthread_cond_t pthread_cond_wait(condition, mutex) pthread_cond_signal(condition) pthread_cond_broadcast(condition) pthread_rwlock_t pthread_barrier_t
  • 55.
  • 56.
    QtCreator Code::Blocks EclipseVim Emacs NetBeans MonoDevelop ...