How do I manipulate the contents of a stat() struct?
I have a stat struct, and I'm looking for a way to get data out of it to be manipulated. The program will successfully run and print the desired st_mtime value, but including either of the "seg-fault" lines below causes a segmentation fault in runtime.
struct stat buf;
time_t time_m;
time_t sys_time = time(0);
if(stat(sub_dirp->d_name,&buf)==0)
{
//time_m = buf.st_mtime; //seg-fault
//double since_last = (difftime(sys_time, buf.st_mtime)/60); //seg-fault
printf("%d ", (int)buf.st_mtime); //This works.
}
Both lines are attempting to manipulate the buf.st_mtime
value in some way.
I've had a hard time finding any examples of the usage of stat() that do anything other than print its contents, which makes me wonder if it's even possible.
So my question is, if it is possible, what am I missing?
P.S. I do wish to keep st_mtime
in the Unix timestamp format to make it easier to manipulate.
Edit: After realizing that st_mtime
is itself its own struct (timespec), how can I access the st_mtime.tv_sec
member?
The compiler doesn't like buf.st_mtime.tv_sec
one bit.
1 answer
-
answered 2022-05-07 19:10
jettg
For anyone who was stumped by this, I ended up achieving my desired result by creating a timespec struct:
struct timespec tspec;
This subsequently allowed me to make these two assignments:
tspec.tv_sec = buf.st_mtime; time_t time_m = tspec.tv_sec; //tv_sec is of type time_t
Then I can manipulate time_m however I please. Although I must admit I'm still not sure why you can't assign
time_m
directly tobuf.st_mtime
if doing it with a "middleman" works just fine.
do you know?
how many words do you know
See also questions close to this topic
-
What's purpose of __linecapp in getline, when it'll auto resize?
It's all about second parameter of getline in stdio.h,
I'll name it 'n' or '__linecapp' below.
According to the document:
If the buffer is not large enough to hold the line, getline() resizes it with realloc(3), updating *lineptr and *n as necessary.
It'll automatically update line capacity, then why should we input __linecapp?
P.S Someone ask before, but discussion didn't explain when we need it, or how to make it useful.
-
Linked List Deletion function causing program to crash *wrong pointers?*
In my program when a username is following another one and also has posted a "tweet" which is a string in an attempt to delete the followed username it breaks the program. I believe this is the code snippet in question. If anyone could help me identify the issue I would be thankful as I am learning the usage of linked lists for scale able projects. Thanks
void deleteAccount(accountNodePtr *startPtr, accountNodePtr *curAcPtr, tweetsNodePtr *startTwtPtr){ accountNodePtr acLoopPtr; accountNodePtr tempCur = *curAcPtr; followNodePtr followingPtr = tempCur->followingPtr; followNodePtr tempPtr; followNodePtr tempPtr2; tweetsNodePtr iterTwtPtr; iterTwtPtr = *startTwtPtr; *below here in question* tempCur = *curAcPtr; while (tempCur->followersPtr!=NULL){ acLoopPtr = *startPtr; while (strcmp(acLoopPtr->username, tempCur->followersPtr->username)!=0){ acLoopPtr=acLoopPtr->nextPtr; } if (strcmp(acLoopPtr->followingPtr->username, tempCur->username)==0){ tempPtr=acLoopPtr->followingPtr->nextPtr; free(acLoopPtr->followingPtr); acLoopPtr->followingPtr=tempPtr; }else{ tempPtr=acLoopPtr->followingPtr; while(strcmp(tempPtr->nextPtr->username, tempCur->username)!=0){ tempPtr=tempPtr->nextPtr; } tempPtr2=tempPtr->nextPtr->nextPtr; free(tempPtr->nextPtr); tempPtr->nextPtr=tempPtr2; } tempPtr = tempCur->followersPtr->nextPtr; free(tempCur->followersPtr); tempCur->followersPtr=tempPtr; }
This is the structure
typedef struct followsNode { char username[MAX_USERNAME]; struct followsNode *nextPtr; } followNode; typedef struct accountsNode { char username[MAX_USERNAME]; struct followsNode *followersPtr; struct followsNode *followingPtr; struct accountsNode *nextPtr; } accountNode; typedef followNode *followNodePtr; typedef accountNode *accountNodePtr;
-
Double stack linked list segmentation fault
So I've been asked to make a C++ program Double stack with linked list. I can't find any tutorial or example on Google, most of them use Array to do it. so I have to figure it out how to do this, and end up with Segmentation Fault output in the end, which I still have no idea which part of my code is wrong here
#include <iostream> using namespace std; struct Node{ public: int data; Node *next; Node *prev; }; Node *head = NULL; Node *tail = NULL; Node *del = NULL; void push(Node **head_ref, int data){ Node *temp = new Node; temp->data = data; temp->next = head; head->prev = temp; head = temp; } void push2(Node **head_ref, int data){ Node *temp = new Node; temp->data = data; tail->next = temp; temp->prev = tail; tail = temp; } void pop(Node **head_ref, int data){ del = head; head->next->prev = NULL; head = del->next; del = NULL; } void pop2(Node **head_ref, int data){ del = tail; tail->prev->next = NULL; tail = del->prev; del = NULL; } int peek(Node **head_ref){ return head->data; } int main(){ system("clear"); push2(&head, 10); }
any help is appreciated
-
Segmentation Fault - unordered_map(tarjan's algorithm)
I have implemented Tarjan's algorithm to find strongly connected component in a graph and getting Segmentation fault for some large input.
#include <iostream> #include <sstream> #include <vector> #include <stack> #include <unordered_set> #include <unordered_map> using namespace std; class Graph { public: int n, m; unordered_map<int, unordered_set<int>> graph; Graph(int n, int m): n(n), m(m) {} void add_edge(int u, int v) { graph[u].insert(v); if(graph.find(v) == graph.end()) graph[v] = unordered_set<int>(); } void scc_helper(int u, unordered_map<int, int>& disc, unordered_map<int, int>& low, stack<int>& st, unordered_map<int, bool>& inStack, vector<unordered_set<int>>& scc, int& time) { disc[u] = low[u] = time++; st.push(u); inStack[u] = true; for(const int& ch: graph[u]) { if(disc[ch] == 0) { scc_helper(ch, disc, low, st, inStack, scc, time); low[u] = min(low[u], low[ch]); } else if(inStack[ch]) { low[u] = min(low[u], disc[ch]); } } if(disc[u] == low[u]) { scc.push_back(unordered_set<int>()); while(st.top() != u) { scc.back().insert(st.top()); inStack[st.top()] = false; st.pop(); } scc.back().insert(st.top()); inStack[st.top()] = false; st.pop(); } }; vector<unordered_set<int>> get_scc() { unordered_map<int, int> disc, low; stack<int> st; unordered_map<int, bool> inStack; vector<unordered_set<int>> scc; int time = 1; for(const auto& p: graph) { if(disc[p.first] == 0) scc_helper(p.first, disc, low, st, inStack, scc, time); } cerr << "completed" << endl; return scc; } }; void read(string& input) { do { getline(cin, input); } while(input.length() > 0 && input[0] == '%'); } Graph read_graph() { string input; istringstream ss; int n, m, v; read(input); ss.str(input); ss >> n >> m; ss.clear(); Graph G(n, m); for(int u=1; u<=n; u++) { read(input); ss.str(input); while(ss >> v) { G.add_edge(u, v); } ss.clear(); if(G.graph.find(u) == G.graph.end()) G.graph[u] = unordered_set<int>(); } return G; } int main() { Graph G = read_graph(); cerr << "read input\n"; vector<unordered_set<int>> scc = G.get_scc(); cout << scc.size() << "\n"; }
After debugging, I have found that the condition
if(disc[u] == low[u])
is not getting evaluated to true when program throws segmentation fault. Another thing is that, Segmentation fault was received on linesdisc[u] = low[u] = time++;
,st.push(u);
andinStack[u] = true;
and at that time there were approx. 20,000 entries in each of the unordered_map and in stack.Some details about input: for, n=16384 m=283794, the program is working correctly but for, n=58960 m=269439, it is throwing segmentation fault.
-
If the offset of `pread` represents the real offset in disk
Random read is usually slower than sequential read. I want to make my program faster, so my question is: do the following two reads mean sequential reads on the disk.
pread(fd, size, offset); pread(fd, size, offset+size);
Or under which condition, these two reads can be sequential?
Thanks!
-
Read system call for C unix socket only returns and gets triggered when new line is detected. Is this the default behaviour?
The sources on the Internet and books I've been reading seem to not specify exactly how the unix read system call behaves and when exactly it is triggered. They simply say that as soon as data are sent from the other end this data are available for consuming with the read and as soon as the EOF signal is received ( for example because of FIN ) the returns -1.
1) How come that the read in this server is ONLY triggered when data are sent that include an \n new line character ?
2) Why does the read get stuck if \n is not detected ?
3) How come that if I try to reverse the situation ( the server sends data and the client reads it this situation doesn't occur ?
4) Has this behaviour something to do with some TCP/IP protocol stack settings on my OS that set different behaviours when read is applied to client or server respectively?
This is the server :
#define PORT 1026 int main(){ int sockfd, connfd; unsigned int len; struct sockaddr_in servaddr, cli; //SOCKET CREATION sockfd = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP); if (sockfd == -1) { printf("socket creation failed...\n"); exit(0); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr =htonl(INADDR_ANY); servaddr.sin_port = htons(PORT); //BIND if ((bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) != 0) { printf("socket bind failed...\n"); exit(0); } //LISTEN if ((listen(sockfd, 5)) != 0) { printf("Listen failed...\n"); exit(0); } for(;;){ len = sizeof(cli); connfd = accept(sockfd, (struct sockaddr*)&cli, &len); if (connfd < 0) { printf("server accept failed...\n"); exit(0); }else{ printf("New connection accepted !\n"); } char buffr; int r; while( (r=read(connfd,&buffr,sizeof(buffr))) > 0 ){ if(buffr=='#') break; printf("%c",buffr); }; close(connfd); }; return 0; }
And this is the client sending data :
#define PORT 1026 int main(){ int sockfd; struct sockaddr_in servaddr, cli; //CREATE SOCKET sockfd = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP); if (sockfd == -1) { printf("socket creation failed...\n"); exit(0); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); servaddr.sin_port = htons(PORT); if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) != 0) { printf("connection with the server failed...\n"); //exit(0); } char s[]="Hello World !#"; // DOESN'T WORK ! /*char s[]="Hello World !#\n"; DOES WORK*/ write(sockfd,s,sizeof(s)); close(sockfd); return 0; }
I'm using Mac OS and I've also checked on the wireshark traffic and it seems there are no problems with the packets. So, what's going on here ?
-
How to stop pathlib.Path().stat() from resolving a symlink?
I want to test modification time of a file I have:
$ /tmp/bla -> bla.1 # was linked once $ /tmp/bla.1 # was modified after the link
Now, if I run the shell command
stat bla
, I get one time, andstat bla.1
will give me a later time (because the link indeed was created once, but the destination was modified after that)When doing it from python, it returns the same values for both the link and the destination because for some reason, it resolves the link:
In [1]: from pathlib import Path In [2]: Path("bla").stat().st_mtime == Path("bla.1").stat().st_mtime Out[2]: True
This is clearly wrong:
$ stat bla | grep "^Mod" Modify: 2022-04-25 19:37:23.697182669 +0300 $ stat bla.1 | grep "^Mod" Modify: 2022-04-25 19:37:59.437309050 +0300
pathlib.Path.stat
says that:Return the result of the stat() system call on this path, like os.stat() does.
but it doesn't help me because it also resolves the link. How can this be fixed? (Same issue with
os.stat
)Python3.6.9
-
R; package {stats}; function {ts.plot}; change x-axis labeles
I need to change the x-axis labels so they are words instead of numerals. Currently, the x-axis goes 1, 2, 3, etc. I would like it to go "Placement", "Fresh", etc.
trendplot <- function(timeseries, color, index, first = FALSE, w = 4, add_main = ""){ if (first) { plot.ts(timeseries[, index], col = color, lwd = w, ylim = c(-2, 2), ylab = "Scaled Relative Abundance", xlab = "Stage", main = paste0("Trend Plots", add_main)) # gsub(".", " ", colnames(timeseries)[index], fixed = TRUE) } else { lines(timeseries[, index], col = color, lwd = w) } }
Update: This code works for what I wanted it be.
stages<-c('Placement','Fresh','Bloat One','Bloat Two','Post-Bloat One','Post-Bloat Two') trendplot <- function(timeseries, color, index, first = FALSE, w = 4, add_main = ""){ if (first) { plot.ts(timeseries[, index], col = color, lwd = w, axes = FALSE, ylim = c(-2, 2), ylab = "Scaled Measurement", xlab = "Time Point", main = paste0("Trend Plots", add_main)) # gsub(".", " ", colnames(timeseries)[index], fixed = TRUE)+ } else { lines(timeseries[, index], col = color, lwd = w) } {axis(1, at=1:6, labels=stages, cex.axis=0.5)} }
-
Invalid Modification Date for Linux Directories in stat C
I was working on a shell project, where I encountered a problem to which I can't find a solution to. When using stat() to get modification time, I was getting weird times with Linux directories like
/home
,/mnt
, etc.Code:
DIR *d; struct dirent *dir; struct stat s; struct tm date; char second[4]; char minute[4]; char hour[4]; char day[4]; char month[4]; char* dateStr; d = opendir("/home"); if (d) { printf("Directory Contents of \"%s\":\n\n", directory); // Printing Directory Contents message printf("%7s %16s Name\n", "Size", "Last Modified"); printf("==================================================\n"); while ((dir = readdir(d)) != NULL) { stat(dir->d_name, &s); date = *(localtime(&s.st_mtime)); if (date.tm_sec < 10) { sprintf(second, "0%d", date.tm_sec); } else { sprintf(second, "%d", date.tm_sec); } if (date.tm_min < 10) { sprintf(minute, "0%d", date.tm_min); } else { sprintf(minute, "%d", date.tm_min); } if (date.tm_hour < 10) { sprintf(hour, "0%d", date.tm_hour); } else { sprintf(hour, "%d", date.tm_hour); } if (date.tm_mday < 10) { sprintf(day, "0%d", date.tm_mday); } else { sprintf(day, "%d", date.tm_mday); } if (date.tm_mon < 10) { sprintf(month, "0%d", date.tm_mon + 1); } else { sprintf(month, "%d", date.tm_mon + 1); } if (dir->d_type == 4 || dir->d_type == 8 || dir->d_type == 10) { if (s.st_size < 1000) { printf(" <DIR> %2s/%2s/%d %2s:%2s:%2s %s\n", day, month, (date.tm_year + 1900), hour, minute, second, dir->d_name); } else if (s.st_size > 1024 && s.st_size < 1048576) { printf(" <DIR> %2s/%2s/%d %2s:%2s:%2s %s\n", day, month, (date.tm_year + 1900), hour, minute, second, dir->d_name); } else if (s.st_size > 1048576 && s.st_size < 1073741824) { printf(" <DIR> %2s/%2s/%d %2s:%2s:%2s %s\n", day, month, (date.tm_year + 1900), hour, minute, second, dir->d_name); } else if (s.st_size > 1073741824 && s.st_size < 1099511627776) { printf(" <DIR> %2s/%2s/%d %2s:%2s:%2s %s\n", day, month, (date.tm_year + 1900), hour, minute, second, dir->d_name); } else { printf(" <DIR> %2s/%2s/%d %2s:%2s:%2s %s\n", day, month, (date.tm_year + 1900), hour, minute, second, dir->d_name); } } } }
Output:
Directory Contents of "/": Size Last Modified Name ================================================== <DIR> 24/08/2975165 08:56:24 home <DIR> 24/08/2975165 08:56:24 srv <DIR> 24/08/2975165 08:56:24 etc <DIR> 24/08/2975165 08:56:24 opt <DIR> 24/08/2975165 08:56:24 root <DIR> 24/08/2975165 08:56:24 lib <DIR> 24/08/2975165 08:56:24 mnt <DIR> 24/08/2975165 08:56:24 usr <DIR> 24/08/2975165 08:56:24 media <DIR> 24/08/2975165 08:56:24 lib64 <DIR> 24/08/2975165 08:56:24 sys <DIR> 24/08/2975165 08:56:24 dev <DIR> 24/08/2975165 08:56:24 sbin <DIR> 24/08/2975165 08:56:24 boot <DIR> 24/08/2975165 08:56:24 bin <DIR> 24/08/2975165 08:56:24 run <DIR> 24/08/2975165 08:56:24 lib32 <DIR> 24/08/2975165 08:56:24 libx32 <DIR> 24/08/2975165 08:56:24 init <DIR> 24/08/2975165 08:56:24 proc <DIR> 24/08/2975165 08:56:24 snap <DIR> 24/08/2975165 08:56:24 tmp <DIR> 24/08/2975165 08:56:24 var <DIR> 24/08/2975165 08:56:24 lost+found <DIR> 16/04/2022 18:02:15 .. <DIR> 21/04/2022 17:07:47 .
The output should be something like
03/04/2022 16:03:22
(it is correct for.
and..
), so where I am making a mistake?I am sorry if my code is not clean (because I am a beginner) or I have given some unnecessary parts of the code.