forked from gzbykyasin/Unix-Linux_System_Programming
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPosix_functions.c
1599 lines (1018 loc) · 58.3 KB
/
Posix_functions.c
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
int getopt(int argc, char * const argv[],const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <getopt.h>
int getopt_long(int argc, char * const argv[],const char *optstring,const struct option *longopts, int *longindex);
int getopt_long_only(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <locale.h>
char* setlocale( int category, const char* locale );
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <stdio.h>
void perror(const char *str);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
char *getcwd(char *buf, size_t size);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
int chdir(const char *path);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
task_struct (files) ---> files_struct (fdt) ---> fdtable (fd) ---> file * türünden bir dizi ---> file
proses kontrol block ---> betimleyici tablosu --> dosya nesneleri (Kısaca)
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <fcntl.h>
int open(const char *path, int flags, ...);
O_RDONLY
O_WRONLY
O_RDWR
S_IRUSR
S_IWUSR
S_IXUSR
S_IRGRP
S_IWGRP
S_IXGRP
S_IROTH
S_IWOTH
S_IXOTH
S_IRWXU
S_IRWXG
S_IRWXO
#define S_IRWXU (S_IRUSR|S_IWUSR|S_IXUSR)
#define S_IRWXG (S_IRGRP|S_IWGRP|S_IXGRP)
#define S_IRWXO (S_IROTH|S_IWOTH|S_IXOTH)
S_IRWXU 0700
S_IRUSR 0400
S_IWUSR 0200
S_IXUSR 0100
S_IRWXG 070
S_IRGRP 040
S_IWGRP 020
S_IXGRP 010
S_IRWXO 07
S_IROTH 04
S_IWOTH 02
S_IXOTH 01
S_ISUID 04000
S_ISGID 02000
S_ISVTX 01000
S_IRUSR 100 000 000
S_IWUSR 010 000 000
S_IXUSR 001 000 000
S_IRGRP 000 100 000
S_IWGRP 000 010 000
S_IXGRP 001 001 000
S_IROTH 000 000 100
S_IWOTH 000 010 010
S_IXOTH 001 001 001
Standart C fopen POSIX
"w" O_WRONLY|O_CREAT|O_TRUNC
"w+" O_RDWR|O_CREAT|O_TRUNC
"r" O_RDONLY
"r+" O_RDWR
"a" O_WRONLY|O_CREAT|O_APPEND
"a+" O_RDWR|O_CREAT|O_APPEND
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <fcntl.h>
int creat(const char *path, mode_t mode);
int creat(const char *path, mode_t mode)
{
return open(path, O_WRONLY|O_CREAT|O_TRUNC, mode);
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t nbyte);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t nbyte);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
SEEK_SET
SEEK_CUR
SEEK_END
ör : lseek(fd, 0, SEEK_END);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <sys/stat.h>
mode_t umask(mode_t cmask);
mode_t mode;
mode = umask(0);
umask(mode);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <sys/stat.h>
int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* Inode number */
mode_t st_mode; /* File type and mode */
nlink_t st_nlink; /* Number of hard links */
uid_t st_uid; /* User ID of owner */
gid_t st_gid; /* Group ID of owner */
dev_t st_rdev; /* Device ID (if special file) */
off_t st_size; /* Total size, in bytes */
blksize_t st_blksize; /* Block size for filesystem I/O */
blkcnt_t st_blocks; /* Number of 512B blocks allocated */
/* Since Linux 2.6, the kernel supports nanosecond precision for the following timestamp fields.
For the details before Linux 2.6, see NOTES. */
struct timespec st_atim; /* Time of last access */
struct timespec st_mtim; /* Time of last modification */
struct timespec st_ctim; /* Time of last status change */
#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};
struct timespec {
time_t tv_sec;
long tv_nsec;
};
S_ISBLK(m) Blok aygıt sürücü dosyası mı? (ls -l'de 'b' dosya türü)
S_ISCHR(m) Karakter aygıt sürücü dosyası mı? (ls -l'de 'c' dosya türü)
S_ISDIR(m) Dizin dosyası mı? (ls -l'de 'd' dosya türü)
S_ISFIFO(m) Boru dosyası mı? (ls -l'de 'p' dosya türü)
S_ISREG(m) Sıradan bir disk dosyası mı? (ls -l'de '-' dosya türü)
S_ISLNK(m) Sembolik bağlantı dosyası mı? (ls -l'de 'l' dosya türü)
S_ISSOCK(m) Soket dosyası mı? (ls -l'de 's' dosya türü)
S_IFBLK Blok aygıt dosyası
S_IFCHR Karakter aygıt dosyası
S_IFIFO Boru dosyası
S_IFREG Sıradan disk dosyası
S_IFDIR Dizin dosyası
S_IFLNK Sembolik bağlantı dosyası
S_IFSOCK Soket dosyası
S_IFMT
(mode & S_IFMT) == S_IFXXX
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <stdio.h>
int remove(const char *path);
#include <unistd.h>
int unlink(const char *path);
remove'da unlink'te aynı işi yapıyor.
remove C fonksiyonudur. unlink ise POSIX fonksionudur
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <sys/stat.h>
int chmod(const char *path, mode_t mode);
int fchmod(int fd, mode_t mode);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
#ifdef _POSIX_CHOWN_RESTRICTED
printf("chown restricted\n");
#else
printf("chown not restricted\n");
#endif
return 0;
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
int chown(const char *path, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <sys/stat.h>
int mkdir(const char *path, mode_t mode);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
int rmdir(const char *path);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <pwd.h>
struct passwd *getpwnam(const char *name);
struct passwd *getpwuid(uid_t uid);
struct passwd {
char *pw_name; /* username */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* user information */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
};
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <pwd.h>
struct passwd *getpwent(void);
void setpwent(void);
void endpwent(void);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <grp.h>
struct group *getgrnam(const char *name);
struct group *getgrgid(gid_t gid);
struct group *getgrent(void);
void setgrent(void);
void endgrent(void);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <fcntl.h>
int openat(int fd, const char *path, int oflag, ...);
Fonksiyonun prototipini open fonksiyonu ile karşılaştırınız:
int open(const char *path, int oflag, ...);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
int fchmodat(int fd, const char *path, mode_t mode, int flag);
int fchownat(int fd, const char *path, uid_t owner, gid_t group, int flag);
int fstatat(int fd, const char *restrict path, struct stat *restrict buf, int flag);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <dirent.h>
DIR *opendir(const char *dirname);
DIR *fdopendir(int fd);
struct dirent *readdir(DIR *dirp);
int closedir(DIR *dirp);
struct dirent {
ino_t d_ino; /* Inode number */
off_t d_off; /* Not an offset; see below */
unsigned short d_reclen; /* Length of this record */
unsigned char d_type; /* Type of file; not supported
by all filesystem types */
char d_name[256]; /* Null-terminated filename */
};
DT_BLK block device
DT_CHR character device
DT_DIR directory
DT_FIFO named pipe (FIFO)
DT_LNK symbolic link
DT_REG regular file.
DT_SOCK UNIX domain socket.
DT_UNKNOWN Bilinmeyen bir tür
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <dirent.h>
int dirfd(DIR *dirp);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <sys/stat.h>
int fstatat(int fd, const char *restrict path, struct stat *restrict buf, int flag);
Fonskiyonun fd parametresinin yanı sıra aynı zamanda bir flag parametresinin olduğuna dikkat ediniz. Bu parametre stat semantiğinin mi yoksa
lstat semantiğinin mi uygulanacağını belirtmektedir. Eğer bu parametreye 0 geçilirse bu durumda stat semnatiği uygulanır Eğer bu parametreye
AT_SYMLINK_NOFOLLOW değeri geçilirse bu durumda lstat semantiği uygulanmaktadır. AT_SYMLINK_NOFOLLOW sembolik sabiti <sys/stat.h> içerisinde değil
<fcntl.h> içerisinde bildirilmiştir. İşte biz yukarıdaki örnekte önce dizin'in betimleycisini dirfd fonksiyonu ile alıp bunu fstatat
fonksiyonunda kullanırsak yol ifadesini düzenlememize gerek kalmaz. Aşağıdaki örnekte bu çözüm verilmiştir.
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <dirent.h>
long telldir(DIR *dirp);
void seekdir(DIR *dirp, long loc);
void rewinddir(DIR *dirp);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <dirent.h>
int alphasort(const struct dirent **d1, const struct dirent **d2);
int scandir(const char *dir, struct dirent ***namelist, int (*sel)(const struct dirent *),
int (*compar)(const struct dirent **, const struct dirent **));
int cmp(const struct **direnet1, const struct **dirent2); -> biz yazdık bunu
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#define _XOPEN_SOURCE 500
#include <ftw.h>
int nftw(const char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *), int fd_limit, int flags);
FTW_CHDIR: Eğer bu bayrak belirtilirse fonksiyon her dizine geçtiğinde prosesin çalışma dizinini de o dizin olarak değiştirmektedir.
FTW_DEPTH: Normalde dolaşım "pre-order" biçimde yapılmaktadır. Bu bayrak girilirse "post-order" dolaşım yapılır. Bayrağın ismi
yanlış verilmiştir. "pre-order" dolaşım demek bir dizin ile karşılaşıldığında önce dizin girişinin ele alnıması sonra özyineleme
yapılması demektir. "post-order" dolaşım ise önce özyineleme yapılıp sonra dizin girişinin ele alınması demektir.
Default durum "pre-order" dolaşım biçimindedir.
FTW_MOUNT: Bu bayrak belirtilirse özyineleme yapılırken bir "mount point" ile karşılaşılırsa o dosya sistemine girilmez. Default durumda
özyineleme sırasında bir "mount point" ile kaşılaşılırsa özyineleme o dosya sisteminin içime girilerek devam ettirilmektedir.
FTW_PHYS: Default durumda nftw fonksiyonu bir sembolik link dosyası ile karşılaştığında linki izler ve link'in hedefine
yönelik hareket eder. Daha önce bir böyle bir durumun sonsuz döngüye yol açabileceğinden bahsetmiştik. Bu nedenle biz özyinelemede
stat fonksiyonu yerine lstat fonksiyonunu kullanmıştık. İşte bu bayrak belirtilirse artık nftw fonksiyonu sembolik link dosyası
ile karşılaştığında link'i izlemez, sembolik link dosyasının kendisi hakkında bilgi verir.
int callback(const char *path, const struct stat *finfo, int flag, struct FTW *ftw); -> biz yazdık
struct FTW {
int base;
int level;
};
FTW_D: Bulunan giriş bir dizin girişidir.
FTW_DNR: Bulunan giriş bir dizin girişidir. Ancak bu dizin'in içi okunamamaktadır. Dolayısıyla bu dizin özyinelemede dolaşılamayacaktır.
FTW_DP: Post-order dolaşımda bir dizinle karşılaşıldığında bayrak FTW_D yerine FTW_DP olarak set edilmektedir.
FTW_F: Bulunan dizin girişi sıradan bir dıosyadır (regular file).
FTW_NS: Bulunan dizin girişi için stat ya da lstat fonksiyonu başarısız olmuştur. Dolayısıyla fonksiyona geçirilen stat yapısı da
anlamlı değildir.
FTW_SL: Bulunan giriş bir sembolik bağlantı dosyasına ilişkindir. Sembolik bağlantı dosyasının hedefi mevcuttur.
FTW_SLN: Bulunan giriş bir sembolik bağlantı dosyasına ilişkindir. Sembolik bağlantı dosyasının hedefi mevcut değildir ("danging klink" durumu).
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
int link(const char *oldpath, const char *newpath);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <fcntl.h>
int linkat(int fd1, const char *path1, int fd2, const char *path2, int flag);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
int symlink(const char *path1, const char *path2);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <fcntl.h>
int symlinkat(const char *path1, int fd, const char *path2);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
ssize_t readlink(const char *path, char *buf, size_t bufsize);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
int access(const char *path, int amode)
Fonksiyonun birinci parametresi erişim testinin yapılacağı dosyanın yol ifadesini belirtmektedir. İkinci parametresi test edilecek
erişimi belirtir. Bu parametre aşağıdaki sembolik sabitlerin bir düzeyinde OR'lanmasıyla oluşturulabilir:
R_OK: Okuma yapılabilir mi?
W_OK: Yazma yapılabilir mi?
X_OK: Çalıştırılabilir mi?
F_OK: Dosya var mı?
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <unistd.h>
int euidaccess(const char *pathname, int mode);
int eaccess(const char *pathname, int mode);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <fcntl.h>
int faccessat(int fd, const char *path, int amode, int flag);
Fonksiyonun birinci paraetresi ikinci parametresiyle belirtilen yol ifadesinin göreli olması durumunda aramanın yapılacağı
dizini belirtmektedir. Son parametre 0 geçilebilir ya da AT_EACCESS geçilebilir. Bu AT_EACCESS değeri test işleminin etkin kulalnı ve grup
id'lerine bakılarak yapılacağı anlamına gelmektedir. (Tabii ikinci parametre ile belirtilen yol ifadesi mutlak olduğunda birinci parametrede
belirtilen dizine ilişkin betimleyici yine dikkate alınmaz. Ancak üçüncü parametreyle belirtilen bayrak dikkate alınır)
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
int dup(int fildes);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
int dup2(int fildes, int fildes2);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
IO yönlendirmesi kabuk üzerinden de yapılabilmektedir. Kabukta ">" sembolü 1 numaralı betimleyicinin yönlendirileceği anlamına gelmektedir.
Kabuk üzerinde "<" sembolü de 0 numaralı betimleyiciyi yönlendirmektedr.
Aslında kabukta genel olarak yönlendirme için "n>" ve "n<" sembolleri de kullanılabilmektedir. Buradaki n betimleyicinin
numarasını belirtir. Bu sayede biz herhangi bir betimleyiciyi okuma ve yazma amaçlı bir dosyaya yönlendirebiliriz.
ÖR: ./sample 2> test.txt
Tabii hem stdout dosyasını hem de stdin dosyasını kabuk üzerinden birlikte de yönlendirebiliriz.
ÖR: ./sample > out.txt < in.txt
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
<unistd.h> dosyasında okunabilirliği artırmak için şu sembolik sabitler bildirilmiştir:
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
IO yönlendirmesi kabuk üzerinden de yapılabilmektedir. Kabukta ">" sembolü 1 numaralı betimleyicinin yönlendirileceği anlamına gelmektedir. Örneğin:
./sample > test.txt
Bu durumda kabuk önce ">" sembolünün sağındaki dosyayı O_WRONLY|O_TRUNC modunda açar. Sonra ./sample programını çalıştırarak bu
prosesin 1 numaralı betimleyicisini dup2 fonksiyonu ile bu dosyaya yönlendirir. Böylece ./sample sample programının ekrana yazdığını
zannettiği ieşyle bu dosyaya yazılmış olacaktır.
ls gibi, cat gibi kabuk komutlarının da aslında birer program olduğuna bunların da 1 numaralı betimleyiciyi kullanarak yazdırma
yaptığına dikkat ediniz. Örneğimn biz kabuk üzerinde şu komutu uygulayabiliriz:
ls -l > test.txt
Eğer kabulta ">" yerine ">>" sembolü kullanılırsa bu durumda ">>" sembolünün sağındaki dosya O_CREAT|O_WRONLY|O_APPEND modunda
açılmaktadır. Yani dosya varsa bu durumda olan dosyanın sonuna ekleme yapılacaktır. Örneğin:
ls -l >> test.txt
Kabuk üzerinde "<" sembolü de 0 numaralı betimleyiciyi yönlendirmektedr. Örneğin:
./sample < test.txt
Burada kabuk "test.txt" dosyasını O_RDONLY modda açar. Sonra ./sample programını çalıştırır. Prosesin 0 numaralı betimleyicisini
"test.txt" dosyasına dup2 fonksiyonuyla yönlendirir. Böylece rpogram sanki klavyeden okuduğunu sanırken aslında dosyadan okuma
yapacaktır.
Aslında kabukta genel olarak yönlendirme için "n>" ve "n<" sembolleri de kullanılabilmektedir. Buradaki n betimleyicinin
numarasını belirtir. Bu sayede biz herhangi bir betimleyiciyi okuma ve yazma amaçlı bir dosyaya yönlendirebiliriz. Örneğin:
./sample 2> test.txt
Burada "test.txt" dosyası açılıp ./sample programının "stderr" olarak isimlendirilen 2 numaralı betimleyicisi bu dosyaya
yönlendirilecektir.
Kabuk programları ">", "<", "n>" "n<" gibi yönlendirmeleri nasıl yapmaktadır? Bu konu ileride ele alınacaktır. Kabuk önce bir kez
fork işlemi yapar. Sonra yönlendirme işlemini gerçekleştirir. Sonra da exec işlemi yapmaktadır.
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
Komut satırındaki diğer önemli bir işlem de "boru (pipe)" işlemidir. Boru işlemi "|" ile temsil edilmektedir. Kabul üzerinden
aşağıdaki gibi bir komut uygulamış olalım:
a | b
Burada kabuk bu yazıyı "|" karakterindne parse eder. "|" karakterinin solundaki ve sağındakileri birer program olarak ele alır.
Her iki programı da çalışırır. Yani burada "a" programı da "b" programı da çalıştırılacaktır. "a" programının "stdout" dosyasına
yazdıklarını "b" programı "stdin" dosyasından okuyacaktır. Başka bir deyişle "a" programının 1 numaralı betimeyiciyle yaptuığı write
işlemlerini "b" programı 0 numaralı betimleyici ile read fonksiyonunu kullanarak okuyabilecektir. Kabuk boru işlemlerini
"prosesler arası haberleşme yöntemlerindne biri olan boru haberleşmesi ile" gerçekleştirmektedir. Zaten ilerleyen bölümlerde
bu konu ele alınacaktır.
Tabii boru işlemi yapılırken programların komut satırı arümanları da verilebilir. Örneğin:
a b c | d e f
Burada aslında çalıştırılacak programlar "a" ve "d" programlarıdır. Diğerleri bunların komut satırı argümanlarıdır.
Aşağıdaki örnekte "a" programı ekrana (stdout dosyasına) 0'dan 10'a kadar sayıları yazdırmaktadır. "b" programı ise
döngü içerisinde klavyeden (stdin dosyasından) değer okuyup ekrana yazdırmaktadır. Bu iki programı aşağıdkai gibi çalıştıralım:
./a | ./b
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <stdio.h>
int fileno(FILE *stream);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <stdio.h>
FILE *fdopen(int fd, const char *mode);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <stdio.h>
void setbuf(FILE *stream, char *buf);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <stdio.h>
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
void clear_stdin(void)
{
int ch;
while ((ch = getchar()) != '\n' && ch != EOF)
;
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <stdio.h>
int getchar(void);
char *gets(char *s);
char *gets_s(char *s, rsize_t n);
char *fgets(char *s, size_t n, FILE *f);
int scanf(const char *format, ...);
int getc(FILE *stream);
int ungetc(int c, FILE *stream);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
pid_t getpid(void);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
pid_t getppid(void);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
pid_t fork(void);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
void _exit(int status);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <stdlib.h>
void exit(int status);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <sys/wait.h>
pid_t wait(int *wstatus);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *stat_loc, int options);
Fonksiyonun birinci parametresi beklenecek alt prosesin proses id değerini belirtir. Bu sayede programcı belli bir alt prosesi bekleyebilmektedir.
Bu birinci parametre aslına birkaç biçimde geçilebilmektedir. Eğer bu parametre negatif bir proses id değeri olarak geçilirse
bu durumda fonksiyon proses grup id'si bu değerin pozitifi olan herhangi bir alt prosesi beklemektedir. Eğer bu parametre -1
olarak geçilirse bu durumda fonksiyon tamamen wait fonksiyonundaki gibi davranmaktadır. Yani herhangi bir alt prosesi beklemektedir.
Eğer bu parametre 0 olarak geçilirse fonksiyon proses grup id'si waitpid fonksiyonunu çağıran prosesin id'si ile yanı olan
herhangi bir alt prosesi beklemektedir. Tabii normal olarak bu parametreye programcı pozitif olan bir proses id geçer. Bu durumda
fonksiyon o alt prosesi bekleyecektir. (Tabii bu parametreye geçilen proses id o prosesin bir alt prosesi değilse fonksiyon yine
başarısız olmaktadır.) Fonksiyonun ikinci parametresi exit bilgisinin yerleştirileceği int türden nesnesnin adresini alır. Üçüncü
parametre bazı özel değerlerin bit düzeyinde OR'lanmasıyla oluşturulabilmektedir:
WNOHANG: Bu durumda waitpid eğer alt proses henüz sonlanmamışsa bekleme yapmaz, başarısızlıkla sonuçlanır.
WCONTINUED, WUNTRACED: Bu bayrakların açıklaması burada yapılmayacaktır.
Tabii bu üçüncü parametre genellikle 0 geçilmektedir. 0 geçilmesi bu bayraklardan hiçbirinin kullanılmayacağı anlamına gelmektedir.
O halde aslında wait(&status) çağrısı ile waitpid(-1, &status, 0) eşdeğerdir.
waitpid fonksiyonunda da ikinci parametre NULL adres geçilebilir. Bu durumda proses beklenir ama exit bilgileri elde edilmez.
waitpid fonksiyonu da başarı durumunda beklenen proses id değeri ile başarısızlık durumunda -1 değeriyle geri dönmektedir.
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <stdlib.h>
extern char **environ;
char *getenv(const char *name);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <stdlib.h>
int setenv(const char *name, const char *value, int overwrite);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <stdlib.h>
int putenv(char *str);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <stdlib.h>
int unsetenv(const char *name);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
execl
execle
execlp
execv
execve (Linux'ta sistem fonksiyonu olarak yazılmıştır)
execvp
fexecve (Linux'ta execveat sistem fonksiyonu)
#include <unistd.h>
int execl(const char *path, const char *arg0, ... /*, (char *)0 */);
int execv(const char *path, char * const *argv);
int execlp(const char *file, const char *arg0, ... /*, (char *)0 */);
int execvp(const char *file, char *const argv[]);
int execle(const char *path, const char *arg0, ... /*, (char *)0, char *const envp[]*/);
int execve(const char *path, char *const argv[], char *const envp[]);
pid_t vfork(void);
int fexecve(int fd, char *const argv[], char *const envp[]);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
fd = open("test.txt", O_RDONLY|O_CLOEXEC); // flag farkına dikkat
if (fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC)) == -1) // flag farkına dikkat
exit_sys("fcntl");
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <stdlib.h>
int system(const char *command);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
uid_t getuid(void)
uid_t geteuid(void)
gid_t getgid(void);
gid_t getegid(void);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
int setuid(uid_t uid);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
int seteuid(uid_t uid);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
int setgid(gid_t gid);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
int setegid(gid_t gid);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
int setreuid(uid_t ruid, uid_t euid);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
int setregid(gid_t rgid, gid_t egid);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <unistd.h>
int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <unistd.h>
int setresuid(uid_t ruid, uid_t euid, uid_t suid);
int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
int getgroups(int gidsetsize, gid_t grouplist[]);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <grp.h>
int setgroups(size_t size, const gid_t *list);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <grp.h>
int initgroups(const char *user, gid_t group);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <unistd.h>
int pipe(int pipefd[2]);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <stdio.h>
FILE *popen(const char *command, const char *mode);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <stdio.h>
int pclose(FILE *stream);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <sys/stat.h>
int mkfifo(const char *path, mode_t mode);
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#include <fcntl.h>
int fcntl(int fd, int cmd, ...);
File status flag:
O_APPEND
O_DSYNC
O_NONBLOCK
O_RSYNC
O_SYNC
File access mode:
O_EXEC
O_RDONLY
O_RDWR
O_SEARCH
O_WRONLY
F_SETFL
F_GETFL
F_SETFD
F_GETFD
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
System 5 IPC Fonksiyonların POSIX IPC Fonksiyonları
msgget (mesaj kuyruğu) mq_open (mesaj kuyruğu)