file.c: In function 'get_times':
file.c:668:17: error: incompatible types when assigning to type 'struct timespec' from type 'st_timespec_t' {aka 'const struct st_timespec'}
(*times)[0] = sb->st_atim;
^
file.c:669:17: error: incompatible types when assigning to type 'struct timespec' from type 'st_timespec_t' {aka 'const struct st_timespec'}
(*times)[1] = sb->st_mtim;
- NevemTeve blogja
- A hozzászóláshoz be kell jelentkezni
- 451 megtekintés
Hozzászólások
Esetleg jelezni a fejlesztők felé a dolgot/problémát részletes hibaüzenettel?
https://midnight-commander.org/wiki/McDevelopers
"Share what you know. Learn what you don't."
- A hozzászóláshoz be kell jelentkezni
A két érintett struct
identikus? Ha igen, typecast vagy memcpy()
nem játszik, mint hotfix?
- A hozzászóláshoz be kell jelentkezni
wtf did I just read???
code reviewn ordas nagy reject lenne
- A hozzászóláshoz be kell jelentkezni
Benéztem volna valamit? Nekem ez sima struct
-copynak tűnik, ha pedig a két struct
-ban ugyanaz van, akkor copy-hoz a typecast, vagy a memcpy()
is jó. Ha nem ugyanaz van a két struct
-ban, akkor nyilván nem jó, de épp ezért kérdeztem rá, hogy ugyanaz van-e bennük. Ha meg az a baj, hogy gány...hát ezért mondtam, hogy hotfixnek, hogy leforduljon, nem azt, hogy ezt merge-eljék.
- A hozzászóláshoz be kell jelentkezni
Ha ugyanolyan lenne a két struct, szerinted szólna a fordító?
- A hozzászóláshoz be kell jelentkezni
Szól érte:
typedef struct struct1
{
int sub1, sub2;
} struct1_t;
typedef struct struct2
{
int sub1, sub2;
} struct2_t;
int main(int argc, char *argv[])
{
struct1_t s1;
struct2_t s2;
s1 = s2;
}
# gcc x.c
x.c: In function ‘main’:
x.c:16:7: error: incompatible types when assigning to type ‘struct1_t’ {aka ‘struct struct1’} from type ‘struct2_t’ {aka ‘struct struct2’}
16 | s1 = s2;
| ^~
- A hozzászóláshoz be kell jelentkezni
Ottan a time_t/long/int stb videken lehet a kutya elasva. Az egyiknel int, a maskinal long a nanosec, cserebe az int meg a long mar nem ugyanaz. Peldaul.
- A hozzászóláshoz be kell jelentkezni
664 static void
665 get_times (const struct stat *sb, mc_timesbuf_t * times)
666 {
667 #ifdef HAVE_UTIMENSAT
668 (*times)[0] = sb->st_atim;
669 (*times)[1] = sb->st_mtim;
670 #else
671 times->actime = sb->st_atime;
672 times->modtime = sb->st_mtime;
673 #endif
674 }
Ez lenne az:
int utimensat (DirFileDescriptor, Path, Times, Flag)
int DirFileDescriptor;
char *Path;
struct timespec Times[2];
int Flag;
struct timespec {
time_t tv_sec;
long tv_nsec;
};
Valamint ez:
typedef struct st_timespec {
time_t tv_sec;
int tv_nsec;
} st_timespec_t;
- A hozzászóláshoz be kell jelentkezni
Valamint ez:
struct stat
{
dev_t st_dev;
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
ushort_t st_flag;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
soff_t st_ssize;
st_timespec_t st_atim;
st_timespec_t st_mtim;
st_timespec_t st_ctim;
blksize_t st_blksize;
blkcnt_t st_blocks;
int st_vfstype;
uint_t st_vfs;
uint_t st_type;
uint_t st_gen;
uint_t st_reserved[10];
off64_t st_size;
};
Szinte biztos, hogy ez a kavarás a 'timespec'-cel és 'st_timespec_t'-vel valamilyen kompatibilitási probléma megoldására van.
- A hozzászóláshoz be kell jelentkezni
Property-k másolása kézzel?
(*times)[0].tv_sec = sb->st_atim.tv_sec;
(*times)[0].tv_nsec = sb->st_atim.tv_nsec;
(*times)[1].tv_sec = sb->st_mtim.tv_sec;
(*times)[1].tv_nsec = sb->st_mtim.tv_nsec;
- A hozzászóláshoz be kell jelentkezni
Köszönöm, végül ez lett a megoldás, ilyesmi:
sed 's/(\*times)\[0\] = sb->st_atim;/(*times)[0].tv_sec = sb->st_atim.tv_sec;(*times)[0].tv_nsec = sb->st_atim.tv_nsec;/
s/(\*times)\[1\] = sb->st_mtim;/(*times)[1].tv_sec = sb->st_mtim.tv_sec;(*times)[1].tv_nsec = sb->st_mtim.tv_nsec;/
' src/filemanager/file.c.orig >src/filemanager/file.c
- A hozzászóláshoz be kell jelentkezni
Van is egy ilyen okosság a sys/stat.h-ban:
#if _XOPEN_SOURCE>=700
#ifdef _ALL_SOURCE
st_timespec_t st_atim; /* Time of last access */
st_timespec_t st_mtim; /* Time of last data modification */
st_timespec_t st_ctim; /* Time of last file status change */
#else
struct timespec st_atim;/* Time of last access */
struct timespec st_mtim;/* Time of last data modification */
struct timespec st_ctim;/* Time of last file status change */
#endif
#else
time_t st_atime; /* Time of last access */
int st_atime_n;
time_t st_mtime; /* Time of last data modification */
int st_mtime_n;
time_t st_ctime; /* Time of last file status change */
int st_ctime_n;
#endif
- A hozzászóláshoz be kell jelentkezni
Hogy milyen jól sikerült a kompatibilitási probléma megoldása, azt tesztprogrammal is bebizonyíthatjuk:
/* default: mtime=1681573187.209315433
_ALL_SOURCE=1: mtime=1681573187.209315433
_XOPEN_SOURCE=700: mtime=1681573187.899002939283079168
_XOPEN_SOURCE=700 _ALL_SOURCE=1: mtime=1681573187.209315433
*/
#include
#include
int main(void) {
struct stat stbuff;
stat("Makefile", &stbuff);
printf("%s: mtime=%lld.%lld\n"
, "Makefile"
, (long long)stbuff.st_mtim.tv_sec
, (long long)stbuff.st_mtim.tv_nsec);
return 0;
}
- A hozzászóláshoz be kell jelentkezni
Valamint van egy ilyen is, ezt a struct statx
használja:
#if _XOPEN_SOURCE>=700
struct timespec64 {
time64_t tv_sec; /* 8: Time of last access */
int32_t tv_nsec; /* 4: nanoseconds */
int32_t tv_pad; /* 4: padding */
};
#endif
- A hozzászóláshoz be kell jelentkezni
Biztos ami biztos, elhelyeztem egy ilyet is a /usr/local/include/sys/stat.h -ba:
#if defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 >= 700 && !defined(_ALL_SOURCE)
#define _ALL_SOURCE 1
#endif
#pragma GCC system_header
#include_next
- A hozzászóláshoz be kell jelentkezni
Az újabb mc verziókban van egy ilyen rész a configure.ac-ben:
dnl utimensat is supported since glibc 2.6 and specified in POSIX.1-2008
dnl utimensat() causes different timespec structures to cause failures on IBM i and AIX
case $host_os in
*os400 | aix*)
;;
- A hozzászóláshoz be kell jelentkezni
mc_timesbuf_t mit takar?
- A hozzászóláshoz be kell jelentkezni
#ifdef HAVE_UTIMENSAT
typedef struct timespec mc_timesbuf_t[2];
#else
typedef struct utimbuf mc_timesbuf_t;
#endif
- A hozzászóláshoz be kell jelentkezni
Azt nem értem teljesen, hogy ha az mc_timesbuf_t az függ a HAVE_UTIMENSAT értékétől, akkor a stat struct miért nem. Honnan jön az a típus?
- A hozzászóláshoz be kell jelentkezni
A 'struct stat' a sys/stat.h-ból jön, sajnos különféle define-októl függ a tartalma, van fentebb egy példa arra, hogy bizonyos opciók esetén `long` (int64_t) a nanosec, ami jószándékra vall ugyan, de nem kompatibilis a stat-rendszerhívás által visszaadott `int`-tel (int32_t). (Az illesztési követelmény miatt (time_t=int64_t) az egyes nanosec mezők ugyanott vannak, tehát little endian platformon még menne is a dolog, de ez big endian, itt nem jó.)
A 'mc_timesbuf_t' a Mindnight Commander tipusa (egyébként kétségtelenül igyekeznek ők mindenféle platformot szupportálni, de azért azt látni kell, hogy nem az Aix a figyelem fókusza).
- A hozzászóláshoz be kell jelentkezni
A stat.h tartamát a POSIX írja elő?
Arra gondolok, hogy ha már arra hivatkoznak, hogy POSIX.1-2008-tól van utimensat, akkor nézzük már meg, hogy a POSIX.1-2008 mit tartalmaz stat.h téren.
https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/
Itt bizony az van, hogy az st_atim és st_mtim-nek struct timespec a típusa.
Azaz ha nálad st_timespec_t van, és az nem ugyanaz, mint a struct timespec, akkor bizony az AIX a ludas.
Ugyebár az AIX 7 az UNIX V7 certified: https://www.opengroup.org/openbrand/register/ibm.htm
Ami pedig ugye POSIX.1-2017-et jelent.
Ez az st_timespec_t nem is értem, hogy honnan jön, ilyet a POSIX nem ismer. Minek ez, ha ott a timespec, ami a szabványos struktúra.
Én itt most az AIX-ra haragudnék, nem az mc-re.
A fent idézett #ifdef __ALL_SOURCE totál értelmetlennek tűnik nekem.
- A hozzászóláshoz be kell jelentkezni
- A hozzászóláshoz be kell jelentkezni
Nem ez a kérdés. Miért engedi meg az AIX, hogy a stat.h a szabványtól eltérő jelentésű legyen? Miért jó az?
- A hozzászóláshoz be kell jelentkezni
Az AIX még a POSIX előtti időkben született: lehet, hogy ez valami backward-compatibility mizéria miatt van így.
- A hozzászóláshoz be kell jelentkezni
Nem csak backward, hanem egyszerre többféle rendszerrel is kompatibilis binárisokat is összehordták. Ehhez nem árt a többfél rendszerrel kompatibilis header sem.
Pl. (ha jól emléxem a pah-okra) /usr/bin/tr és /usr/ucb/tr.
- A hozzászóláshoz be kell jelentkezni
Akkor jól gondoltam, hogy compatibility stuff. Vagyis az MC fejlesztőinek nincs más dolga, mint makróból a megfelelő headert behúzni AIX alatt.
- A hozzászóláshoz be kell jelentkezni
Pontosabban mondva, a tényleges rendszerhívás ilyen szerkezetben adja vissza az információt:
sec 64-bit
nsec 32-bit
unused 32-bit (gondolom, kinullázza)
Posix barátunk a következőt írja elő (timespec):
sec 64-bit
nsec 64-bit (ebből a felső 33 bit mindig nulla)
Ez a kettő big endian platformon sosem lesz kompatibilis, pl. az 1025ns így jön ki a rendszerhívásból: 00 00 04 01 00 00 00 00, ami 64 bitesen értelmezve 1025*2^32
- A hozzászóláshoz be kell jelentkezni
Igen! Sőt! Pontosan!
- A hozzászóláshoz be kell jelentkezni
Ez miért nem felelt meg?
"
:/home/root] # dnf search mc
=========================================================== Name Exactly Matched: mc ===========================================================
mc.ppc : User-friendly text console file manager and visual shell.
"
/home/root] # oslevel -s
7200-05-03-2147
- A hozzászóláshoz be kell jelentkezni