- Код: Выделить всё
var
SHMI: TShmid_ds;
begin
Data:= shmat(Handle, nil, 0);
if PtrUInt(Data) <> PtrUInt(-1) then
if shmctl(Handle, IPC_STAT, @SHMI) = 0 then
begin
Size:= SHMI.shm_segsz;
Работал нормально под Ubuntu/32, но после значительной модификации использующего этот код проекта вдруг в Size стала заноситься какая-то фигня. Первая же проверка показала неправильное заполнение полей структуры TShmid_ds.shm_perm, а значит и всего, что находится ниже нее. После нескольких попыток было выяснено, что для правильной работы, тип TIPC_Perm должен иметь такой вид:
- Код: Выделить всё
type TIPC_Perm = record
key: TKey;
uid: cushort; // а не uid_t
gid: cushort; // а не gid_t
cuid: cushort; // а не uid_t
cgid: cushort; // а не gid_t
mode: cushort; // а не mode_t
seq: cushort;
end;
Т.е. поля идентификаторов и режима должны быть 16-битными! В этом случае значения полей данной структуры оказываются правильными, и, соответственно, TShmid_ds.shm_segsz тоже заполняется корректной информацией.
Я просто не могу догнать, как же так могло получиться? Система одна и та же (только обновления периодически сама для себя качает), функцию вызываю ту же самую, почему же она теперь ожидает иную структуру? Как вообще в линуксе функция определяет, в каком формате и сколько байт заливать в out-параметр? Вот, например, как shm_perm описана с манах:
- Код: Выделить всё
struct shmid_ds {
struct ipc_perm shm_perm; /* Ownership and permissions */
size_t shm_segsz; /* Size of segment (bytes) */
time_t shm_atime; /* Last attach time */
time_t shm_dtime; /* Last detach time */
time_t shm_ctime; /* Last change time */
pid_t shm_cpid; /* PID of creator */
pid_t shm_lpid; /* PID of last shmat()/shmdt() */
shmatt_t shm_nattch; /* No. of current attaches */
...
};
Как вообще можно трактовать многоточие в конце структуры? Что это за деструктивные вольности?